From 5c72f124903c8a7561a9310a6d26cef532433056 Mon Sep 17 00:00:00 2001 From: Saeed Vaziry Date: Sun, 2 Jul 2023 12:47:50 +0200 Subject: [PATCH] init --- .editorconfig | 18 + .env.example | 75 + .env.testing | 41 + .gitattributes | 11 + .gitignore | 20 + Makefile | 5 + README.md | 1 + app/Actions/Backup/CreateBackup.php | 85 + app/Actions/CronJob/CreateCronJob.php | 48 + app/Actions/Database/CreateDatabase.php | 58 + app/Actions/Database/CreateDatabaseUser.php | 53 + app/Actions/Database/InstallPHPMyAdmin.php | 55 + app/Actions/Database/LinkUser.php | 30 + app/Actions/FirewallRule/CreateRule.php | 64 + .../NotificationChannels/AddChannel.php | 55 + app/Actions/PHP/InstallNewPHP.php | 52 + app/Actions/PHP/InstallPHPExtension.php | 46 + app/Actions/PHP/UninstallPHP.php | 39 + app/Actions/PHP/UpdatePHPIni.php | 40 + app/Actions/Queue/CreateQueue.php | 65 + app/Actions/SSL/CreateSSL.php | 47 + app/Actions/Script/CreateScript.php | 41 + app/Actions/Script/GetScripts.php | 17 + app/Actions/Script/UpdateScript.php | 37 + app/Actions/Server/CreateServer.php | 183 + app/Actions/Server/DeleteServer.php | 33 + app/Actions/Server/EditServer.php | 55 + app/Actions/Server/GetServers.php | 14 + .../ServerProvider/CreateServerProvider.php | 77 + app/Actions/Site/ChangePHPVersion.php | 30 + app/Actions/Site/CreateRedirect.php | 51 + app/Actions/Site/CreateSite.php | 118 + app/Actions/Site/DeleteSite.php | 32 + app/Actions/Site/EditSite.php | 41 + app/Actions/Site/GetSites.php | 14 + app/Actions/Site/UpdateBranch.php | 30 + app/Actions/Site/UpdateDeploymentScript.php | 32 + app/Actions/Site/UpdateEnv.php | 18 + .../SourceControl/ConnectSourceControl.php | 35 + app/Actions/SshKey/CreateSshKey.php | 43 + .../StorageProvider/AddStorageProvider.php | 30 + .../HandleProviderCallback.php | 34 + .../StorageProvider/ValidateProvider.php | 28 + app/Actions/User/UpdateUserPassword.php | 25 + .../User/UpdateUserProfileInformation.php | 44 + .../Commands/CreateDatabaseCommand.php | 28 + app/Console/Commands/CreateUserCommand.php | 26 + app/Console/Kernel.php | 27 + app/Contracts/Database.php | 24 + app/Contracts/Firewall.php | 10 + app/Contracts/Notification.php | 10 + app/Contracts/NotificationChannel.php | 14 + app/Contracts/ProcessManager.php | 27 + app/Contracts/SSHCommand.php | 10 + app/Contracts/ServerProvider.php | 26 + app/Contracts/ServerType.php | 14 + app/Contracts/SiteType.php | 22 + app/Contracts/SourceControlProvider.php | 18 + app/Contracts/StorageProvider.php | 17 + app/Contracts/Webserver.php | 23 + app/Enums/CronjobStatus.php | 14 + app/Enums/Database.php | 16 + app/Enums/DatabaseStatus.php | 16 + app/Enums/DatabaseUserStatus.php | 16 + app/Enums/DeploymentStatus.php | 14 + app/Enums/FirewallRuleStatus.php | 14 + app/Enums/LogType.php | 12 + app/Enums/NotificationChannel.php | 14 + app/Enums/OperatingSystem.php | 14 + app/Enums/QueueStatus.php | 24 + app/Enums/ServerProvider.php | 20 + app/Enums/ServerStatus.php | 16 + app/Enums/ServerType.php | 10 + app/Enums/ServiceStatus.php | 26 + app/Enums/SiteStatus.php | 16 + app/Enums/SiteType.php | 14 + app/Enums/SourceControl.php | 16 + app/Enums/SshKeyStatus.php | 14 + app/Enums/SslStatus.php | 16 + app/Enums/SslType.php | 12 + app/Enums/StorageProvider.php | 12 + app/Enums/Webserver.php | 10 + app/Events/Broadcast.php | 25 + app/Exceptions/CannotDeployKey.php | 10 + app/Exceptions/ComposerInstallFailed.php | 10 + app/Exceptions/CouldNotConnectToProvider.php | 10 + app/Exceptions/ErrorUpdatingRedirects.php | 10 + app/Exceptions/FailedToDeleteServer.php | 10 + app/Exceptions/FailedToDeployGitHook.php | 10 + app/Exceptions/FailedToDestroyGitHook.php | 10 + app/Exceptions/FailedToInstallWordpress.php | 10 + app/Exceptions/GitRepositoryNotFound.php | 10 + app/Exceptions/Handler.php | 48 + app/Exceptions/InstallationFailed.php | 10 + app/Exceptions/ProcessFailed.php | 10 + app/Exceptions/RepositoryNotFound.php | 10 + app/Exceptions/RepositoryPermissionDenied.php | 10 + app/Exceptions/SSHAuthenticationError.php | 10 + app/Exceptions/SSHConnectionError.php | 10 + app/Exceptions/SSLCreationException.php | 10 + app/Exceptions/ServerInstallationFailed.php | 10 + app/Exceptions/ServerProviderError.php | 10 + .../SourceControlIsNotConnected.php | 14 + app/Facades/SSH.php | 31 + app/Helpers/SSH.php | 196 + app/Helpers/Toast.php | 40 + .../Auth/AuthenticatedSessionController.php | 48 + .../Auth/ConfirmablePasswordController.php | 41 + .../Auth/NewPasswordController.php | 61 + .../Controllers/Auth/PasswordController.php | 29 + .../Auth/PasswordResetLinkController.php | 44 + app/Http/Controllers/Controller.php | 12 + app/Http/Controllers/CronjobController.php | 15 + app/Http/Controllers/DaemonController.php | 15 + app/Http/Controllers/DatabaseController.php | 15 + app/Http/Controllers/FirewallController.php | 15 + app/Http/Controllers/PHPController.php | 15 + app/Http/Controllers/SSHKeyController.php | 15 + app/Http/Controllers/ServerController.php | 28 + .../Controllers/ServerSettingController.php | 13 + app/Http/Controllers/ServiceController.php | 15 + app/Http/Controllers/SiteController.php | 72 + app/Http/Kernel.php | 67 + .../Livewire/Application/ChangeBranch.php | 35 + app/Http/Livewire/Application/Deploy.php | 40 + .../Livewire/Application/DeploymentScript.php | 37 + .../Livewire/Application/DeploymentsList.php | 34 + app/Http/Livewire/Application/LaravelApp.php | 20 + app/Http/Livewire/Application/PhpApp.php | 20 + .../Livewire/Application/WordpressApp.php | 20 + app/Http/Livewire/Cronjobs/CreateCronjob.php | 34 + app/Http/Livewire/Cronjobs/CronjobsList.php | 35 + app/Http/Livewire/Databases/DatabaseList.php | 65 + .../Livewire/Databases/DatabaseUserList.php | 94 + .../Livewire/Firewall/CreateFirewallRule.php | 40 + .../Livewire/Firewall/FirewallRulesList.php | 36 + .../NotificationChannels/AddChannel.php | 34 + .../NotificationChannels/ChannelsList.php | 37 + app/Http/Livewire/Php/DefaultCli.php | 30 + app/Http/Livewire/Php/InstalledVersions.php | 85 + app/Http/Livewire/Profile/UpdatePassword.php | 32 + .../Profile/UpdateProfileInformation.php | 48 + app/Http/Livewire/Queues/CreateQueue.php | 36 + app/Http/Livewire/Queues/QueuesList.php | 57 + app/Http/Livewire/ServerLogs/LogsList.php | 58 + .../ServerProviders/ConnectProvider.php | 40 + .../ServerProviders/ProvidersList.php | 37 + .../ServerSettings/CheckConnection.php | 24 + .../Livewire/ServerSettings/EditServer.php | 40 + .../Livewire/ServerSettings/RebootServer.php | 24 + .../Livewire/ServerSettings/ServerDetails.php | 20 + .../Livewire/ServerSshKeys/AddExistingKey.php | 33 + app/Http/Livewire/ServerSshKeys/AddNewKey.php | 36 + .../Livewire/ServerSshKeys/ServerKeysList.php | 40 + app/Http/Livewire/Servers/CreateServer.php | 64 + app/Http/Livewire/Servers/DeleteServer.php | 29 + app/Http/Livewire/Servers/ServersList.php | 20 + app/Http/Livewire/Servers/ShowServer.php | 31 + app/Http/Livewire/Services/ServicesList.php | 49 + app/Http/Livewire/Sites/ChangePhpVersion.php | 41 + app/Http/Livewire/Sites/CreateSite.php | 59 + app/Http/Livewire/Sites/DeleteSite.php | 27 + app/Http/Livewire/Sites/ShowSite.php | 20 + app/Http/Livewire/Sites/SitesList.php | 38 + .../Livewire/SourceControls/Bitbucket.php | 36 + app/Http/Livewire/SourceControls/Github.php | 36 + app/Http/Livewire/SourceControls/Gitlab.php | 36 + app/Http/Livewire/SshKeys/AddKey.php | 31 + app/Http/Livewire/SshKeys/KeysList.php | 37 + app/Http/Livewire/Ssl/CreateSsl.php | 35 + app/Http/Livewire/Ssl/SslsList.php | 46 + app/Http/Livewire/UserDropdown.php | 18 + app/Http/Middleware/Authenticate.php | 17 + app/Http/Middleware/EncryptCookies.php | 17 + .../PreventRequestsDuringMaintenance.php | 17 + .../Middleware/RedirectIfAuthenticated.php | 30 + app/Http/Middleware/TrimStrings.php | 19 + app/Http/Middleware/TrustHosts.php | 20 + app/Http/Middleware/TrustProxies.php | 28 + app/Http/Middleware/ValidateSignature.php | 22 + app/Http/Middleware/VerifyCsrfToken.php | 17 + app/Http/Requests/Auth/LoginRequest.php | 85 + app/Http/Requests/ProfileUpdateRequest.php | 23 + app/Jobs/Backup/RestoreDatabase.php | 47 + app/Jobs/Backup/RunBackup.php | 44 + app/Jobs/CronJob/AddToServer.php | 48 + app/Jobs/CronJob/RemoveFromServer.php | 46 + app/Jobs/Database/CreateOnServer.php | 35 + app/Jobs/Database/DeleteFromServer.php | 37 + app/Jobs/DatabaseUser/CreateOnServer.php | 43 + app/Jobs/DatabaseUser/DeleteFromServer.php | 40 + app/Jobs/DatabaseUser/LinkUser.php | 40 + app/Jobs/DatabaseUser/UnlinkUser.php | 39 + app/Jobs/Firewall/AddToServer.php | 48 + app/Jobs/Firewall/RemoveFromServer.php | 48 + .../Installation/ContinueInstallation.php | 34 + app/Jobs/Installation/Initialize.php | 75 + app/Jobs/Installation/InstallCertbot.php | 25 + app/Jobs/Installation/InstallComposer.php | 25 + app/Jobs/Installation/InstallMariadb.php | 35 + app/Jobs/Installation/InstallMysql.php | 35 + app/Jobs/Installation/InstallNginx.php | 35 + app/Jobs/Installation/InstallNodejs.php | 25 + app/Jobs/Installation/InstallPHP.php | 35 + app/Jobs/Installation/InstallPHPMyAdmin.php | 103 + app/Jobs/Installation/InstallRedis.php | 35 + app/Jobs/Installation/InstallRequirements.php | 28 + app/Jobs/Installation/InstallSupervisor.php | 35 + app/Jobs/Installation/InstallUfw.php | 35 + app/Jobs/Installation/InstallationJob.php | 17 + app/Jobs/Installation/UninstallPHP.php | 28 + app/Jobs/Installation/UninstallPHPMyAdmin.php | 63 + app/Jobs/Installation/Upgrade.php | 25 + app/Jobs/Job.php | 15 + app/Jobs/LongJob.php | 8 + app/Jobs/PHP/InstallPHPExtension.php | 58 + app/Jobs/PHP/SetDefaultCli.php | 46 + app/Jobs/PHP/UpdatePHPSettings.php | 58 + app/Jobs/Queue/Deploy.php | 49 + app/Jobs/Queue/GetLogs.php | 37 + app/Jobs/Queue/Manage.php | 68 + app/Jobs/Queue/Remove.php | 41 + app/Jobs/Redirect/AddToServer.php | 42 + app/Jobs/Redirect/DeleteFromServer.php | 44 + app/Jobs/Script/ExecuteOn.php | 61 + app/Jobs/Server/CheckConnection.php | 49 + app/Jobs/Server/RebootServer.php | 45 + app/Jobs/Service/Install.php | 24 + app/Jobs/Service/Manage.php | 75 + app/Jobs/Site/ChangePHPVersion.php | 43 + app/Jobs/Site/CloneRepository.php | 34 + app/Jobs/Site/ComposerInstall.php | 34 + app/Jobs/Site/CreateVHost.php | 21 + app/Jobs/Site/DeleteSite.php | 40 + app/Jobs/Site/Deploy.php | 64 + app/Jobs/Site/DeployEnv.php | 46 + app/Jobs/Site/InstallWordpress.php | 109 + app/Jobs/Site/UpdateBranch.php | 53 + app/Jobs/Site/UpdateSourceControlsRemote.php | 41 + app/Jobs/Site/UpdateVHost.php | 21 + app/Jobs/SshKey/DeleteSshKeyFromServer.php | 50 + app/Jobs/SshKey/DeploySshKeyToServer.php | 53 + app/Jobs/Ssl/Deploy.php | 48 + app/Jobs/Ssl/Remove.php | 39 + app/Jobs/StorageProvider/DeleteFile.php | 24 + app/Mail/NotificationChannelMessage.php | 47 + app/Models/AbstractModel.php | 24 + app/Models/Backup.php | 87 + app/Models/BackupFile.php | 88 + app/Models/CronJob.php | 90 + app/Models/Database.php | 79 + app/Models/DatabaseUser.php | 96 + app/Models/Deployment.php | 67 + app/Models/DeploymentScript.php | 32 + app/Models/FirewallRule.php | 68 + app/Models/GitHook.php | 83 + app/Models/NotificationChannel.php | 39 + app/Models/Queue.php | 143 + app/Models/Redirect.php | 50 + app/Models/Script.php | 44 + app/Models/ScriptExecution.php | 42 + app/Models/Server.php | 388 + app/Models/ServerLog.php | 72 + app/Models/ServerProvider.php | 43 + app/Models/Service.php | 217 + app/Models/Site.php | 397 + app/Models/SourceControl.php | 36 + app/Models/SshKey.php | 66 + app/Models/Ssl.php | 132 + app/Models/StorageProvider.php | 50 + app/Models/User.php | 106 + app/NotificationChannels/AbstractProvider.php | 16 + app/NotificationChannels/Discord.php | 58 + app/NotificationChannels/Email.php | 37 + app/NotificationChannels/Slack.php | 58 + .../FailedToDeleteServerFromProvider.php | 44 + app/Notifications/SSLExpirationAlert.php | 26 + app/Notifications/ServerDisconnected.php | 40 + .../ServerInstallationFailed.php | 42 + .../ServerInstallationStarted.php | 44 + .../ServerInstallationSucceed.php | 51 + .../SourceControlDisconnected.php | 42 + app/Providers/AppServiceProvider.php | 51 + app/Providers/AuthServiceProvider.php | 26 + app/Providers/BroadcastServiceProvider.php | 19 + app/Providers/EventServiceProvider.php | 38 + app/Providers/RouteServiceProvider.php | 48 + app/Providers/TelescopeServiceProvider.php | 65 + app/SSHCommands/ChangeDefaultPHPCommand.php | 32 + .../ChangeNginxPHPVersionCommand.php | 47 + app/SSHCommands/CloneRepositoryCommand.php | 45 + app/SSHCommands/Command.php | 10 + app/SSHCommands/ComposerInstallCommand.php | 29 + app/SSHCommands/CreateCustomSSLCommand.php | 43 + .../CreateLetsencryptSSLCommand.php | 35 + .../CreateNginxPHPMyAdminVHostCommand.php | 29 + app/SSHCommands/CreateNginxVHostCommand.php | 50 + app/SSHCommands/CreateUserCommand.php | 39 + .../Database/BackupDatabaseCommand.php | 36 + app/SSHCommands/Database/CreateCommand.php | 36 + .../Database/CreateUserCommand.php | 51 + app/SSHCommands/Database/DeleteCommand.php | 36 + .../Database/DeleteUserCommand.php | 44 + app/SSHCommands/Database/LinkCommand.php | 48 + .../Database/RestoreDatabaseCommand.php | 36 + app/SSHCommands/Database/UnlinkCommand.php | 41 + .../DeleteNginxPHPMyAdminVHost.php | 30 + app/SSHCommands/DeleteNginxSiteCommand.php | 40 + app/SSHCommands/DeleteSshKeyCommand.php | 32 + app/SSHCommands/DeploySshKeyCommand.php | 32 + app/SSHCommands/DownloadPHPMyAdminCommand.php | 18 + app/SSHCommands/EditFileCommand.php | 31 + app/SSHCommands/Firewall/AddRuleCommand.php | 56 + app/SSHCommands/Firewall/CommandContent.php | 18 + .../Firewall/RemoveRuleCommand.php | 56 + app/SSHCommands/GetPHPIniCommand.php | 29 + app/SSHCommands/GetPublicKeyCommand.php | 18 + app/SSHCommands/InstallCertbotCommand.php | 18 + app/SSHCommands/InstallComposerCommand.php | 18 + .../InstallDependenciesCommand.php | 18 + app/SSHCommands/InstallMariadbCommand.php | 18 + app/SSHCommands/InstallMysqlCommand.php | 29 + app/SSHCommands/InstallNginxCommand.php | 29 + app/SSHCommands/InstallNodejsCommand.php | 18 + app/SSHCommands/InstallPHPCommand.php | 34 + .../InstallPHPExtensionCommand.php | 37 + app/SSHCommands/InstallRedisCommand.php | 18 + .../InstallRequirementsCommand.php | 28 + app/SSHCommands/InstallSupervisorCommand.php | 18 + app/SSHCommands/InstallUfwCommand.php | 18 + app/SSHCommands/InstallWordpressCommand.php | 71 + app/SSHCommands/ManageServiceCommand.php | 40 + .../Supervisor/CreateWorkerCommand.php | 33 + .../Supervisor/DeleteWorkerCommand.php | 29 + .../Supervisor/RestartWorkerCommand.php | 29 + .../Supervisor/StartWorkerCommand.php | 29 + .../Supervisor/StopWorkerCommand.php | 29 + app/SSHCommands/RebootCommand.php | 18 + app/SSHCommands/RemoveSSLCommand.php | 23 + app/SSHCommands/RestartServiceCommand.php | 32 + app/SSHCommands/RunScript.php | 31 + app/SSHCommands/ServiceStatusCommand.php | 32 + app/SSHCommands/StartServiceCommand.php | 32 + app/SSHCommands/StopServiceCommand.php | 32 + .../Storage/DownloadFromDropboxCommand.php | 37 + .../Storage/UploadToDropboxCommand.php | 37 + app/SSHCommands/UninstallPHPCommand.php | 34 + app/SSHCommands/UpdateBranchCommand.php | 31 + app/SSHCommands/UpdateCronJobsCommand.php | 34 + .../UpdateNginxRedirectsCommand.php | 43 + app/SSHCommands/UpdateNginxVHostCommand.php | 50 + app/SSHCommands/UpdatePHPSettingsCommand.php | 41 + app/SSHCommands/UpdateWordpressCommand.php | 50 + app/SSHCommands/UpgradeCommand.php | 18 + app/ServerProviders/AWS.php | 223 + app/ServerProviders/AbstractProvider.php | 22 + app/ServerProviders/Custom.php | 72 + app/ServerProviders/DigitalOcean.php | 158 + app/ServerProviders/Hetzner.php | 146 + app/ServerProviders/Linode.php | 139 + app/ServerProviders/Vultr.php | 152 + app/ServerTypes/AbstractType.php | 32 + app/ServerTypes/Regular.php | 184 + .../Database/AbstractDatabase.php | 16 + app/ServiceHandlers/Database/Mysql.php | 138 + .../Firewall/AbstractFirewall.php | 16 + app/ServiceHandlers/Firewall/Ufw.php | 32 + app/ServiceHandlers/PHP.php | 36 + .../ProcessManager/AbstractProcessManager.php | 16 + .../ProcessManager/Supervisor.php | 124 + .../Webserver/AbstractWebserver.php | 16 + app/ServiceHandlers/Webserver/Nginx.php | 194 + app/SiteTypes/AbstractSiteType.php | 38 + app/SiteTypes/Laravel.php | 7 + app/SiteTypes/PHPSite.php | 117 + app/SiteTypes/Wordpress.php | 172 + .../AbstractSourceControlProvider.php | 40 + app/SourceControlProviders/Bitbucket.php | 114 + app/SourceControlProviders/Custom.php | 36 + app/SourceControlProviders/Github.php | 120 + app/SourceControlProviders/Gitlab.php | 117 + .../AbstractStorageProvider.php | 16 + app/StorageProviders/Dropbox.php | 72 + .../SocialiteProviders/DropboxProvider.php | 78 + app/Support/Testing/SSHFake.php | 66 + app/Support/helpers.php | 65 + app/Traits/HasCustomPaginationView.php | 15 + app/Traits/HasToast.php | 13 + app/Traits/RefreshComponentOnBroadcast.php | 20 + app/ValidationRules/CronRule.php | 19 + app/ValidationRules/DomainRule.php | 22 + .../RestrictedIPAddressesRule.php | 28 + app/ValidationRules/SshKeyRule.php | 50 + app/View/Components/AppLayout.php | 14 + app/View/Components/GuestLayout.php | 14 + app/View/Components/ProfileLayout.php | 14 + app/View/Components/ServerLayout.php | 19 + app/View/Components/SiteLayout.php | 19 + artisan | 53 + bootstrap/app.php | 55 + bootstrap/cache/.gitignore | 2 + composer.json | 76 + composer.lock | 8973 +++++++++++++++++ config/app.php | 216 + config/auth.php | 115 + config/blade-heroicons.php | 57 + config/broadcasting.php | 70 + config/cache.php | 110 + config/core.php | 361 + config/cors.php | 34 + config/database.php | 151 + config/filesystems.php | 85 + config/hashing.php | 52 + config/logging.php | 131 + config/mail.php | 124 + config/queue.php | 89 + config/sanctum.php | 67 + config/serverproviders.php | 821 ++ config/services.php | 34 + config/session.php | 201 + config/telescope.php | 187 + config/view.php | 36 + database/.gitignore | 1 + database/factories/BackupFactory.php | 15 + database/factories/BackupFileFactory.php | 15 + database/factories/CronJobFactory.php | 23 + database/factories/DatabaseFactory.php | 20 + database/factories/DatabaseUserFactory.php | 21 + database/factories/DeploymentFactory.php | 18 + .../factories/DeploymentScriptFactory.php | 24 + database/factories/FirewallRuleFactory.php | 23 + .../factories/NotificationChannelFactory.php | 20 + database/factories/QueueFactory.php | 26 + database/factories/RedirectFactory.php | 25 + database/factories/ScriptExecutionFactory.php | 26 + database/factories/ScriptFactory.php | 15 + database/factories/ServerFactory.php | 41 + database/factories/ServerLogFactory.php | 21 + database/factories/ServerProviderFactory.php | 23 + database/factories/ServiceFactory.php | 19 + database/factories/SiteFactory.php | 26 + database/factories/SourceControlFactory.php | 20 + database/factories/SshKeyFactory.php | 20 + database/factories/SslFactory.php | 26 + database/factories/StorageProviderFactory.php | 15 + database/factories/UserFactory.php | 23 + .../2014_10_12_000000_create_users_table.php | 29 + ...12_100000_create_password_resets_table.php | 22 + ..._08_19_000000_create_failed_jobs_table.php | 26 + ...01_create_personal_access_tokens_table.php | 27 + ...021_06_23_192743_create_sessions_table.php | 25 + ...2021_06_23_211827_create_servers_table.php | 38 + ...021_06_23_214143_create_services_table.php | 30 + .../2021_06_25_102220_create_jobs_table.php | 26 + ..._06_25_124831_create_server_logs_table.php | 26 + .../2021_06_26_211903_create_sites_table.php | 35 + ...28_085814_create_source_controls_table.php | 23 + ..._07_02_065815_create_deployments_table.php | 28 + ...21_07_03_133319_create_databases_table.php | 25 + ..._03_133327_create_database_users_table.php | 28 + ..._15_090830_create_firewall_rules_table.php | 29 + ...21_07_30_204454_create_cron_jobs_table.php | 28 + ...213657_create_deployment_scripts_table.php | 24 + .../2021_08_14_165326_create_ssls_table.php | 30 + ...21_08_26_055643_create_redirects_table.php | 26 + .../2021_08_27_064512_create_queues_table.php | 32 + ...021_08_29_210204_create_ssh_keys_table.php | 24 + ...30_174511_create_server_ssh_keys_table.php | 25 + ...21_11_12_093030_create_git_hooks_table.php | 28 + ...4_190808_create_server_providers_table.php | 26 + ...2021_12_09_062430_create_scripts_table.php | 24 + ..._204458_create_script_executions_table.php | 25 + ...835_create_notification_channels_table.php | 26 + ..._183900_create_storage_providers_table.php | 27 + ...2022_02_11_085718_create_backups_table.php | 29 + ...02_11_085815_create_backup_files_table.php | 26 + database/seeders/DatabaseSeeder.php | 20 + deploy.sh | 16 + docker-compose.yml | 83 + docker/8.1/Dockerfile | 63 + docker/8.1/php.ini | 4 + docker/8.1/start-container | 17 + docker/8.1/supervisord.conf | 14 + package-lock.json | 3108 ++++++ package.json | 21 + phpunit.xml | 23 + postcss.config.js | 6 + public/.htaccess | 21 + public/favicon.ico | 0 public/favicon/android-icon-144x144.png | Bin 0 -> 4676 bytes public/favicon/android-icon-192x192.png | Bin 0 -> 5226 bytes public/favicon/android-icon-36x36.png | Bin 0 -> 1404 bytes public/favicon/android-icon-48x48.png | Bin 0 -> 1748 bytes public/favicon/android-icon-72x72.png | Bin 0 -> 2090 bytes public/favicon/android-icon-96x96.png | Bin 0 -> 2561 bytes public/favicon/apple-icon-114x114.png | Bin 0 -> 3691 bytes public/favicon/apple-icon-120x120.png | Bin 0 -> 3879 bytes public/favicon/apple-icon-144x144.png | Bin 0 -> 4676 bytes public/favicon/apple-icon-152x152.png | Bin 0 -> 5010 bytes public/favicon/apple-icon-180x180.png | Bin 0 -> 6045 bytes public/favicon/apple-icon-57x57.png | Bin 0 -> 1816 bytes public/favicon/apple-icon-60x60.png | Bin 0 -> 1891 bytes public/favicon/apple-icon-72x72.png | Bin 0 -> 2090 bytes public/favicon/apple-icon-76x76.png | Bin 0 -> 2164 bytes public/favicon/apple-icon-precomposed.png | Bin 0 -> 5768 bytes public/favicon/apple-icon.png | Bin 0 -> 5768 bytes public/favicon/browserconfig.xml | 2 + public/favicon/favicon-16x16.png | Bin 0 -> 994 bytes public/favicon/favicon-32x32.png | Bin 0 -> 1364 bytes public/favicon/favicon-96x96.png | Bin 0 -> 2561 bytes public/favicon/favicon.ico | Bin 0 -> 1150 bytes public/favicon/manifest.json | 41 + public/favicon/ms-icon-144x144.png | Bin 0 -> 4676 bytes public/favicon/ms-icon-150x150.png | Bin 0 -> 4888 bytes public/favicon/ms-icon-310x310.png | Bin 0 -> 12792 bytes public/favicon/ms-icon-70x70.png | Bin 0 -> 2059 bytes public/index.php | 55 + public/robots.txt | 2 + public/static/images/aws.svg | 2 + public/static/images/bitbucket.svg | 14 + public/static/images/custom.svg | 74 + public/static/images/digital-ocean.svg | 7 + public/static/images/digitalocean.svg | 7 + public/static/images/discord.svg | 6 + public/static/images/dropbox.svg | 10 + public/static/images/email.svg | 1 + public/static/images/error.svg | 129 + public/static/images/github.svg | 6 + public/static/images/gitlab.svg | 12 + public/static/images/google.svg | 11 + public/static/images/hetzner.svg | 1 + public/static/images/laravel.svg | 6 + public/static/images/linode.svg | 8 + public/static/images/logo.png | Bin 0 -> 19403 bytes public/static/images/mariadb.svg | 8 + public/static/images/monitoring.svg | 1 + public/static/images/mysql.svg | 9 + public/static/images/nginx.svg | 7 + public/static/images/openvpn.svg | 1 + public/static/images/php.svg | 37 + public/static/images/redis.svg | 16 + public/static/images/server.svg | 74 + public/static/images/slack.svg | 9 + public/static/images/supervisor.svg | 1 + public/static/images/telegram.svg | 9 + public/static/images/ufw.svg | 1 + public/static/images/vitomonitor.svg | 1 + public/static/images/vultr.svg | 1 + public/static/images/wordpress.svg | 6 + public/static/images/www.svg | 1 + public/static/libs/ace/ace.js | 17 + public/static/libs/ace/mode-sh.js | 1 + public/static/libs/ace/theme-github.js | 5 + public/static/libs/ace/theme-one-dark.js | 5 + public/vendor/telescope/app-dark.css | 8 + public/vendor/telescope/app.css | 7 + public/vendor/telescope/app.js | 2 + public/vendor/telescope/favicon.ico | Bin 0 -> 26622 bytes public/vendor/telescope/mix-manifest.json | 5 + resources/css/app.css | 5 + resources/css/toastr.css | 256 + resources/js/app.js | 24 + resources/js/bootstrap.js | 43 + .../views/auth/confirm-password.blade.php | 27 + .../views/auth/forgot-password.blade.php | 25 + resources/views/auth/login.blade.php | 47 + resources/views/auth/reset-password.blade.php | 39 + .../components/application-logo.blade.php | 1 + .../components/auth-session-status.blade.php | 7 + .../views/components/card-header.blade.php | 21 + resources/views/components/card.blade.php | 25 + .../views/components/confirm-modal.blade.php | 18 + .../views/components/console-view.blade.php | 3 + .../views/components/container.blade.php | 3 + .../views/components/danger-button.blade.php | 3 + resources/views/components/datetime.blade.php | 3 + .../views/components/dropdown-link.blade.php | 1 + resources/views/components/dropdown.blade.php | 46 + .../views/components/icon-button.blade.php | 15 + .../views/components/input-error.blade.php | 9 + .../views/components/input-label.blade.php | 5 + .../views/components/item-card.blade.php | 3 + resources/views/components/modal.blade.php | 80 + resources/views/components/nav-link.blade.php | 11 + .../views/components/primary-button.blade.php | 15 + .../components/responsive-nav-link.blade.php | 11 + .../components/secondary-button.blade.php | 24 + resources/views/components/section.blade.php | 19 + .../views/components/select-input.blade.php | 5 + .../components/server-provider-item.blade.php | 12 + .../views/components/sidebar-link.blade.php | 11 + .../views/components/simple-card.blade.php | 3 + .../views/components/site-type-item.blade.php | 12 + resources/views/components/status.blade.php | 15 + resources/views/components/table.blade.php | 5 + resources/views/components/td.blade.php | 3 + .../views/components/text-input.blade.php | 3 + resources/views/components/textarea.blade.php | 3 + resources/views/components/th.blade.php | 3 + resources/views/components/toast.blade.php | 14 + resources/views/cronjobs/index.blade.php | 5 + resources/views/daemons/index.blade.php | 4 + resources/views/databases/index.blade.php | 9 + resources/views/firewall/index.blade.php | 5 + resources/views/layouts/app.blade.php | 57 + resources/views/layouts/guest.blade.php | 30 + resources/views/layouts/navigation.blade.php | 63 + resources/views/layouts/profile.blade.php | 34 + resources/views/layouts/server.blade.php | 60 + resources/views/layouts/site.blade.php | 44 + .../application/change-branch.blade.php | 32 + .../livewire/application/deploy.blade.php | 5 + .../application/deployment-script.blade.php | 32 + .../application/deployments-list.blade.php | 51 + .../application/laravel-app.blade.php | 21 + .../partials/deployment-status.blade.php | 9 + .../livewire/application/php-app.blade.php | 3 + .../application/wordpress-app.blade.php | 3 + .../cronjobs/create-cronjob.blade.php | 69 + .../livewire/cronjobs/cronjobs-list.blade.php | 45 + .../cronjobs/partials/status.blade.php | 9 + .../databases/database-list.blade.php | 46 + .../databases/database-user-list.blade.php | 56 + .../partials/create-database-modal.blade.php | 68 + .../create-database-user-modal.blade.php | 51 + .../partials/database-status.blade.php | 12 + .../database-user-password-modal.blade.php | 23 + .../partials/database-user-status.blade.php | 12 + .../partials/delete-database-modal.blade.php | 6 + .../delete-database-user-modal.blade.php | 6 + .../link-database-user-modal.blade.php | 28 + .../firewall/create-firewall-rule.blade.php | 72 + .../firewall/firewall-rules-list.blade.php | 52 + .../firewall/partials/status.blade.php | 9 + .../add-channel.blade.php | 66 + .../channels-list.blade.php | 45 + .../livewire/partials/pagination.blade.php | 43 + .../views/livewire/php/default-cli.blade.php | 41 + .../livewire/php/installed-versions.blade.php | 61 + .../php/partials/install-new-php.blade.php | 18 + .../php/partials/uninstall-php.blade.php | 6 + .../php/partials/update-php-ini.blade.php | 25 + .../profile/update-password.blade.php | 45 + .../update-profile-information.blade.php | 56 + .../livewire/queues/create-queue.blade.php | 75 + .../livewire/queues/partials/status.blade.php | 27 + .../livewire/queues/queues-list.blade.php | 54 + .../livewire/server-logs/logs-list.blade.php | 43 + .../connect-provider.blade.php | 74 + .../server-providers/providers-list.blade.php | 45 + .../check-connection.blade.php | 1 + .../server-settings/edit-server.blade.php | 38 + .../server-settings/reboot-server.blade.php | 1 + .../server-settings/server-details.blade.php | 58 + .../add-existing-key.blade.php | 36 + .../server-ssh-keys/add-new-key.blade.php | 39 + .../server-ssh-keys/partials/status.blade.php | 9 + .../server-keys-list.blade.php | 50 + .../livewire/servers/create-server.blade.php | 158 + .../livewire/servers/delete-server.blade.php | 9 + .../partials/installation-failed.blade.php | 14 + .../servers/partials/installing.blade.php | 16 + .../servers/partials/public-key.blade.php | 24 + .../partials/server-overview.blade.php | 34 + .../servers/partials/status.blade.php | 12 + .../livewire/servers/servers-list.blade.php | 42 + .../livewire/servers/show-server.blade.php | 16 + .../services/partials/status.blade.php | 27 + .../livewire/services/services-list.blade.php | 48 + .../sites/change-php-version.blade.php | 33 + .../livewire/sites/create-site.blade.php | 104 + .../livewire/sites/delete-site.blade.php | 9 + .../partials/installation-failed.blade.php | 10 + .../sites/partials/installing.blade.php | 13 + .../sites/partials/site-overview.blade.php | 38 + .../livewire/sites/partials/status.blade.php | 12 + .../views/livewire/sites/show-site.blade.php | 13 + .../views/livewire/sites/sites-list.blade.php | 42 + .../source-controls/bitbucket.blade.php | 48 + .../livewire/source-controls/github.blade.php | 48 + .../livewire/source-controls/gitlab.blade.php | 48 + .../partials/bitbucket-icon.blade.php | 12 + .../partials/github-icon.blade.php | 3 + .../partials/gitlab-icon.blade.php | 10 + .../views/livewire/ssh-keys/add-key.blade.php | 39 + .../livewire/ssh-keys/keys-list.blade.php | 42 + .../views/livewire/ssl/create-ssl.blade.php | 54 + .../livewire/ssl/partials/status.blade.php | 12 + .../views/livewire/ssl/ssls-list.blade.php | 54 + .../views/livewire/user-dropdown.blade.php | 31 + .../notification-channels/index.blade.php | 5 + resources/views/php/index.blade.php | 9 + resources/views/profile/index.blade.php | 7 + .../views/server-providers/index.blade.php | 5 + .../views/server-settings/index.blade.php | 38 + .../views/server-ssh-keys/index.blade.php | 5 + resources/views/servers/create.blade.php | 5 + resources/views/servers/index.blade.php | 5 + resources/views/servers/logs.blade.php | 5 + resources/views/servers/show.blade.php | 5 + resources/views/services/index.blade.php | 5 + resources/views/sites/application.blade.php | 15 + resources/views/sites/create.blade.php | 5 + resources/views/sites/index.blade.php | 5 + resources/views/sites/logs.blade.php | 5 + resources/views/sites/queues.blade.php | 5 + resources/views/sites/settings.blade.php | 14 + resources/views/sites/show.blade.php | 7 + resources/views/sites/ssl.blade.php | 5 + .../views/source-controls/index.blade.php | 20 + resources/views/ssh-keys/index.blade.php | 5 + routes/api.php | 19 + routes/auth.php | 24 + routes/channels.php | 8 + routes/console.php | 19 + routes/web.php | 53 + sail | 486 + storage/app/.gitignore | 3 + storage/app/public/.gitignore | 2 + storage/framework/.gitignore | 9 + storage/framework/cache/.gitignore | 3 + storage/framework/cache/data/.gitignore | 2 + storage/framework/sessions/.gitignore | 2 + storage/framework/testing/.gitignore | 2 + storage/framework/views/.gitignore | 2 + storage/logs/.gitignore | 2 + system/command-templates/nginx/nginx.conf | 85 + .../nginx/php-vhost-ssl.conf | 38 + system/command-templates/nginx/php-vhost.conf | 33 + .../nginx/phpmyadmin-vhost.conf | 31 + system/command-templates/nginx/redirect.conf | 3 + .../nginx/reverse-vhost-ssl.conf | 36 + .../nginx/reverse-vhost.conf | 31 + system/command-templates/nginx/vhost-ssl.conf | 32 + system/command-templates/nginx/vhost.conf | 27 + .../command-templates/supervisor/worker.conf | 10 + system/commands/common/clone-repository.sh | 23 + system/commands/common/composer-install.sh | 7 + system/commands/common/create-custom-ssl.sh | 13 + .../commands/common/create-letsencrypt-ssl.sh | 3 + system/commands/common/download-phpmyadmin.sh | 21 + system/commands/common/edit-file.sh | 3 + system/commands/common/get-public-key.sh | 1 + system/commands/common/install-composer.sh | 7 + system/commands/common/run-script.sh | 5 + .../common/storage/download-from-dropbox.sh | 4 + .../common/storage/upload-to-dropbox.sh | 6 + system/commands/common/update-branch.sh | 7 + system/commands/common/update-cron-jobs.sh | 7 + system/commands/common/wordpress/install.sh | 27 + system/commands/database/mysql/backup.sh | 11 + system/commands/database/mysql/create-user.sh | 9 + system/commands/database/mysql/create.sh | 5 + system/commands/database/mysql/delete-user.sh | 9 + system/commands/database/mysql/delete.sh | 5 + system/commands/database/mysql/link.sh | 9 + system/commands/database/mysql/restore.sh | 11 + system/commands/database/mysql/unlink.sh | 5 + system/commands/firewall/ufw/add-rule.sh | 11 + system/commands/firewall/ufw/remove-rule.sh | 11 + system/commands/ubuntu/basics.sh | 1 + system/commands/ubuntu/change-default-php.sh | 11 + system/commands/ubuntu/create-user.sh | 11 + system/commands/ubuntu/delete-ssh-key.sh | 1 + system/commands/ubuntu/deploy-ssh-key.sh | 3 + system/commands/ubuntu/get-php-ini.sh | 1 + system/commands/ubuntu/install-certbot.sh | 1 + system/commands/ubuntu/install-mariadb.sh | 12 + system/commands/ubuntu/install-mysql-8.sh | 19 + system/commands/ubuntu/install-mysql.sh | 13 + system/commands/ubuntu/install-nginx.sh | 8 + system/commands/ubuntu/install-nodejs.sh | 5 + .../commands/ubuntu/install-php-extension.sh | 5 + system/commands/ubuntu/install-php.sh | 13 + system/commands/ubuntu/install-redis.sh | 5 + .../commands/ubuntu/install-requirements.sh | 3 + system/commands/ubuntu/install-supervisor.sh | 5 + system/commands/ubuntu/install-ufw.sh | 27 + .../supervisor/create-worker.sh | 21 + .../supervisor/delete-worker.sh | 20 + .../supervisor/restart-worker.sh | 3 + .../supervisor/start-worker.sh | 3 + .../process-manager/supervisor/stop-worker.sh | 3 + system/commands/ubuntu/reboot.sh | 3 + system/commands/ubuntu/restart-service.sh | 3 + system/commands/ubuntu/service-status.sh | 1 + system/commands/ubuntu/start-service.sh | 3 + system/commands/ubuntu/stop-service.sh | 3 + system/commands/ubuntu/uninstall-php.sh | 5 + system/commands/ubuntu/update-php-ini.sh | 7 + system/commands/ubuntu/update-php-settings.sh | 11 + system/commands/ubuntu/upgrade.sh | 7 + .../webserver/nginx/change-php-version.sh | 9 + .../nginx/create-phpmyadmin-vhost.sh | 17 + .../ubuntu/webserver/nginx/create-vhost.sh | 27 + .../nginx/delete-phpmyadmin-vhost.sh | 11 + .../ubuntu/webserver/nginx/delete-site.sh | 7 + .../webserver/nginx/update-redirects.sh | 7 + .../ubuntu/webserver/nginx/update-vhost.sh | 7 + tailwind.config.js | 27 + tests/CreatesApplication.php | 21 + tests/Feature/Http/ApplicationTest.php | 69 + .../Feature/Http/Auth/AuthenticationTest.php | 40 + .../Http/Auth/PasswordConfirmationTest.php | 47 + tests/Feature/Http/Auth/PasswordResetTest.php | 64 + .../Feature/Http/Auth/PasswordUpdateTest.php | 40 + tests/Feature/Http/CronjobTest.php | 64 + tests/Feature/Http/DatabaseTest.php | 76 + tests/Feature/Http/DatabaseUserTest.php | 74 + tests/Feature/Http/FirewallTest.php | 79 + tests/Feature/Http/LogsTest.php | 30 + .../Feature/Http/NotificationChannelsTest.php | 85 + tests/Feature/Http/PHP.php | 71 + tests/Feature/Http/ProfileTest.php | 40 + tests/Feature/Http/QueuesTest.php | 69 + tests/Feature/Http/ServerKeysTest.php | 111 + tests/Feature/Http/ServerProvidersTest.php | 67 + tests/Feature/Http/ServerTest.php | 47 + tests/Feature/Http/ServicesTest.php | 94 + tests/Feature/Http/SitesTest.php | 111 + tests/Feature/Http/SourceControlsTest.php | 66 + tests/Feature/Http/SshKeysTest.php | 61 + tests/Feature/Http/SslTest.php | 83 + tests/TestCase.php | 72 + vite.config.js | 14 + 825 files changed, 41659 insertions(+) create mode 100644 .editorconfig create mode 100755 .env.example create mode 100755 .env.testing create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 app/Actions/Backup/CreateBackup.php create mode 100755 app/Actions/CronJob/CreateCronJob.php create mode 100755 app/Actions/Database/CreateDatabase.php create mode 100755 app/Actions/Database/CreateDatabaseUser.php create mode 100644 app/Actions/Database/InstallPHPMyAdmin.php create mode 100755 app/Actions/Database/LinkUser.php create mode 100755 app/Actions/FirewallRule/CreateRule.php create mode 100644 app/Actions/NotificationChannels/AddChannel.php create mode 100755 app/Actions/PHP/InstallNewPHP.php create mode 100755 app/Actions/PHP/InstallPHPExtension.php create mode 100755 app/Actions/PHP/UninstallPHP.php create mode 100755 app/Actions/PHP/UpdatePHPIni.php create mode 100644 app/Actions/Queue/CreateQueue.php create mode 100644 app/Actions/SSL/CreateSSL.php create mode 100644 app/Actions/Script/CreateScript.php create mode 100755 app/Actions/Script/GetScripts.php create mode 100644 app/Actions/Script/UpdateScript.php create mode 100755 app/Actions/Server/CreateServer.php create mode 100755 app/Actions/Server/DeleteServer.php create mode 100755 app/Actions/Server/EditServer.php create mode 100755 app/Actions/Server/GetServers.php create mode 100644 app/Actions/ServerProvider/CreateServerProvider.php create mode 100755 app/Actions/Site/ChangePHPVersion.php create mode 100644 app/Actions/Site/CreateRedirect.php create mode 100755 app/Actions/Site/CreateSite.php create mode 100755 app/Actions/Site/DeleteSite.php create mode 100755 app/Actions/Site/EditSite.php create mode 100755 app/Actions/Site/GetSites.php create mode 100755 app/Actions/Site/UpdateBranch.php create mode 100755 app/Actions/Site/UpdateDeploymentScript.php create mode 100755 app/Actions/Site/UpdateEnv.php create mode 100644 app/Actions/SourceControl/ConnectSourceControl.php create mode 100644 app/Actions/SshKey/CreateSshKey.php create mode 100644 app/Actions/StorageProvider/AddStorageProvider.php create mode 100755 app/Actions/StorageProvider/HandleProviderCallback.php create mode 100755 app/Actions/StorageProvider/ValidateProvider.php create mode 100755 app/Actions/User/UpdateUserPassword.php create mode 100755 app/Actions/User/UpdateUserProfileInformation.php create mode 100644 app/Console/Commands/CreateDatabaseCommand.php create mode 100644 app/Console/Commands/CreateUserCommand.php create mode 100644 app/Console/Kernel.php create mode 100755 app/Contracts/Database.php create mode 100755 app/Contracts/Firewall.php create mode 100644 app/Contracts/Notification.php create mode 100644 app/Contracts/NotificationChannel.php create mode 100755 app/Contracts/ProcessManager.php create mode 100755 app/Contracts/SSHCommand.php create mode 100755 app/Contracts/ServerProvider.php create mode 100755 app/Contracts/ServerType.php create mode 100755 app/Contracts/SiteType.php create mode 100755 app/Contracts/SourceControlProvider.php create mode 100644 app/Contracts/StorageProvider.php create mode 100755 app/Contracts/Webserver.php create mode 100644 app/Enums/CronjobStatus.php create mode 100644 app/Enums/Database.php create mode 100644 app/Enums/DatabaseStatus.php create mode 100644 app/Enums/DatabaseUserStatus.php create mode 100644 app/Enums/DeploymentStatus.php create mode 100644 app/Enums/FirewallRuleStatus.php create mode 100644 app/Enums/LogType.php create mode 100644 app/Enums/NotificationChannel.php create mode 100644 app/Enums/OperatingSystem.php create mode 100644 app/Enums/QueueStatus.php create mode 100644 app/Enums/ServerProvider.php create mode 100644 app/Enums/ServerStatus.php create mode 100644 app/Enums/ServerType.php create mode 100644 app/Enums/ServiceStatus.php create mode 100644 app/Enums/SiteStatus.php create mode 100644 app/Enums/SiteType.php create mode 100644 app/Enums/SourceControl.php create mode 100644 app/Enums/SshKeyStatus.php create mode 100644 app/Enums/SslStatus.php create mode 100644 app/Enums/SslType.php create mode 100644 app/Enums/StorageProvider.php create mode 100644 app/Enums/Webserver.php create mode 100644 app/Events/Broadcast.php create mode 100755 app/Exceptions/CannotDeployKey.php create mode 100644 app/Exceptions/ComposerInstallFailed.php create mode 100644 app/Exceptions/CouldNotConnectToProvider.php create mode 100644 app/Exceptions/ErrorUpdatingRedirects.php create mode 100644 app/Exceptions/FailedToDeleteServer.php create mode 100644 app/Exceptions/FailedToDeployGitHook.php create mode 100644 app/Exceptions/FailedToDestroyGitHook.php create mode 100644 app/Exceptions/FailedToInstallWordpress.php create mode 100755 app/Exceptions/GitRepositoryNotFound.php create mode 100644 app/Exceptions/Handler.php create mode 100644 app/Exceptions/InstallationFailed.php create mode 100644 app/Exceptions/ProcessFailed.php create mode 100644 app/Exceptions/RepositoryNotFound.php create mode 100644 app/Exceptions/RepositoryPermissionDenied.php create mode 100755 app/Exceptions/SSHAuthenticationError.php create mode 100755 app/Exceptions/SSHConnectionError.php create mode 100644 app/Exceptions/SSLCreationException.php create mode 100644 app/Exceptions/ServerInstallationFailed.php create mode 100644 app/Exceptions/ServerProviderError.php create mode 100755 app/Exceptions/SourceControlIsNotConnected.php create mode 100644 app/Facades/SSH.php create mode 100755 app/Helpers/SSH.php create mode 100644 app/Helpers/Toast.php create mode 100644 app/Http/Controllers/Auth/AuthenticatedSessionController.php create mode 100644 app/Http/Controllers/Auth/ConfirmablePasswordController.php create mode 100644 app/Http/Controllers/Auth/NewPasswordController.php create mode 100644 app/Http/Controllers/Auth/PasswordController.php create mode 100644 app/Http/Controllers/Auth/PasswordResetLinkController.php create mode 100644 app/Http/Controllers/Controller.php create mode 100644 app/Http/Controllers/CronjobController.php create mode 100644 app/Http/Controllers/DaemonController.php create mode 100644 app/Http/Controllers/DatabaseController.php create mode 100644 app/Http/Controllers/FirewallController.php create mode 100644 app/Http/Controllers/PHPController.php create mode 100644 app/Http/Controllers/SSHKeyController.php create mode 100644 app/Http/Controllers/ServerController.php create mode 100644 app/Http/Controllers/ServerSettingController.php create mode 100644 app/Http/Controllers/ServiceController.php create mode 100644 app/Http/Controllers/SiteController.php create mode 100644 app/Http/Kernel.php create mode 100644 app/Http/Livewire/Application/ChangeBranch.php create mode 100644 app/Http/Livewire/Application/Deploy.php create mode 100644 app/Http/Livewire/Application/DeploymentScript.php create mode 100644 app/Http/Livewire/Application/DeploymentsList.php create mode 100644 app/Http/Livewire/Application/LaravelApp.php create mode 100644 app/Http/Livewire/Application/PhpApp.php create mode 100644 app/Http/Livewire/Application/WordpressApp.php create mode 100644 app/Http/Livewire/Cronjobs/CreateCronjob.php create mode 100644 app/Http/Livewire/Cronjobs/CronjobsList.php create mode 100644 app/Http/Livewire/Databases/DatabaseList.php create mode 100644 app/Http/Livewire/Databases/DatabaseUserList.php create mode 100644 app/Http/Livewire/Firewall/CreateFirewallRule.php create mode 100644 app/Http/Livewire/Firewall/FirewallRulesList.php create mode 100644 app/Http/Livewire/NotificationChannels/AddChannel.php create mode 100644 app/Http/Livewire/NotificationChannels/ChannelsList.php create mode 100644 app/Http/Livewire/Php/DefaultCli.php create mode 100644 app/Http/Livewire/Php/InstalledVersions.php create mode 100644 app/Http/Livewire/Profile/UpdatePassword.php create mode 100644 app/Http/Livewire/Profile/UpdateProfileInformation.php create mode 100644 app/Http/Livewire/Queues/CreateQueue.php create mode 100644 app/Http/Livewire/Queues/QueuesList.php create mode 100644 app/Http/Livewire/ServerLogs/LogsList.php create mode 100644 app/Http/Livewire/ServerProviders/ConnectProvider.php create mode 100644 app/Http/Livewire/ServerProviders/ProvidersList.php create mode 100644 app/Http/Livewire/ServerSettings/CheckConnection.php create mode 100644 app/Http/Livewire/ServerSettings/EditServer.php create mode 100644 app/Http/Livewire/ServerSettings/RebootServer.php create mode 100644 app/Http/Livewire/ServerSettings/ServerDetails.php create mode 100644 app/Http/Livewire/ServerSshKeys/AddExistingKey.php create mode 100644 app/Http/Livewire/ServerSshKeys/AddNewKey.php create mode 100644 app/Http/Livewire/ServerSshKeys/ServerKeysList.php create mode 100644 app/Http/Livewire/Servers/CreateServer.php create mode 100644 app/Http/Livewire/Servers/DeleteServer.php create mode 100644 app/Http/Livewire/Servers/ServersList.php create mode 100644 app/Http/Livewire/Servers/ShowServer.php create mode 100644 app/Http/Livewire/Services/ServicesList.php create mode 100644 app/Http/Livewire/Sites/ChangePhpVersion.php create mode 100644 app/Http/Livewire/Sites/CreateSite.php create mode 100644 app/Http/Livewire/Sites/DeleteSite.php create mode 100644 app/Http/Livewire/Sites/ShowSite.php create mode 100644 app/Http/Livewire/Sites/SitesList.php create mode 100644 app/Http/Livewire/SourceControls/Bitbucket.php create mode 100644 app/Http/Livewire/SourceControls/Github.php create mode 100644 app/Http/Livewire/SourceControls/Gitlab.php create mode 100644 app/Http/Livewire/SshKeys/AddKey.php create mode 100644 app/Http/Livewire/SshKeys/KeysList.php create mode 100644 app/Http/Livewire/Ssl/CreateSsl.php create mode 100644 app/Http/Livewire/Ssl/SslsList.php create mode 100644 app/Http/Livewire/UserDropdown.php create mode 100644 app/Http/Middleware/Authenticate.php create mode 100644 app/Http/Middleware/EncryptCookies.php create mode 100644 app/Http/Middleware/PreventRequestsDuringMaintenance.php create mode 100644 app/Http/Middleware/RedirectIfAuthenticated.php create mode 100644 app/Http/Middleware/TrimStrings.php create mode 100644 app/Http/Middleware/TrustHosts.php create mode 100644 app/Http/Middleware/TrustProxies.php create mode 100644 app/Http/Middleware/ValidateSignature.php create mode 100644 app/Http/Middleware/VerifyCsrfToken.php create mode 100644 app/Http/Requests/Auth/LoginRequest.php create mode 100644 app/Http/Requests/ProfileUpdateRequest.php create mode 100644 app/Jobs/Backup/RestoreDatabase.php create mode 100644 app/Jobs/Backup/RunBackup.php create mode 100644 app/Jobs/CronJob/AddToServer.php create mode 100644 app/Jobs/CronJob/RemoveFromServer.php create mode 100644 app/Jobs/Database/CreateOnServer.php create mode 100644 app/Jobs/Database/DeleteFromServer.php create mode 100644 app/Jobs/DatabaseUser/CreateOnServer.php create mode 100644 app/Jobs/DatabaseUser/DeleteFromServer.php create mode 100644 app/Jobs/DatabaseUser/LinkUser.php create mode 100644 app/Jobs/DatabaseUser/UnlinkUser.php create mode 100644 app/Jobs/Firewall/AddToServer.php create mode 100644 app/Jobs/Firewall/RemoveFromServer.php create mode 100644 app/Jobs/Installation/ContinueInstallation.php create mode 100755 app/Jobs/Installation/Initialize.php create mode 100755 app/Jobs/Installation/InstallCertbot.php create mode 100755 app/Jobs/Installation/InstallComposer.php create mode 100755 app/Jobs/Installation/InstallMariadb.php create mode 100755 app/Jobs/Installation/InstallMysql.php create mode 100755 app/Jobs/Installation/InstallNginx.php create mode 100755 app/Jobs/Installation/InstallNodejs.php create mode 100755 app/Jobs/Installation/InstallPHP.php create mode 100644 app/Jobs/Installation/InstallPHPMyAdmin.php create mode 100755 app/Jobs/Installation/InstallRedis.php create mode 100755 app/Jobs/Installation/InstallRequirements.php create mode 100755 app/Jobs/Installation/InstallSupervisor.php create mode 100755 app/Jobs/Installation/InstallUfw.php create mode 100755 app/Jobs/Installation/InstallationJob.php create mode 100755 app/Jobs/Installation/UninstallPHP.php create mode 100644 app/Jobs/Installation/UninstallPHPMyAdmin.php create mode 100755 app/Jobs/Installation/Upgrade.php create mode 100755 app/Jobs/Job.php create mode 100755 app/Jobs/LongJob.php create mode 100755 app/Jobs/PHP/InstallPHPExtension.php create mode 100644 app/Jobs/PHP/SetDefaultCli.php create mode 100755 app/Jobs/PHP/UpdatePHPSettings.php create mode 100644 app/Jobs/Queue/Deploy.php create mode 100644 app/Jobs/Queue/GetLogs.php create mode 100644 app/Jobs/Queue/Manage.php create mode 100644 app/Jobs/Queue/Remove.php create mode 100644 app/Jobs/Redirect/AddToServer.php create mode 100644 app/Jobs/Redirect/DeleteFromServer.php create mode 100644 app/Jobs/Script/ExecuteOn.php create mode 100644 app/Jobs/Server/CheckConnection.php create mode 100644 app/Jobs/Server/RebootServer.php create mode 100644 app/Jobs/Service/Install.php create mode 100644 app/Jobs/Service/Manage.php create mode 100644 app/Jobs/Site/ChangePHPVersion.php create mode 100755 app/Jobs/Site/CloneRepository.php create mode 100755 app/Jobs/Site/ComposerInstall.php create mode 100755 app/Jobs/Site/CreateVHost.php create mode 100755 app/Jobs/Site/DeleteSite.php create mode 100644 app/Jobs/Site/Deploy.php create mode 100644 app/Jobs/Site/DeployEnv.php create mode 100755 app/Jobs/Site/InstallWordpress.php create mode 100644 app/Jobs/Site/UpdateBranch.php create mode 100644 app/Jobs/Site/UpdateSourceControlsRemote.php create mode 100755 app/Jobs/Site/UpdateVHost.php create mode 100644 app/Jobs/SshKey/DeleteSshKeyFromServer.php create mode 100644 app/Jobs/SshKey/DeploySshKeyToServer.php create mode 100644 app/Jobs/Ssl/Deploy.php create mode 100644 app/Jobs/Ssl/Remove.php create mode 100644 app/Jobs/StorageProvider/DeleteFile.php create mode 100644 app/Mail/NotificationChannelMessage.php create mode 100755 app/Models/AbstractModel.php create mode 100644 app/Models/Backup.php create mode 100644 app/Models/BackupFile.php create mode 100755 app/Models/CronJob.php create mode 100755 app/Models/Database.php create mode 100755 app/Models/DatabaseUser.php create mode 100755 app/Models/Deployment.php create mode 100644 app/Models/DeploymentScript.php create mode 100755 app/Models/FirewallRule.php create mode 100755 app/Models/GitHook.php create mode 100644 app/Models/NotificationChannel.php create mode 100644 app/Models/Queue.php create mode 100644 app/Models/Redirect.php create mode 100644 app/Models/Script.php create mode 100644 app/Models/ScriptExecution.php create mode 100755 app/Models/Server.php create mode 100755 app/Models/ServerLog.php create mode 100644 app/Models/ServerProvider.php create mode 100755 app/Models/Service.php create mode 100755 app/Models/Site.php create mode 100755 app/Models/SourceControl.php create mode 100644 app/Models/SshKey.php create mode 100644 app/Models/Ssl.php create mode 100644 app/Models/StorageProvider.php create mode 100755 app/Models/User.php create mode 100644 app/NotificationChannels/AbstractProvider.php create mode 100644 app/NotificationChannels/Discord.php create mode 100644 app/NotificationChannels/Email.php create mode 100644 app/NotificationChannels/Slack.php create mode 100644 app/Notifications/FailedToDeleteServerFromProvider.php create mode 100644 app/Notifications/SSLExpirationAlert.php create mode 100644 app/Notifications/ServerDisconnected.php create mode 100644 app/Notifications/ServerInstallationFailed.php create mode 100644 app/Notifications/ServerInstallationStarted.php create mode 100644 app/Notifications/ServerInstallationSucceed.php create mode 100644 app/Notifications/SourceControlDisconnected.php create mode 100644 app/Providers/AppServiceProvider.php create mode 100644 app/Providers/AuthServiceProvider.php create mode 100644 app/Providers/BroadcastServiceProvider.php create mode 100644 app/Providers/EventServiceProvider.php create mode 100644 app/Providers/RouteServiceProvider.php create mode 100644 app/Providers/TelescopeServiceProvider.php create mode 100755 app/SSHCommands/ChangeDefaultPHPCommand.php create mode 100755 app/SSHCommands/ChangeNginxPHPVersionCommand.php create mode 100755 app/SSHCommands/CloneRepositoryCommand.php create mode 100755 app/SSHCommands/Command.php create mode 100755 app/SSHCommands/ComposerInstallCommand.php create mode 100755 app/SSHCommands/CreateCustomSSLCommand.php create mode 100755 app/SSHCommands/CreateLetsencryptSSLCommand.php create mode 100755 app/SSHCommands/CreateNginxPHPMyAdminVHostCommand.php create mode 100755 app/SSHCommands/CreateNginxVHostCommand.php create mode 100755 app/SSHCommands/CreateUserCommand.php create mode 100644 app/SSHCommands/Database/BackupDatabaseCommand.php create mode 100755 app/SSHCommands/Database/CreateCommand.php create mode 100755 app/SSHCommands/Database/CreateUserCommand.php create mode 100755 app/SSHCommands/Database/DeleteCommand.php create mode 100755 app/SSHCommands/Database/DeleteUserCommand.php create mode 100755 app/SSHCommands/Database/LinkCommand.php create mode 100644 app/SSHCommands/Database/RestoreDatabaseCommand.php create mode 100755 app/SSHCommands/Database/UnlinkCommand.php create mode 100755 app/SSHCommands/DeleteNginxPHPMyAdminVHost.php create mode 100755 app/SSHCommands/DeleteNginxSiteCommand.php create mode 100755 app/SSHCommands/DeleteSshKeyCommand.php create mode 100755 app/SSHCommands/DeploySshKeyCommand.php create mode 100644 app/SSHCommands/DownloadPHPMyAdminCommand.php create mode 100644 app/SSHCommands/EditFileCommand.php create mode 100755 app/SSHCommands/Firewall/AddRuleCommand.php create mode 100755 app/SSHCommands/Firewall/CommandContent.php create mode 100755 app/SSHCommands/Firewall/RemoveRuleCommand.php create mode 100755 app/SSHCommands/GetPHPIniCommand.php create mode 100755 app/SSHCommands/GetPublicKeyCommand.php create mode 100755 app/SSHCommands/InstallCertbotCommand.php create mode 100755 app/SSHCommands/InstallComposerCommand.php create mode 100755 app/SSHCommands/InstallDependenciesCommand.php create mode 100755 app/SSHCommands/InstallMariadbCommand.php create mode 100755 app/SSHCommands/InstallMysqlCommand.php create mode 100755 app/SSHCommands/InstallNginxCommand.php create mode 100755 app/SSHCommands/InstallNodejsCommand.php create mode 100755 app/SSHCommands/InstallPHPCommand.php create mode 100755 app/SSHCommands/InstallPHPExtensionCommand.php create mode 100755 app/SSHCommands/InstallRedisCommand.php create mode 100755 app/SSHCommands/InstallRequirementsCommand.php create mode 100755 app/SSHCommands/InstallSupervisorCommand.php create mode 100755 app/SSHCommands/InstallUfwCommand.php create mode 100755 app/SSHCommands/InstallWordpressCommand.php create mode 100755 app/SSHCommands/ManageServiceCommand.php create mode 100644 app/SSHCommands/ProcessManager/Supervisor/CreateWorkerCommand.php create mode 100644 app/SSHCommands/ProcessManager/Supervisor/DeleteWorkerCommand.php create mode 100644 app/SSHCommands/ProcessManager/Supervisor/RestartWorkerCommand.php create mode 100644 app/SSHCommands/ProcessManager/Supervisor/StartWorkerCommand.php create mode 100644 app/SSHCommands/ProcessManager/Supervisor/StopWorkerCommand.php create mode 100644 app/SSHCommands/RebootCommand.php create mode 100755 app/SSHCommands/RemoveSSLCommand.php create mode 100644 app/SSHCommands/RestartServiceCommand.php create mode 100644 app/SSHCommands/RunScript.php create mode 100755 app/SSHCommands/ServiceStatusCommand.php create mode 100644 app/SSHCommands/StartServiceCommand.php create mode 100644 app/SSHCommands/StopServiceCommand.php create mode 100644 app/SSHCommands/Storage/DownloadFromDropboxCommand.php create mode 100644 app/SSHCommands/Storage/UploadToDropboxCommand.php create mode 100755 app/SSHCommands/UninstallPHPCommand.php create mode 100644 app/SSHCommands/UpdateBranchCommand.php create mode 100755 app/SSHCommands/UpdateCronJobsCommand.php create mode 100755 app/SSHCommands/UpdateNginxRedirectsCommand.php create mode 100755 app/SSHCommands/UpdateNginxVHostCommand.php create mode 100755 app/SSHCommands/UpdatePHPSettingsCommand.php create mode 100755 app/SSHCommands/UpdateWordpressCommand.php create mode 100755 app/SSHCommands/UpgradeCommand.php create mode 100755 app/ServerProviders/AWS.php create mode 100755 app/ServerProviders/AbstractProvider.php create mode 100755 app/ServerProviders/Custom.php create mode 100644 app/ServerProviders/DigitalOcean.php create mode 100644 app/ServerProviders/Hetzner.php create mode 100644 app/ServerProviders/Linode.php create mode 100644 app/ServerProviders/Vultr.php create mode 100755 app/ServerTypes/AbstractType.php create mode 100755 app/ServerTypes/Regular.php create mode 100755 app/ServiceHandlers/Database/AbstractDatabase.php create mode 100755 app/ServiceHandlers/Database/Mysql.php create mode 100755 app/ServiceHandlers/Firewall/AbstractFirewall.php create mode 100755 app/ServiceHandlers/Firewall/Ufw.php create mode 100644 app/ServiceHandlers/PHP.php create mode 100644 app/ServiceHandlers/ProcessManager/AbstractProcessManager.php create mode 100644 app/ServiceHandlers/ProcessManager/Supervisor.php create mode 100755 app/ServiceHandlers/Webserver/AbstractWebserver.php create mode 100755 app/ServiceHandlers/Webserver/Nginx.php create mode 100755 app/SiteTypes/AbstractSiteType.php create mode 100755 app/SiteTypes/Laravel.php create mode 100755 app/SiteTypes/PHPSite.php create mode 100755 app/SiteTypes/Wordpress.php create mode 100755 app/SourceControlProviders/AbstractSourceControlProvider.php create mode 100755 app/SourceControlProviders/Bitbucket.php create mode 100755 app/SourceControlProviders/Custom.php create mode 100755 app/SourceControlProviders/Github.php create mode 100755 app/SourceControlProviders/Gitlab.php create mode 100644 app/StorageProviders/AbstractStorageProvider.php create mode 100644 app/StorageProviders/Dropbox.php create mode 100644 app/Support/SocialiteProviders/DropboxProvider.php create mode 100644 app/Support/Testing/SSHFake.php create mode 100755 app/Support/helpers.php create mode 100644 app/Traits/HasCustomPaginationView.php create mode 100644 app/Traits/HasToast.php create mode 100644 app/Traits/RefreshComponentOnBroadcast.php create mode 100755 app/ValidationRules/CronRule.php create mode 100755 app/ValidationRules/DomainRule.php create mode 100755 app/ValidationRules/RestrictedIPAddressesRule.php create mode 100755 app/ValidationRules/SshKeyRule.php create mode 100644 app/View/Components/AppLayout.php create mode 100644 app/View/Components/GuestLayout.php create mode 100644 app/View/Components/ProfileLayout.php create mode 100644 app/View/Components/ServerLayout.php create mode 100644 app/View/Components/SiteLayout.php create mode 100755 artisan create mode 100644 bootstrap/app.php create mode 100644 bootstrap/cache/.gitignore create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/app.php create mode 100644 config/auth.php create mode 100644 config/blade-heroicons.php create mode 100644 config/broadcasting.php create mode 100644 config/cache.php create mode 100755 config/core.php create mode 100644 config/cors.php create mode 100644 config/database.php create mode 100644 config/filesystems.php create mode 100644 config/hashing.php create mode 100644 config/logging.php create mode 100644 config/mail.php create mode 100755 config/queue.php create mode 100644 config/sanctum.php create mode 100644 config/serverproviders.php create mode 100644 config/services.php create mode 100644 config/session.php create mode 100644 config/telescope.php create mode 100644 config/view.php create mode 100644 database/.gitignore create mode 100644 database/factories/BackupFactory.php create mode 100644 database/factories/BackupFileFactory.php create mode 100644 database/factories/CronJobFactory.php create mode 100755 database/factories/DatabaseFactory.php create mode 100755 database/factories/DatabaseUserFactory.php create mode 100755 database/factories/DeploymentFactory.php create mode 100644 database/factories/DeploymentScriptFactory.php create mode 100644 database/factories/FirewallRuleFactory.php create mode 100644 database/factories/NotificationChannelFactory.php create mode 100644 database/factories/QueueFactory.php create mode 100644 database/factories/RedirectFactory.php create mode 100644 database/factories/ScriptExecutionFactory.php create mode 100644 database/factories/ScriptFactory.php create mode 100755 database/factories/ServerFactory.php create mode 100644 database/factories/ServerLogFactory.php create mode 100644 database/factories/ServerProviderFactory.php create mode 100644 database/factories/ServiceFactory.php create mode 100644 database/factories/SiteFactory.php create mode 100644 database/factories/SourceControlFactory.php create mode 100644 database/factories/SshKeyFactory.php create mode 100644 database/factories/SslFactory.php create mode 100644 database/factories/StorageProviderFactory.php create mode 100755 database/factories/UserFactory.php create mode 100755 database/migrations/2014_10_12_000000_create_users_table.php create mode 100755 database/migrations/2014_10_12_100000_create_password_resets_table.php create mode 100644 database/migrations/2019_08_19_000000_create_failed_jobs_table.php create mode 100644 database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php create mode 100755 database/migrations/2021_06_23_192743_create_sessions_table.php create mode 100755 database/migrations/2021_06_23_211827_create_servers_table.php create mode 100755 database/migrations/2021_06_23_214143_create_services_table.php create mode 100755 database/migrations/2021_06_25_102220_create_jobs_table.php create mode 100755 database/migrations/2021_06_25_124831_create_server_logs_table.php create mode 100755 database/migrations/2021_06_26_211903_create_sites_table.php create mode 100755 database/migrations/2021_06_28_085814_create_source_controls_table.php create mode 100755 database/migrations/2021_07_02_065815_create_deployments_table.php create mode 100755 database/migrations/2021_07_03_133319_create_databases_table.php create mode 100755 database/migrations/2021_07_03_133327_create_database_users_table.php create mode 100755 database/migrations/2021_07_15_090830_create_firewall_rules_table.php create mode 100755 database/migrations/2021_07_30_204454_create_cron_jobs_table.php create mode 100644 database/migrations/2021_08_13_213657_create_deployment_scripts_table.php create mode 100644 database/migrations/2021_08_14_165326_create_ssls_table.php create mode 100644 database/migrations/2021_08_26_055643_create_redirects_table.php create mode 100644 database/migrations/2021_08_27_064512_create_queues_table.php create mode 100644 database/migrations/2021_08_29_210204_create_ssh_keys_table.php create mode 100644 database/migrations/2021_08_30_174511_create_server_ssh_keys_table.php create mode 100644 database/migrations/2021_11_12_093030_create_git_hooks_table.php create mode 100644 database/migrations/2021_11_14_190808_create_server_providers_table.php create mode 100644 database/migrations/2021_12_09_062430_create_scripts_table.php create mode 100644 database/migrations/2021_12_10_204458_create_script_executions_table.php create mode 100644 database/migrations/2021_12_24_151835_create_notification_channels_table.php create mode 100644 database/migrations/2022_01_29_183900_create_storage_providers_table.php create mode 100644 database/migrations/2022_02_11_085718_create_backups_table.php create mode 100644 database/migrations/2022_02_11_085815_create_backup_files_table.php create mode 100644 database/seeders/DatabaseSeeder.php create mode 100755 deploy.sh create mode 100644 docker-compose.yml create mode 100644 docker/8.1/Dockerfile create mode 100644 docker/8.1/php.ini create mode 100644 docker/8.1/start-container create mode 100644 docker/8.1/supervisord.conf create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 phpunit.xml create mode 100644 postcss.config.js create mode 100644 public/.htaccess create mode 100755 public/favicon.ico create mode 100644 public/favicon/android-icon-144x144.png create mode 100644 public/favicon/android-icon-192x192.png create mode 100644 public/favicon/android-icon-36x36.png create mode 100644 public/favicon/android-icon-48x48.png create mode 100644 public/favicon/android-icon-72x72.png create mode 100644 public/favicon/android-icon-96x96.png create mode 100644 public/favicon/apple-icon-114x114.png create mode 100644 public/favicon/apple-icon-120x120.png create mode 100644 public/favicon/apple-icon-144x144.png create mode 100644 public/favicon/apple-icon-152x152.png create mode 100644 public/favicon/apple-icon-180x180.png create mode 100644 public/favicon/apple-icon-57x57.png create mode 100644 public/favicon/apple-icon-60x60.png create mode 100644 public/favicon/apple-icon-72x72.png create mode 100644 public/favicon/apple-icon-76x76.png create mode 100644 public/favicon/apple-icon-precomposed.png create mode 100644 public/favicon/apple-icon.png create mode 100644 public/favicon/browserconfig.xml create mode 100644 public/favicon/favicon-16x16.png create mode 100644 public/favicon/favicon-32x32.png create mode 100644 public/favicon/favicon-96x96.png create mode 100644 public/favicon/favicon.ico create mode 100644 public/favicon/manifest.json create mode 100644 public/favicon/ms-icon-144x144.png create mode 100644 public/favicon/ms-icon-150x150.png create mode 100644 public/favicon/ms-icon-310x310.png create mode 100644 public/favicon/ms-icon-70x70.png create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100755 public/static/images/aws.svg create mode 100644 public/static/images/bitbucket.svg create mode 100644 public/static/images/custom.svg create mode 100755 public/static/images/digital-ocean.svg create mode 100644 public/static/images/digitalocean.svg create mode 100644 public/static/images/discord.svg create mode 100644 public/static/images/dropbox.svg create mode 100644 public/static/images/email.svg create mode 100755 public/static/images/error.svg create mode 100644 public/static/images/github.svg create mode 100644 public/static/images/gitlab.svg create mode 100644 public/static/images/google.svg create mode 100644 public/static/images/hetzner.svg create mode 100644 public/static/images/laravel.svg create mode 100755 public/static/images/linode.svg create mode 100644 public/static/images/logo.png create mode 100644 public/static/images/mariadb.svg create mode 100644 public/static/images/monitoring.svg create mode 100644 public/static/images/mysql.svg create mode 100644 public/static/images/nginx.svg create mode 100644 public/static/images/openvpn.svg create mode 100644 public/static/images/php.svg create mode 100644 public/static/images/redis.svg create mode 100755 public/static/images/server.svg create mode 100644 public/static/images/slack.svg create mode 100644 public/static/images/supervisor.svg create mode 100644 public/static/images/telegram.svg create mode 100644 public/static/images/ufw.svg create mode 100644 public/static/images/vitomonitor.svg create mode 100755 public/static/images/vultr.svg create mode 100644 public/static/images/wordpress.svg create mode 100755 public/static/images/www.svg create mode 100755 public/static/libs/ace/ace.js create mode 100755 public/static/libs/ace/mode-sh.js create mode 100755 public/static/libs/ace/theme-github.js create mode 100644 public/static/libs/ace/theme-one-dark.js create mode 100644 public/vendor/telescope/app-dark.css create mode 100644 public/vendor/telescope/app.css create mode 100644 public/vendor/telescope/app.js create mode 100644 public/vendor/telescope/favicon.ico create mode 100644 public/vendor/telescope/mix-manifest.json create mode 100644 resources/css/app.css create mode 100644 resources/css/toastr.css create mode 100644 resources/js/app.js create mode 100644 resources/js/bootstrap.js create mode 100644 resources/views/auth/confirm-password.blade.php create mode 100644 resources/views/auth/forgot-password.blade.php create mode 100644 resources/views/auth/login.blade.php create mode 100644 resources/views/auth/reset-password.blade.php create mode 100644 resources/views/components/application-logo.blade.php create mode 100644 resources/views/components/auth-session-status.blade.php create mode 100644 resources/views/components/card-header.blade.php create mode 100644 resources/views/components/card.blade.php create mode 100644 resources/views/components/confirm-modal.blade.php create mode 100644 resources/views/components/console-view.blade.php create mode 100644 resources/views/components/container.blade.php create mode 100644 resources/views/components/danger-button.blade.php create mode 100644 resources/views/components/datetime.blade.php create mode 100644 resources/views/components/dropdown-link.blade.php create mode 100644 resources/views/components/dropdown.blade.php create mode 100644 resources/views/components/icon-button.blade.php create mode 100644 resources/views/components/input-error.blade.php create mode 100644 resources/views/components/input-label.blade.php create mode 100644 resources/views/components/item-card.blade.php create mode 100644 resources/views/components/modal.blade.php create mode 100644 resources/views/components/nav-link.blade.php create mode 100644 resources/views/components/primary-button.blade.php create mode 100644 resources/views/components/responsive-nav-link.blade.php create mode 100644 resources/views/components/secondary-button.blade.php create mode 100644 resources/views/components/section.blade.php create mode 100644 resources/views/components/select-input.blade.php create mode 100644 resources/views/components/server-provider-item.blade.php create mode 100644 resources/views/components/sidebar-link.blade.php create mode 100644 resources/views/components/simple-card.blade.php create mode 100644 resources/views/components/site-type-item.blade.php create mode 100644 resources/views/components/status.blade.php create mode 100644 resources/views/components/table.blade.php create mode 100644 resources/views/components/td.blade.php create mode 100644 resources/views/components/text-input.blade.php create mode 100644 resources/views/components/textarea.blade.php create mode 100644 resources/views/components/th.blade.php create mode 100644 resources/views/components/toast.blade.php create mode 100644 resources/views/cronjobs/index.blade.php create mode 100644 resources/views/daemons/index.blade.php create mode 100644 resources/views/databases/index.blade.php create mode 100644 resources/views/firewall/index.blade.php create mode 100644 resources/views/layouts/app.blade.php create mode 100644 resources/views/layouts/guest.blade.php create mode 100644 resources/views/layouts/navigation.blade.php create mode 100644 resources/views/layouts/profile.blade.php create mode 100644 resources/views/layouts/server.blade.php create mode 100644 resources/views/layouts/site.blade.php create mode 100644 resources/views/livewire/application/change-branch.blade.php create mode 100644 resources/views/livewire/application/deploy.blade.php create mode 100644 resources/views/livewire/application/deployment-script.blade.php create mode 100644 resources/views/livewire/application/deployments-list.blade.php create mode 100644 resources/views/livewire/application/laravel-app.blade.php create mode 100644 resources/views/livewire/application/partials/deployment-status.blade.php create mode 100644 resources/views/livewire/application/php-app.blade.php create mode 100644 resources/views/livewire/application/wordpress-app.blade.php create mode 100644 resources/views/livewire/cronjobs/create-cronjob.blade.php create mode 100644 resources/views/livewire/cronjobs/cronjobs-list.blade.php create mode 100644 resources/views/livewire/cronjobs/partials/status.blade.php create mode 100644 resources/views/livewire/databases/database-list.blade.php create mode 100644 resources/views/livewire/databases/database-user-list.blade.php create mode 100644 resources/views/livewire/databases/partials/create-database-modal.blade.php create mode 100644 resources/views/livewire/databases/partials/create-database-user-modal.blade.php create mode 100644 resources/views/livewire/databases/partials/database-status.blade.php create mode 100644 resources/views/livewire/databases/partials/database-user-password-modal.blade.php create mode 100644 resources/views/livewire/databases/partials/database-user-status.blade.php create mode 100644 resources/views/livewire/databases/partials/delete-database-modal.blade.php create mode 100644 resources/views/livewire/databases/partials/delete-database-user-modal.blade.php create mode 100644 resources/views/livewire/databases/partials/link-database-user-modal.blade.php create mode 100644 resources/views/livewire/firewall/create-firewall-rule.blade.php create mode 100644 resources/views/livewire/firewall/firewall-rules-list.blade.php create mode 100644 resources/views/livewire/firewall/partials/status.blade.php create mode 100644 resources/views/livewire/notification-channels/add-channel.blade.php create mode 100644 resources/views/livewire/notification-channels/channels-list.blade.php create mode 100644 resources/views/livewire/partials/pagination.blade.php create mode 100644 resources/views/livewire/php/default-cli.blade.php create mode 100644 resources/views/livewire/php/installed-versions.blade.php create mode 100644 resources/views/livewire/php/partials/install-new-php.blade.php create mode 100644 resources/views/livewire/php/partials/uninstall-php.blade.php create mode 100644 resources/views/livewire/php/partials/update-php-ini.blade.php create mode 100644 resources/views/livewire/profile/update-password.blade.php create mode 100644 resources/views/livewire/profile/update-profile-information.blade.php create mode 100644 resources/views/livewire/queues/create-queue.blade.php create mode 100644 resources/views/livewire/queues/partials/status.blade.php create mode 100644 resources/views/livewire/queues/queues-list.blade.php create mode 100644 resources/views/livewire/server-logs/logs-list.blade.php create mode 100644 resources/views/livewire/server-providers/connect-provider.blade.php create mode 100644 resources/views/livewire/server-providers/providers-list.blade.php create mode 100644 resources/views/livewire/server-settings/check-connection.blade.php create mode 100644 resources/views/livewire/server-settings/edit-server.blade.php create mode 100644 resources/views/livewire/server-settings/reboot-server.blade.php create mode 100644 resources/views/livewire/server-settings/server-details.blade.php create mode 100644 resources/views/livewire/server-ssh-keys/add-existing-key.blade.php create mode 100644 resources/views/livewire/server-ssh-keys/add-new-key.blade.php create mode 100644 resources/views/livewire/server-ssh-keys/partials/status.blade.php create mode 100644 resources/views/livewire/server-ssh-keys/server-keys-list.blade.php create mode 100644 resources/views/livewire/servers/create-server.blade.php create mode 100644 resources/views/livewire/servers/delete-server.blade.php create mode 100644 resources/views/livewire/servers/partials/installation-failed.blade.php create mode 100644 resources/views/livewire/servers/partials/installing.blade.php create mode 100644 resources/views/livewire/servers/partials/public-key.blade.php create mode 100644 resources/views/livewire/servers/partials/server-overview.blade.php create mode 100644 resources/views/livewire/servers/partials/status.blade.php create mode 100644 resources/views/livewire/servers/servers-list.blade.php create mode 100644 resources/views/livewire/servers/show-server.blade.php create mode 100644 resources/views/livewire/services/partials/status.blade.php create mode 100644 resources/views/livewire/services/services-list.blade.php create mode 100644 resources/views/livewire/sites/change-php-version.blade.php create mode 100644 resources/views/livewire/sites/create-site.blade.php create mode 100644 resources/views/livewire/sites/delete-site.blade.php create mode 100644 resources/views/livewire/sites/partials/installation-failed.blade.php create mode 100644 resources/views/livewire/sites/partials/installing.blade.php create mode 100644 resources/views/livewire/sites/partials/site-overview.blade.php create mode 100644 resources/views/livewire/sites/partials/status.blade.php create mode 100644 resources/views/livewire/sites/show-site.blade.php create mode 100644 resources/views/livewire/sites/sites-list.blade.php create mode 100644 resources/views/livewire/source-controls/bitbucket.blade.php create mode 100644 resources/views/livewire/source-controls/github.blade.php create mode 100644 resources/views/livewire/source-controls/gitlab.blade.php create mode 100644 resources/views/livewire/source-controls/partials/bitbucket-icon.blade.php create mode 100644 resources/views/livewire/source-controls/partials/github-icon.blade.php create mode 100644 resources/views/livewire/source-controls/partials/gitlab-icon.blade.php create mode 100644 resources/views/livewire/ssh-keys/add-key.blade.php create mode 100644 resources/views/livewire/ssh-keys/keys-list.blade.php create mode 100644 resources/views/livewire/ssl/create-ssl.blade.php create mode 100644 resources/views/livewire/ssl/partials/status.blade.php create mode 100644 resources/views/livewire/ssl/ssls-list.blade.php create mode 100644 resources/views/livewire/user-dropdown.blade.php create mode 100644 resources/views/notification-channels/index.blade.php create mode 100644 resources/views/php/index.blade.php create mode 100644 resources/views/profile/index.blade.php create mode 100644 resources/views/server-providers/index.blade.php create mode 100644 resources/views/server-settings/index.blade.php create mode 100644 resources/views/server-ssh-keys/index.blade.php create mode 100644 resources/views/servers/create.blade.php create mode 100644 resources/views/servers/index.blade.php create mode 100644 resources/views/servers/logs.blade.php create mode 100644 resources/views/servers/show.blade.php create mode 100644 resources/views/services/index.blade.php create mode 100644 resources/views/sites/application.blade.php create mode 100644 resources/views/sites/create.blade.php create mode 100644 resources/views/sites/index.blade.php create mode 100644 resources/views/sites/logs.blade.php create mode 100644 resources/views/sites/queues.blade.php create mode 100644 resources/views/sites/settings.blade.php create mode 100644 resources/views/sites/show.blade.php create mode 100644 resources/views/sites/ssl.blade.php create mode 100644 resources/views/source-controls/index.blade.php create mode 100644 resources/views/ssh-keys/index.blade.php create mode 100644 routes/api.php create mode 100644 routes/auth.php create mode 100644 routes/channels.php create mode 100644 routes/console.php create mode 100644 routes/web.php create mode 100755 sail create mode 100644 storage/app/.gitignore create mode 100644 storage/app/public/.gitignore create mode 100644 storage/framework/.gitignore create mode 100644 storage/framework/cache/.gitignore create mode 100644 storage/framework/cache/data/.gitignore create mode 100644 storage/framework/sessions/.gitignore create mode 100644 storage/framework/testing/.gitignore create mode 100644 storage/framework/views/.gitignore create mode 100644 storage/logs/.gitignore create mode 100755 system/command-templates/nginx/nginx.conf create mode 100755 system/command-templates/nginx/php-vhost-ssl.conf create mode 100755 system/command-templates/nginx/php-vhost.conf create mode 100755 system/command-templates/nginx/phpmyadmin-vhost.conf create mode 100644 system/command-templates/nginx/redirect.conf create mode 100755 system/command-templates/nginx/reverse-vhost-ssl.conf create mode 100755 system/command-templates/nginx/reverse-vhost.conf create mode 100755 system/command-templates/nginx/vhost-ssl.conf create mode 100755 system/command-templates/nginx/vhost.conf create mode 100644 system/command-templates/supervisor/worker.conf create mode 100755 system/commands/common/clone-repository.sh create mode 100755 system/commands/common/composer-install.sh create mode 100644 system/commands/common/create-custom-ssl.sh create mode 100644 system/commands/common/create-letsencrypt-ssl.sh create mode 100644 system/commands/common/download-phpmyadmin.sh create mode 100644 system/commands/common/edit-file.sh create mode 100755 system/commands/common/get-public-key.sh create mode 100755 system/commands/common/install-composer.sh create mode 100644 system/commands/common/run-script.sh create mode 100644 system/commands/common/storage/download-from-dropbox.sh create mode 100644 system/commands/common/storage/upload-to-dropbox.sh create mode 100644 system/commands/common/update-branch.sh create mode 100755 system/commands/common/update-cron-jobs.sh create mode 100644 system/commands/common/wordpress/install.sh create mode 100644 system/commands/database/mysql/backup.sh create mode 100755 system/commands/database/mysql/create-user.sh create mode 100755 system/commands/database/mysql/create.sh create mode 100755 system/commands/database/mysql/delete-user.sh create mode 100755 system/commands/database/mysql/delete.sh create mode 100755 system/commands/database/mysql/link.sh create mode 100644 system/commands/database/mysql/restore.sh create mode 100755 system/commands/database/mysql/unlink.sh create mode 100755 system/commands/firewall/ufw/add-rule.sh create mode 100755 system/commands/firewall/ufw/remove-rule.sh create mode 100755 system/commands/ubuntu/basics.sh create mode 100755 system/commands/ubuntu/change-default-php.sh create mode 100755 system/commands/ubuntu/create-user.sh create mode 100644 system/commands/ubuntu/delete-ssh-key.sh create mode 100644 system/commands/ubuntu/deploy-ssh-key.sh create mode 100644 system/commands/ubuntu/get-php-ini.sh create mode 100755 system/commands/ubuntu/install-certbot.sh create mode 100755 system/commands/ubuntu/install-mariadb.sh create mode 100755 system/commands/ubuntu/install-mysql-8.sh create mode 100755 system/commands/ubuntu/install-mysql.sh create mode 100755 system/commands/ubuntu/install-nginx.sh create mode 100755 system/commands/ubuntu/install-nodejs.sh create mode 100644 system/commands/ubuntu/install-php-extension.sh create mode 100755 system/commands/ubuntu/install-php.sh create mode 100755 system/commands/ubuntu/install-redis.sh create mode 100755 system/commands/ubuntu/install-requirements.sh create mode 100755 system/commands/ubuntu/install-supervisor.sh create mode 100755 system/commands/ubuntu/install-ufw.sh create mode 100644 system/commands/ubuntu/process-manager/supervisor/create-worker.sh create mode 100644 system/commands/ubuntu/process-manager/supervisor/delete-worker.sh create mode 100644 system/commands/ubuntu/process-manager/supervisor/restart-worker.sh create mode 100644 system/commands/ubuntu/process-manager/supervisor/start-worker.sh create mode 100644 system/commands/ubuntu/process-manager/supervisor/stop-worker.sh create mode 100644 system/commands/ubuntu/reboot.sh create mode 100644 system/commands/ubuntu/restart-service.sh create mode 100755 system/commands/ubuntu/service-status.sh create mode 100644 system/commands/ubuntu/start-service.sh create mode 100644 system/commands/ubuntu/stop-service.sh create mode 100755 system/commands/ubuntu/uninstall-php.sh create mode 100644 system/commands/ubuntu/update-php-ini.sh create mode 100644 system/commands/ubuntu/update-php-settings.sh create mode 100755 system/commands/ubuntu/upgrade.sh create mode 100755 system/commands/ubuntu/webserver/nginx/change-php-version.sh create mode 100644 system/commands/ubuntu/webserver/nginx/create-phpmyadmin-vhost.sh create mode 100755 system/commands/ubuntu/webserver/nginx/create-vhost.sh create mode 100644 system/commands/ubuntu/webserver/nginx/delete-phpmyadmin-vhost.sh create mode 100755 system/commands/ubuntu/webserver/nginx/delete-site.sh create mode 100644 system/commands/ubuntu/webserver/nginx/update-redirects.sh create mode 100755 system/commands/ubuntu/webserver/nginx/update-vhost.sh create mode 100644 tailwind.config.js create mode 100644 tests/CreatesApplication.php create mode 100644 tests/Feature/Http/ApplicationTest.php create mode 100644 tests/Feature/Http/Auth/AuthenticationTest.php create mode 100644 tests/Feature/Http/Auth/PasswordConfirmationTest.php create mode 100644 tests/Feature/Http/Auth/PasswordResetTest.php create mode 100644 tests/Feature/Http/Auth/PasswordUpdateTest.php create mode 100644 tests/Feature/Http/CronjobTest.php create mode 100644 tests/Feature/Http/DatabaseTest.php create mode 100644 tests/Feature/Http/DatabaseUserTest.php create mode 100644 tests/Feature/Http/FirewallTest.php create mode 100644 tests/Feature/Http/LogsTest.php create mode 100644 tests/Feature/Http/NotificationChannelsTest.php create mode 100644 tests/Feature/Http/PHP.php create mode 100644 tests/Feature/Http/ProfileTest.php create mode 100644 tests/Feature/Http/QueuesTest.php create mode 100644 tests/Feature/Http/ServerKeysTest.php create mode 100644 tests/Feature/Http/ServerProvidersTest.php create mode 100644 tests/Feature/Http/ServerTest.php create mode 100644 tests/Feature/Http/ServicesTest.php create mode 100644 tests/Feature/Http/SitesTest.php create mode 100644 tests/Feature/Http/SourceControlsTest.php create mode 100644 tests/Feature/Http/SshKeysTest.php create mode 100644 tests/Feature/Http/SslTest.php create mode 100644 tests/TestCase.php create mode 100644 vite.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8f0de65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/.env.example b/.env.example new file mode 100755 index 0000000..791885d --- /dev/null +++ b/.env.example @@ -0,0 +1,75 @@ +APP_NAME=Vito +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost:2080 + +LOG_CHANNEL=stack +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=vito +DB_USERNAME=root +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DRIVER=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=database +SESSION_LIFETIME=120 + +MEMCACHED_HOST=127.0.0.1 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=null +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +FORWARD_REDIS_PORT=2060 +FORWARD_DB_PORT=2070 +APP_PORT=2080 +HMR_PORT=2090 + +SENTRY_LARAVEL_DSN= + +APP_SERVICE=vito + +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= + +ABLY_KEY= +ABLY_PUBLIC_KEY= + +STRIPE_KEY=pk_test_NndNPdqsaU772F7rGf9VwMBZ00QTxVOAZI +STRIPE_SECRET=sk_test_nXrcZWPhxtzVLDWo3qzk5O2e00ygZPvrAJ +STRIPE_STANDARD_MONTHLY=price_1KJelHLZWr04YoNXo85HB9L6 +STRIPE_STANDARD_ANNUALLY=price_1KJelHLZWr04YoNX5JzxilBB +STRIPE_BUSINESS_MONTHLY=price_1KJelHLZWr04YoNX6rdAxIEA +STRIPE_BUSINESS_ANNUALLY=price_1KJelHLZWr04YoNXAoBOSLs9 +#STRIPE_UNLIMITED_MONTHLY=price_1KJelHLZWr04YoNXDRvMP511 +#STRIPE_UNLIMITED_ANNUALLY=price_1KJelHLZWr04YoNXG4Ad4Bjp diff --git a/.env.testing b/.env.testing new file mode 100755 index 0000000..a919ab1 --- /dev/null +++ b/.env.testing @@ -0,0 +1,41 @@ +APP_NAME=Vito +APP_ENV=local +APP_KEY=base64:d9kZW60V4lFEw2SPn6UiJ0cfi04v80EWP0GZ6kzoxNg= +APP_DEBUG=true +APP_URL=http://localhost:2080 + +LOG_CHANNEL=stack +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=mysql +DB_PORT=3306 +DB_DATABASE=testing +DB_USERNAME=root +DB_PASSWORD=password + +BROADCAST_DRIVER=pusher +CACHE_DRIVER=array +FILESYSTEM_DRIVER=local +QUEUE_CONNECTION=database +SESSION_DRIVER=array +SESSION_LIFETIME=120 + +MAIL_MAILER=array + +PUSHER_APP_ID=app-id +PUSHER_APP_KEY=app-key +PUSHER_APP_SECRET=app-secret +PUSHER_HOST=soketi +PUSHER_PORT=6001 +PUSHER_SCHEME=http +PUSHER_APP_CLUSTER=mt1 + +VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +VITE_PUSHER_HOST="${PUSHER_HOST}" +VITE_PUSHER_PORT="${PUSHER_PORT}" +VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" +VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +SSH_PUBLIC_KEY_NAME=ssh-public.key +SSH_PRIVATE_KEY_NAME=ssh-private.pem diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcb21d3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1494a95 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +/.phpunit.cache +/node_modules +/public/build +/public/hot +/public/storage +/storage/*.key +/storage/*.pem +/vendor +.env +.env.backup +.env.production +.phpunit.result.cache +Homestead.json +Homestead.yaml +auth.json +npm-debug.log +yarn-error.log +/.fleet +/.idea +/.vscode diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6083c79 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +start: + ./sail up + +stop: + ./sail down diff --git a/README.md b/README.md new file mode 100644 index 0000000..a7003e5 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Vito diff --git a/app/Actions/Backup/CreateBackup.php b/app/Actions/Backup/CreateBackup.php new file mode 100644 index 0000000..e2ee9fa --- /dev/null +++ b/app/Actions/Backup/CreateBackup.php @@ -0,0 +1,85 @@ +validate($type, $server, $user, $input); + + if ($type == 'database') { + Gate::forUser($user)->authorize('viewAny', [Database::class, $server]); + } + + $backup = new Backup([ + 'name' => $input['name'], + 'type' => $type, + 'server_id' => $server->id, + 'database_id' => $input['database'] ?? null, + 'storage_id' => $input['storage'], + 'interval' => $input['interval'], + 'keep_backups' => $input['keep_backups'], + 'status' => 'running', + ]); + $backup->save(); + + $backup->run(); + + return $backup; + } + + /** + * @throws ValidationException + */ + private function validate($type, Server $server, User $user, array $input): void + { + $rules = [ + 'name' => 'required', + 'storage' => [ + 'required', + Rule::exists('storage_providers', 'id') + ->where('user_id', $user->id) + ->where('connected', 1), + ], + 'keep_backups' => [ + 'required', + 'numeric', + 'min:1', + ], + 'interval' => [ + 'required', + Rule::in([ + '0 * * * *', + '0 0 * * *', + '0 0 * * 0', + '0 0 1 * *', + ]), + ], + ]; + if ($type === 'database') { + $rules['database'] = [ + 'required', + Rule::exists('databases', 'id') + ->where('server_id', $server->id) + ->where('status', DatabaseStatus::READY), + ]; + } + Validator::make($input, $rules)->validateWithBag('createBackup'); + } +} diff --git a/app/Actions/CronJob/CreateCronJob.php b/app/Actions/CronJob/CreateCronJob.php new file mode 100755 index 0000000..ff5262a --- /dev/null +++ b/app/Actions/CronJob/CreateCronJob.php @@ -0,0 +1,48 @@ +validate($input); + + $cronJob = new CronJob([ + 'server_id' => $server->id, + 'user' => $input['user'], + 'command' => $input['command'], + 'frequency' => $input['frequency'], + 'status' => CronjobStatus::CREATING, + ]); + $cronJob->save(); + $cronJob->addToServer(); + } + + /** + * @throws ValidationException + */ + private function validate(array $input): void + { + Validator::make($input, [ + 'command' => [ + 'required', + ], + 'user' => [ + 'required', + 'in:root,'.config('core.ssh_user'), + ], + 'frequency' => [ + 'required', + new CronRule(), + ], + ])->validateWithBag('createCronJob'); + } +} diff --git a/app/Actions/Database/CreateDatabase.php b/app/Actions/Database/CreateDatabase.php new file mode 100755 index 0000000..7136035 --- /dev/null +++ b/app/Actions/Database/CreateDatabase.php @@ -0,0 +1,58 @@ +validate($server, $input); + + $database = new Database([ + 'server_id' => $server->id, + 'name' => $input['name'], + ]); + $database->save(); + $database->createOnServer(); + + return $database; + } + + /** + * @throws ValidationException + */ + private function validate(Server $server, array $input): void + { + $rules = [ + 'name' => [ + 'required', + 'alpha_dash', + Rule::unique('databases', 'name')->where('server_id', $server->id), + ], + ]; + if (isset($input['user']) && $input['user']) { + $rules['username'] = [ + 'required', + 'alpha_dash', + Rule::unique('database_users', 'username')->where('server_id', $server->id), + ]; + $rules['password'] = [ + 'required', + 'min:6', + ]; + } + if (isset($input['remote']) && $input['remote']) { + $rules['host'] = 'required'; + } + Validator::make($input, $rules)->validate(); + } +} diff --git a/app/Actions/Database/CreateDatabaseUser.php b/app/Actions/Database/CreateDatabaseUser.php new file mode 100755 index 0000000..f8416b2 --- /dev/null +++ b/app/Actions/Database/CreateDatabaseUser.php @@ -0,0 +1,53 @@ +validate($server, $input); + + $databaseUser = new DatabaseUser([ + 'server_id' => $server->id, + 'username' => $input['username'], + 'password' => $input['password'], + 'host' => isset($input['remote']) && $input['remote'] ? $input['host'] : 'localhost', + ]); + $databaseUser->save(); + $databaseUser->createOnServer(); + + return $databaseUser; + } + + /** + * @throws ValidationException + */ + private function validate(Server $server, array $input): void + { + $rules = [ + 'username' => [ + 'required', + 'alpha_dash', + Rule::unique('database_users', 'username')->where('server_id', $server->id), + ], + 'password' => [ + 'required', + 'min:6', + ], + ]; + if (isset($input['remote']) && $input['remote']) { + $rules['host'] = 'required'; + } + Validator::make($input, $rules)->validate(); + } +} diff --git a/app/Actions/Database/InstallPHPMyAdmin.php b/app/Actions/Database/InstallPHPMyAdmin.php new file mode 100644 index 0000000..34c1b68 --- /dev/null +++ b/app/Actions/Database/InstallPHPMyAdmin.php @@ -0,0 +1,55 @@ +validate($input); + + $phpMyAdmin = $server->defaultService('phpmyadmin'); + if ($phpMyAdmin) { + if ($phpMyAdmin->status === 'ready') { + throw ValidationException::withMessages([ + 'install' => __('Already installed'), + ])->errorBag('installPHPMyAdmin'); + } + $phpMyAdmin->delete(); + } + $phpMyAdmin = new Service([ + 'server_id' => $server->id, + 'type' => 'phpmyadmin', + 'type_data' => [ + 'allowed_ip' => $input['allowed_ip'], + 'php' => $server->defaultService('php')->version, + ], + 'name' => 'phpmyadmin', + 'version' => '5.1.2', + 'status' => 'installing', + 'is_default' => 1, + ]); + $phpMyAdmin->save(); + $phpMyAdmin->install(); + + return $phpMyAdmin; + } + + /** + * @throws ValidationException + */ + private function validate(array $input): void + { + Validator::make($input, [ + 'allowed_ip' => 'required', + ])->validateWithBag('installPHPMyAdmin'); + } +} diff --git a/app/Actions/Database/LinkUser.php b/app/Actions/Database/LinkUser.php new file mode 100755 index 0000000..c6a9bcf --- /dev/null +++ b/app/Actions/Database/LinkUser.php @@ -0,0 +1,30 @@ +where('server_id', $databaseUser->server_id) + ->whereIn('name', $databases) + ->count(); + if (count($databases) !== $dbs) { + throw ValidationException::withMessages(['databases' => __('Databases not found!')]) + ->errorBag('linkUser'); + } + + $databaseUser->databases = $databases; + $databaseUser->unlinkUser(); + $databaseUser->linkUser(); + $databaseUser->save(); + } +} diff --git a/app/Actions/FirewallRule/CreateRule.php b/app/Actions/FirewallRule/CreateRule.php new file mode 100755 index 0000000..06e708c --- /dev/null +++ b/app/Actions/FirewallRule/CreateRule.php @@ -0,0 +1,64 @@ +validate($server, $input); + + $rule = new FirewallRule([ + 'server_id' => $server->id, + 'type' => $input['type'], + 'protocol' => $input['protocol'], + 'port' => $input['port'], + 'source' => $input['source'], + 'mask' => $input['mask'], + 'status' => FirewallRuleStatus::CREATING, + ]); + $rule->save(); + $rule->addToServer(); + + return $rule; + } + + /** + * @throws ValidationException + */ + private function validate(Server $server, array $input): void + { + Validator::make($input, [ + 'type' => [ + 'required', + 'in:allow,deny', + ], + 'protocol' => [ + 'required', + 'in:'.implode(',', array_keys(config('core.firewall_protocols_port'))), + ], + 'port' => [ + 'required', + 'numeric', + 'min:1', + 'max:65535', + Rule::unique('firewall_rules', 'port')->where('server_id', $server->id), + ], + 'source' => [ + 'required', + 'ip', + ], + 'mask' => [ + 'required', + 'numeric', + ], + ])->validateWithBag('createRule'); + } +} diff --git a/app/Actions/NotificationChannels/AddChannel.php b/app/Actions/NotificationChannels/AddChannel.php new file mode 100644 index 0000000..091fd32 --- /dev/null +++ b/app/Actions/NotificationChannels/AddChannel.php @@ -0,0 +1,55 @@ +validate($input); + $channel = new NotificationChannel([ + 'user_id' => $user->id, + 'provider' => $input['provider'], + 'label' => $input['label'], + ]); + $this->validateType($channel, $input); + $channel->data = $channel->provider()->data($input); + $channel->save(); + + if (! $channel->provider()->connect()) { + $channel->delete(); + + throw ValidationException::withMessages([ + 'provider' => __('Could not connect'), + ]); + } + } + + /** + * @throws ValidationException + */ + protected function validate(array $input): void + { + Validator::make($input, [ + 'provider' => 'required|in:'.implode(',', config('core.notification_channels_providers')), + 'label' => 'required', + ])->validate(); + } + + /** + * @throws ValidationException + */ + protected function validateType(NotificationChannel $channel, array $input): void + { + Validator::make($input, $channel->provider()->validationRules()) + ->validate(); + } +} diff --git a/app/Actions/PHP/InstallNewPHP.php b/app/Actions/PHP/InstallNewPHP.php new file mode 100755 index 0000000..fe75a05 --- /dev/null +++ b/app/Actions/PHP/InstallNewPHP.php @@ -0,0 +1,52 @@ +validate($server, $input); + + $php = new Service([ + 'server_id' => $server->id, + 'type' => 'php', + 'type_data' => [ + 'extensions' => [], + 'settings' => config('core.php_settings'), + ], + 'name' => 'php', + 'version' => $input['version'], + 'status' => ServiceStatus::INSTALLING, + 'is_default' => false, + ]); + $php->save(); + $php->install(); + } + + /** + * @throws ValidationException + */ + private function validate(Server $server, array $input): void + { + Validator::make($input, [ + 'version' => [ + 'required', + Rule::in(config('core.php_versions')), + ], + ])->validateWithBag('installPHP'); + + if (in_array($input['version'], $server->installedPHPVersions())) { + throw ValidationException::withMessages( + ['version' => __('This version is already installed')] + )->errorBag('installPHP'); + } + } +} diff --git a/app/Actions/PHP/InstallPHPExtension.php b/app/Actions/PHP/InstallPHPExtension.php new file mode 100755 index 0000000..f310fa3 --- /dev/null +++ b/app/Actions/PHP/InstallPHPExtension.php @@ -0,0 +1,46 @@ +type_data; + $typeData['extensions'] = $typeData['extensions'] ?? []; + $service->type_data = $typeData; + $service->save(); + + $this->validate($service, $input); + + $service->handler()->installExtension($input['name']); + + return $service; + } + + /** + * @throws ValidationException + */ + private function validate(Service $service, array $input): void + { + Validator::make($input, [ + 'name' => [ + 'required', + 'in:'.implode(',', config('core.php_extensions')), + ], + ])->validateWithBag('installPHPExtension'); + + if (in_array($input['name'], $service->type_data['extensions'])) { + throw ValidationException::withMessages( + ['name' => __('This extension already installed')] + )->errorBag('installPHPExtension'); + } + } +} diff --git a/app/Actions/PHP/UninstallPHP.php b/app/Actions/PHP/UninstallPHP.php new file mode 100755 index 0000000..b655791 --- /dev/null +++ b/app/Actions/PHP/UninstallPHP.php @@ -0,0 +1,39 @@ +validate($server, $version); + + $php = $server->services()->where('type', 'php')->where('version', $version)->first(); + + $php->uninstall(); + } + + /** + * @throws ValidationException + */ + private function validate(Server $server, string $version): void + { + $php = $server->services()->where('type', 'php')->where('version', $version)->first(); + + if (! $php) { + throw ValidationException::withMessages( + ['version' => __('This version has not been installed yet!')] + ); + } + + $hasSite = $server->sites()->where('php_version', $version)->first(); + if ($hasSite) { + throw ValidationException::withMessages( + ['version' => __('Cannot uninstall this version because some sites are using it!')] + ); + } + } +} diff --git a/app/Actions/PHP/UpdatePHPIni.php b/app/Actions/PHP/UpdatePHPIni.php new file mode 100755 index 0000000..09849f2 --- /dev/null +++ b/app/Actions/PHP/UpdatePHPIni.php @@ -0,0 +1,40 @@ +put($tmpName, $ini); + $service->server->ssh('root')->upload( + Storage::disk('local')->path($tmpName), + "/etc/php/$service->version/cli/php.ini" + ); + $this->deleteTempFile($tmpName); + } catch (Throwable) { + $this->deleteTempFile($tmpName); + throw ValidationException::withMessages([ + 'ini' => __("Couldn't update php.ini file!"), + ]); + } + } + + private function deleteTempFile(string $name): void + { + if (Storage::disk('local')->exists($name)) { + Storage::disk('local')->delete($name); + } + } +} diff --git a/app/Actions/Queue/CreateQueue.php b/app/Actions/Queue/CreateQueue.php new file mode 100644 index 0000000..42b15ce --- /dev/null +++ b/app/Actions/Queue/CreateQueue.php @@ -0,0 +1,65 @@ +validate($input); + + $queue = new Queue([ + 'server_id' => $queueable instanceof Server ? $queueable->id : $queueable->server_id, + 'site_id' => $queueable instanceof Site ? $queueable->id : null, + 'command' => $input['command'], + 'user' => $input['user'], + 'auto_start' => $input['auto_start'], + 'auto_restart' => $input['auto_restart'], + 'numprocs' => $input['numprocs'], + 'status' => QueueStatus::CREATING, + ]); + $queue->save(); + $queue->deploy(); + } + + /** + * @throws ValidationException + */ + protected function validate(array $input): void + { + $rules = [ + 'command' => [ + 'required', + ], + 'user' => [ + 'required', + 'in:root,'.config('core.ssh_user'), + ], + 'auto_start' => [ + 'required', + 'in:0,1', + ], + 'auto_restart' => [ + 'required', + 'in:0,1', + ], + 'numprocs' => [ + 'required', + 'numeric', + 'min:1', + ], + ]; + + Validator::make($input, $rules)->validateWithBag('createQueue'); + } +} diff --git a/app/Actions/SSL/CreateSSL.php b/app/Actions/SSL/CreateSSL.php new file mode 100644 index 0000000..18076da --- /dev/null +++ b/app/Actions/SSL/CreateSSL.php @@ -0,0 +1,47 @@ +validate($input); + + if ($input['type'] == SslType::LETSENCRYPT) { + $site->createFreeSsl(); + } + + if ($input['type'] == SslType::CUSTOM) { + $site->createCustomSsl($input['certificate'], $input['private']); + } + } + + /** + * @throws ValidationException + */ + protected function validate(array $input): void + { + $rules = [ + 'type' => [ + 'required', + Rule::in(SslType::getValues()), + ], + ]; + if (isset($input['type']) && $input['type'] == SslType::CUSTOM) { + $rules['certificate'] = 'required'; + $rules['private'] = 'required'; + } + + Validator::make($input, $rules)->validateWithBag('createSSL'); + } +} diff --git a/app/Actions/Script/CreateScript.php b/app/Actions/Script/CreateScript.php new file mode 100644 index 0000000..a469a6c --- /dev/null +++ b/app/Actions/Script/CreateScript.php @@ -0,0 +1,41 @@ +validateInputs($input); + + $script = new Script([ + 'user_id' => $creator->id, + 'name' => $input['name'], + 'content' => $input['content'], + ]); + $script->save(); + + return $script; + } + + /** + * @throws ValidationException + */ + private function validateInputs(array $input): void + { + $rules = [ + 'name' => 'required', + 'content' => 'required', + ]; + + Validator::make($input, $rules)->validateWithBag('createScript'); + } +} diff --git a/app/Actions/Script/GetScripts.php b/app/Actions/Script/GetScripts.php new file mode 100755 index 0000000..5aeac76 --- /dev/null +++ b/app/Actions/Script/GetScripts.php @@ -0,0 +1,17 @@ +scripts() + ->orderBy('id', 'desc') + ->paginate(6) + ->onEachSide(1); + } +} diff --git a/app/Actions/Script/UpdateScript.php b/app/Actions/Script/UpdateScript.php new file mode 100644 index 0000000..267ca35 --- /dev/null +++ b/app/Actions/Script/UpdateScript.php @@ -0,0 +1,37 @@ +validateInputs($input); + + $script->name = $input['name']; + $script->content = $input['content']; + $script->save(); + + return $script; + } + + /** + * @throws ValidationException + */ + private function validateInputs(array $input): void + { + $rules = [ + 'name' => 'required', + 'content' => 'required', + ]; + + Validator::make($input, $rules)->validateWithBag('updateScript'); + } +} diff --git a/app/Actions/Server/CreateServer.php b/app/Actions/Server/CreateServer.php new file mode 100755 index 0000000..082b672 --- /dev/null +++ b/app/Actions/Server/CreateServer.php @@ -0,0 +1,183 @@ +validateInputs($input); + + $server = new Server([ + 'user_id' => $creator->id, + 'name' => $input['name'], + 'ssh_user' => config('core.server_providers_default_user')[$input['provider']][$input['os']], + 'ip' => $input['ip'], + 'port' => $input['port'] ?? 22, + 'os' => $input['os'], + 'type' => $input['type'], + 'provider' => $input['provider'], + 'authentication' => [ + 'user' => config('core.ssh_user'), + 'pass' => Str::random(10), + 'root_pass' => Str::random(10), + ], + 'progress' => 0, + 'progress_step' => 'Initializing', + ]); + + try { + DB::beginTransaction(); + + if ($server->provider != 'custom') { + $server->provider_id = $input['server_provider']; + } + + // validate type + $this->validateType($server, $input); + $server->type_data = $server->type()->data($input); + + // validate provider + $this->validateProvider($server, $input); + $server->provider_data = $server->provider()->data($input); + + // save + $server->save(); + + // create firewall rules + $this->createFirewallRules($server); + + // create instance + $server->provider()->create(); + + // add services + $server->type()->createServices($input); + + // install server + if ($server->provider == 'custom') { + $server->install(); + } else { + $server->progress_step = __('Installation will begin in 3 minutes!'); + $server->save(); + dispatch(new ContinueInstallation($server)) + ->delay(now()->addMinutes(3)) + ->onQueue('default'); + } + DB::commit(); + + return $server; + } catch (Exception $e) { + $server->provider()->delete(); + DB::rollBack(); + if ($e instanceof ServerProviderError) { + throw ValidationException::withMessages([ + 'provider' => __('Provider Error: ').$e->getMessage(), + ])->errorBag('createServer'); + } + throw $e; + } + } + + /** + * @throws ValidationException + */ + private function validateInputs(array $input): void + { + $rules = [ + 'provider' => 'required|in:'.implode(',', config('core.server_providers')), + 'name' => 'required', + 'os' => 'required|in:'.implode(',', config('core.operating_systems')), + 'type' => [ + 'required', + Rule::in(config('core.server_types')), + ], + ]; + + Validator::make($input, $rules)->validate(); + + if ($input['provider'] != 'custom') { + $rules['server_provider'] = 'required|exists:server_providers,id,user_id,'.auth()->user()->id; + } + + if ($input['provider'] == 'custom') { + $rules['ip'] = [ + 'required', + 'ip', + new RestrictedIPAddressesRule(), + ]; + $rules['port'] = [ + 'required', + 'numeric', + 'min:1', + 'max:65535', + ]; + } + + Validator::make($input, $rules)->validate(); + } + + /** + * @throws ValidationException + */ + private function validateType(Server $server, array $input): void + { + Validator::make($input, $server->type()->createValidationRules($input)) + ->validate(); + } + + /** + * @throws ValidationException + */ + private function validateProvider(Server $server, array $input): void + { + Validator::make($input, $server->provider()->createValidationRules($input)) + ->validate(); + } + + private function createFirewallRules(Server $server): void + { + $server->firewallRules()->createMany([ + [ + 'type' => 'allow', + 'protocol' => 'ssh', + 'port' => 22, + 'source' => '0.0.0.0', + 'mask' => 0, + 'status' => FirewallRuleStatus::READY, + ], + [ + 'type' => 'allow', + 'protocol' => 'http', + 'port' => 80, + 'source' => '0.0.0.0', + 'mask' => 0, + 'status' => FirewallRuleStatus::READY, + ], + [ + 'type' => 'allow', + 'protocol' => 'https', + 'port' => 443, + 'source' => '0.0.0.0', + 'mask' => 0, + 'status' => FirewallRuleStatus::READY, + ], + ]); + } +} diff --git a/app/Actions/Server/DeleteServer.php b/app/Actions/Server/DeleteServer.php new file mode 100755 index 0000000..08daec8 --- /dev/null +++ b/app/Actions/Server/DeleteServer.php @@ -0,0 +1,33 @@ +validateDelete($input); + + DB::transaction(function () use ($server) { + $server->cleanDelete(); + }); + } + + /** + * @throws ValidationException + */ + protected function validateDelete(array $input): void + { + Validator::make($input, [ + 'confirm' => 'required|in:delete', + ])->validateWithBag('deleteServer'); + } +} diff --git a/app/Actions/Server/EditServer.php b/app/Actions/Server/EditServer.php new file mode 100755 index 0000000..85187fe --- /dev/null +++ b/app/Actions/Server/EditServer.php @@ -0,0 +1,55 @@ +validate($input); + + $checkConnection = false; + if (isset($input['name'])) { + $server->name = $input['name']; + } + if (isset($input['ip'])) { + if ($server->ip !== $input['ip']) { + $checkConnection = true; + } + $server->ip = $input['ip']; + } + if (isset($input['port'])) { + if ($server->port !== $input['port']) { + $checkConnection = true; + } + $server->port = $input['port']; + } + $server->save(); + + if ($checkConnection) { + $server->checkConnection(); + } + + return $server; + } + + /** + * @throws ValidationException + */ + protected function validate(array $input): void + { + Validator::make($input, [ + 'ip' => [ + new RestrictedIPAddressesRule(), + ], + ])->validateWithBag('editServer'); + } +} diff --git a/app/Actions/Server/GetServers.php b/app/Actions/Server/GetServers.php new file mode 100755 index 0000000..d7d33a3 --- /dev/null +++ b/app/Actions/Server/GetServers.php @@ -0,0 +1,14 @@ +latest()->get(); + } +} diff --git a/app/Actions/ServerProvider/CreateServerProvider.php b/app/Actions/ServerProvider/CreateServerProvider.php new file mode 100644 index 0000000..750bed7 --- /dev/null +++ b/app/Actions/ServerProvider/CreateServerProvider.php @@ -0,0 +1,77 @@ +validateInput($input); + + $provider = $this->getProvider($input['provider']); + + $this->validateProvider($provider, $input); + + try { + $provider->connect($input); + } catch (Exception) { + throw ValidationException::withMessages([ + 'provider' => [ + __("Couldn't connect to provider. Please check your credentials and try again later."), + ], + ]); + } + + $serverProvider = new ServerProvider(); + $serverProvider->user_id = $user->id; + $serverProvider->profile = $input['name']; + $serverProvider->provider = $input['provider']; + $serverProvider->credentials = $provider->credentialData($input); + $serverProvider->save(); + + return $serverProvider; + } + + private function getProvider($name): ServerProviderContract + { + $providerClass = config('core.server_providers_class.'.$name); + + return new $providerClass(); + } + + /** + * @throws ValidationException + */ + private function validateInput(array $input): void + { + Validator::make($input, [ + 'name' => [ + 'required', + ], + 'provider' => [ + 'required', + Rule::in(config('core.server_providers')), + Rule::notIn('custom'), + ], + ])->validate(); + } + + /** + * @throws ValidationException + */ + private function validateProvider(ServerProviderContract $provider, array $input): void + { + Validator::make($input, $provider->credentialValidationRules($input))->validate(); + } +} diff --git a/app/Actions/Site/ChangePHPVersion.php b/app/Actions/Site/ChangePHPVersion.php new file mode 100755 index 0000000..94bc56a --- /dev/null +++ b/app/Actions/Site/ChangePHPVersion.php @@ -0,0 +1,30 @@ +validate($site, $input); + + $site->changePHPVersion($input['php_version']); + } + + /** + * @throws ValidationException + */ + protected function validate(Site $site, array $input): void + { + Validator::make($input, [ + 'php_version' => 'required|in:'.implode(',', $site->server->installedPHPVersions()), + ])->validateWithBag('changePHPVersion'); + } +} diff --git a/app/Actions/Site/CreateRedirect.php b/app/Actions/Site/CreateRedirect.php new file mode 100644 index 0000000..b685275 --- /dev/null +++ b/app/Actions/Site/CreateRedirect.php @@ -0,0 +1,51 @@ +validate($input); + + $redirect = new Redirect([ + 'site_id' => $site->id, + 'mode' => $input['mode'], + 'from' => $input['from'], + 'to' => $input['to'], + ]); + $redirect->save(); + $redirect->addToServer(); + } + + /** + * @throws ValidationException + */ + private function validate(array $input): void + { + $rules = [ + 'mode' => [ + 'required', + 'in:301,302', + ], + 'from' => [ + 'required', + ], + 'to' => [ + 'required', + 'url', + ], + ]; + + Validator::make($input, $rules)->validateWithBag('createRedirect'); + } +} diff --git a/app/Actions/Site/CreateSite.php b/app/Actions/Site/CreateSite.php new file mode 100755 index 0000000..b869c09 --- /dev/null +++ b/app/Actions/Site/CreateSite.php @@ -0,0 +1,118 @@ +validateInputs($server, $input); + + try { + DB::beginTransaction(); + + $site = new Site([ + 'server_id' => $server->id, + 'type' => $input['type'], + 'domain' => $input['domain'], + 'aliases' => isset($input['alias']) ? [$input['alias']] : [], + 'path' => '/home/'.$server->ssh_user.'/'.$input['domain'], + 'status' => SiteStatus::INSTALLING, + ]); + + // fields based on type + $site->fill($site->type()->createFields($input)); + + // check has access to repository + try { + if ($site->sourceControl()) { + $site->sourceControl()->getRepo($site->repository); + } + } catch (SourceControlIsNotConnected) { + throw ValidationException::withMessages([ + 'source_control' => __('Source control is not connected'), + ]); + } + + // detect php version + if ($site->type()->language() === 'php') { + $site->php_version = $input['php_version']; + } + + // validate type + $this->validateType($site, $input); + + // set type data + $site->type_data = $site->type()->data($input); + + // save + $site->save(); + + // create default deployment script + $site->deploymentScript()->create([ + 'name' => 'default', + 'content' => '', + ]); + + // install server + $site->install(); + + DB::commit(); + + return $site; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + /** + * @throws ValidationException + */ + private function validateInputs(Server $server, array $input): void + { + $rules = [ + 'type' => [ + 'required', + Rule::in(config('core.site_types')), + ], + 'domain' => [ + 'required', + new DomainRule(), + Rule::unique('sites', 'domain')->where(function ($query) use ($server) { + return $query->where('server_id', $server->id); + }), + ], + 'alias' => [ + new DomainRule(), + ], + ]; + + Validator::make($input, $rules)->validate(); + } + + /** + * @throws ValidationException + */ + private function validateType(Site $site, array $input): void + { + $rules = $site->type()->createValidationRules($input); + + Validator::make($input, $rules)->validate(); + } +} diff --git a/app/Actions/Site/DeleteSite.php b/app/Actions/Site/DeleteSite.php new file mode 100755 index 0000000..e2adc27 --- /dev/null +++ b/app/Actions/Site/DeleteSite.php @@ -0,0 +1,32 @@ +validateDelete($input); + + $site->update(['status' => 'deleting']); + + $site->remove(); + } + + /** + * @throws ValidationException + */ + protected function validateDelete(array $input): void + { + Validator::make($input, [ + 'confirm' => 'required|in:delete', + ])->validateWithBag('deleteSite'); + } +} diff --git a/app/Actions/Site/EditSite.php b/app/Actions/Site/EditSite.php new file mode 100755 index 0000000..02d678d --- /dev/null +++ b/app/Actions/Site/EditSite.php @@ -0,0 +1,41 @@ +validateType($site, $input); + + // set type data + $site->type_data = $site->type()->data($input); + + // save + $site->port = $input['port'] ?? null; + $site->save(); + + // edit + $site->type()->edit(); + + return $site; + } + + /** + * @throws ValidationException + */ + private function validateType(Site $site, array $input): void + { + $rules = $site->type()->editValidationRules($input); + + Validator::make($input, $rules)->validateWithBag('editSite'); + } +} diff --git a/app/Actions/Site/GetSites.php b/app/Actions/Site/GetSites.php new file mode 100755 index 0000000..6a69214 --- /dev/null +++ b/app/Actions/Site/GetSites.php @@ -0,0 +1,14 @@ +sites()->orderBy('id', 'desc')->get(); + } +} diff --git a/app/Actions/Site/UpdateBranch.php b/app/Actions/Site/UpdateBranch.php new file mode 100755 index 0000000..7cc5b0d --- /dev/null +++ b/app/Actions/Site/UpdateBranch.php @@ -0,0 +1,30 @@ +validate($input); + + $site->updateBranch($input['branch']); + } + + /** + * @throws ValidationException + */ + protected function validate(array $input): void + { + Validator::make($input, [ + 'branch' => 'required', + ])->validateWithBag('updateBranch'); + } +} diff --git a/app/Actions/Site/UpdateDeploymentScript.php b/app/Actions/Site/UpdateDeploymentScript.php new file mode 100755 index 0000000..eaf207b --- /dev/null +++ b/app/Actions/Site/UpdateDeploymentScript.php @@ -0,0 +1,32 @@ +validate($input); + + $site->deploymentScript()->update([ + 'content' => $input['script'], + ]); + } + + /** + * @throws ValidationException + */ + protected function validate(array $input): void + { + Validator::make($input, [ + 'script' => 'required', + ])->validateWithBag('updateDeploymentScript'); + } +} diff --git a/app/Actions/Site/UpdateEnv.php b/app/Actions/Site/UpdateEnv.php new file mode 100755 index 0000000..a41dcee --- /dev/null +++ b/app/Actions/Site/UpdateEnv.php @@ -0,0 +1,18 @@ +type_data; + $typeData['env'] = $input['env']; + $site->type_data = $typeData; + $site->save(); + + $site->deployEnv(); + } +} diff --git a/app/Actions/SourceControl/ConnectSourceControl.php b/app/Actions/SourceControl/ConnectSourceControl.php new file mode 100644 index 0000000..4e7a881 --- /dev/null +++ b/app/Actions/SourceControl/ConnectSourceControl.php @@ -0,0 +1,35 @@ +where('provider', $provider) + ->first(); + if (! $sourceControl) { + $sourceControl = new SourceControl([ + 'provider' => $provider, + ]); + } + + if (! $input['token']) { + $sourceControl->delete(); + + return; + } + + $sourceControl->access_token = $input['token']; + if (! $sourceControl->provider()->connect()) { + throw ValidationException::withMessages([ + 'token' => __('Cannot connect to :provider or invalid token!', ['provider' => $provider]), + ]); + } + $sourceControl->save(); + } +} diff --git a/app/Actions/SshKey/CreateSshKey.php b/app/Actions/SshKey/CreateSshKey.php new file mode 100644 index 0000000..116c5af --- /dev/null +++ b/app/Actions/SshKey/CreateSshKey.php @@ -0,0 +1,43 @@ +validate($input); + + $key = new SshKey([ + 'user_id' => $user->id, + 'name' => $input['name'], + 'public_key' => $input['public_key'], + ]); + $key->save(); + + return $key; + } + + /** + * @throws ValidationException + */ + private function validate(array $input): void + { + Validator::make($input, [ + 'name' => 'required', + 'public_key' => [ + 'required', + new SshKeyRule(), + ], + ])->validate(); + } +} diff --git a/app/Actions/StorageProvider/AddStorageProvider.php b/app/Actions/StorageProvider/AddStorageProvider.php new file mode 100644 index 0000000..b2a02b9 --- /dev/null +++ b/app/Actions/StorageProvider/AddStorageProvider.php @@ -0,0 +1,30 @@ +validate($user, $input); + + $storageProvider = new StorageProvider([ + 'user_id' => $user->id, + 'provider' => $input['provider'], + 'label' => $input['label'], + 'connected' => false, + ]); + $storageProvider->save(); + + return $storageProvider->provider()->connect(); + } +} diff --git a/app/Actions/StorageProvider/HandleProviderCallback.php b/app/Actions/StorageProvider/HandleProviderCallback.php new file mode 100755 index 0000000..5242e2c --- /dev/null +++ b/app/Actions/StorageProvider/HandleProviderCallback.php @@ -0,0 +1,34 @@ +session()->get('storage_provider_id'); + /** @var StorageProvider $storageProvider */ + $storageProvider = StorageProvider::query()->findOrFail($providerId); + /** @var User $oauthUser */ + $oauthUser = Socialite::driver($provider)->user(); + $storageProvider->token = $oauthUser->token; + $storageProvider->refresh_token = $oauthUser->refreshToken; + $storageProvider->token_expires_at = now()->addSeconds($oauthUser->expiresIn); + $storageProvider->connected = true; + $storageProvider->save(); + /** @TODO toast success message */ + } catch (Throwable) { + /** @TODO toast failed message */ + } + + return redirect()->route('storage-providers'); + } +} diff --git a/app/Actions/StorageProvider/ValidateProvider.php b/app/Actions/StorageProvider/ValidateProvider.php new file mode 100755 index 0000000..6b0ca05 --- /dev/null +++ b/app/Actions/StorageProvider/ValidateProvider.php @@ -0,0 +1,28 @@ + [ + 'required', + Rule::unique('storage_providers', 'label')->where('user_id', $user->id), + ], + 'provider' => [ + 'required', + Rule::in(config('core.storage_providers')), + ], + ])->validateWithBag('addStorageProvider'); + } +} diff --git a/app/Actions/User/UpdateUserPassword.php b/app/Actions/User/UpdateUserPassword.php new file mode 100755 index 0000000..5026bc3 --- /dev/null +++ b/app/Actions/User/UpdateUserPassword.php @@ -0,0 +1,25 @@ + ['required', 'string', 'current-password'], + 'password' => ['required', 'string'], + 'password_confirmation' => ['required', 'same:password'], + ])->validate(); + + $user->forceFill([ + 'password' => Hash::make($input['password']), + ])->save(); + } +} diff --git a/app/Actions/User/UpdateUserProfileInformation.php b/app/Actions/User/UpdateUserProfileInformation.php new file mode 100755 index 0000000..6efa12c --- /dev/null +++ b/app/Actions/User/UpdateUserProfileInformation.php @@ -0,0 +1,44 @@ + ['required', 'string', 'max:255'], + 'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)], + ])->validateWithBag('updateProfileInformation'); + + if ($input['email'] !== $user->email) { + $this->updateVerifiedUser($user, $input); + } else { + $user->forceFill([ + 'name' => $input['name'], + 'email' => $input['email'], + ])->save(); + } + } + + /** + * Update the given verified user's profile information. + */ + protected function updateVerifiedUser(User $user, array $input): void + { + $user->forceFill([ + 'name' => $input['name'], + 'email' => $input['email'], + ])->save(); + } +} diff --git a/app/Console/Commands/CreateDatabaseCommand.php b/app/Console/Commands/CreateDatabaseCommand.php new file mode 100644 index 0000000..ab1d30c --- /dev/null +++ b/app/Console/Commands/CreateDatabaseCommand.php @@ -0,0 +1,28 @@ + null]); + + $query = "CREATE DATABASE IF NOT EXISTS $schemaName"; + + DB::statement($query); + + config(["database.connections.mysql.database" => $schemaName]); + + $this->info(sprintf("Database `%s` created successfully.", $schemaName)); + } +} diff --git a/app/Console/Commands/CreateUserCommand.php b/app/Console/Commands/CreateUserCommand.php new file mode 100644 index 0000000..cef1c15 --- /dev/null +++ b/app/Console/Commands/CreateUserCommand.php @@ -0,0 +1,26 @@ + $this->argument('name'), + 'email' => $this->argument('email'), + 'password' => bcrypt($password), + ]); + + $this->info("User created with password: {$password}"); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php new file mode 100644 index 0000000..e6b9960 --- /dev/null +++ b/app/Console/Kernel.php @@ -0,0 +1,27 @@ +command('inspire')->hourly(); + } + + /** + * Register the commands for the application. + */ + protected function commands(): void + { + $this->load(__DIR__.'/Commands'); + + require base_path('routes/console.php'); + } +} diff --git a/app/Contracts/Database.php b/app/Contracts/Database.php new file mode 100755 index 0000000..aabcb24 --- /dev/null +++ b/app/Contracts/Database.php @@ -0,0 +1,24 @@ +, \Psr\Log\LogLevel::*> + */ + protected $levels = [ + // + ]; + + /** + * A list of the exception types that are not reported. + * + * @var array> + */ + protected $dontReport = [ + // + ]; + + /** + * A list of the inputs that are never flashed to the session on validation exceptions. + * + * @var array + */ + protected $dontFlash = [ + 'current_password', + 'password', + 'password_confirmation', + ]; + + /** + * Register the exception handling callbacks for the application. + */ + public function register(): void + { + $this->reportable(function (Throwable $e) { + // + }); + } +} diff --git a/app/Exceptions/InstallationFailed.php b/app/Exceptions/InstallationFailed.php new file mode 100644 index 0000000..750ed44 --- /dev/null +++ b/app/Exceptions/InstallationFailed.php @@ -0,0 +1,10 @@ +connection = null; + $this->log = null; + $this->asUser = null; + $this->server = $server->refresh(); + $this->user = $server->ssh_user; + if ($asUser && $asUser != $server->ssh_user) { + $this->user = $asUser; + $this->asUser = $asUser; + } + $this->publicKey = $this->server->sshKey($defaultKeys)['public_key_path']; + $this->privateKey = $this->server->sshKey($defaultKeys)['private_key_path']; + + return $this; + } + + public function setLog(string $logType, $siteId = null): void + { + $this->log = $this->server->logs()->create([ + 'site_id' => $siteId, + 'name' => $this->server->id.'-'.strtotime('now').'-'.$logType.'.log', + 'type' => $logType, + 'disk' => config('core.logs_disk'), + ]); + } + + /** + * @throws Throwable + */ + public function connect(): void + { + $defaultTimeout = ini_get('default_socket_timeout'); + ini_set('default_socket_timeout', 7); + + try { + if (! ($this->connection = ssh2_connect($this->server->ip, $this->server->port))) { + throw new SSHConnectionError('Cannot connect to the server'); + } + + if (! ssh2_auth_pubkey_file($this->connection, $this->user, $this->publicKey, $this->privateKey)) { + throw new SSHAuthenticationError('Authentication failed'); + } + } catch (Throwable $e) { + ini_set('default_socket_timeout', $defaultTimeout); + if ($this->server->status == 'ready') { + $this->server->status = 'disconnected'; + $this->server->save(); + } + throw $e; + } + + ini_set('default_socket_timeout', $defaultTimeout); + } + + /** + * @throws Throwable + */ + public function exec(string|array|SSHCommand $commands, string $log = '', int $siteId = null): string + { + if ($log) { + $this->setLog($log, $siteId); + } else { + $this->log = null; + } + + if (! $this->connection) { + $this->connect(); + } + + if (! is_array($commands)) { + $commands = [$commands]; + } + + $result = ''; + foreach ($commands as $command) { + $result .= $this->executeCommand($command); + } + + return $result; + } + + /** + * @throws Throwable + */ + public function upload(string $local, string $remote): void + { + if (! $this->connection) { + $this->connect(); + } + + $sftp = @ssh2_sftp($this->connection); + if (! $sftp) { + throw new Exception('Could not initialize SFTP'); + } + + $stream = @fopen("ssh2.sftp://$sftp$remote", 'w'); + + if (! $stream) { + throw new Exception("Could not open file: $remote"); + } + + $data_to_send = @file_get_contents($local); + if ($data_to_send === false) { + throw new Exception("Could not open local file: $local."); + } + + if (@fwrite($stream, $data_to_send) === false) { + throw new Exception("Could not send data from file: $local."); + } + + @fclose($stream); + } + + /** + * @throws Exception + */ + protected function executeCommand(string|SSHCommand $command): string + { + if ($command instanceof SSHCommand) { + $commandContent = $command->content($this->server->os); + } else { + $commandContent = $command; + } + + if ($this->asUser) { + $commandContent = 'sudo su - '.$this->asUser.' -c '.'"'.addslashes($commandContent).'"'; + } + + if (! ($stream = ssh2_exec($this->connection, $commandContent, 'vt102', [], 100, 30))) { + throw new Exception('SSH command failed'); + } + + $data = ''; + try { + stream_set_blocking($stream, true); + while ($buf = fread($stream, 1024)) { + $data .= $buf; + $this->log?->write($buf); + } + fclose($stream); + } catch (Throwable) { + $data = 'Error reading data'; + } + + if (Str::contains($data, 'VITO_SSH_ERROR')) { + throw new Exception('SSH command failed with an error'); + } + + return $data; + } + + /** + * @throws Exception + */ + public function disconnect(): void + { + if ($this->connection) { + try { + ssh2_disconnect($this->connection); + } catch (Exception) { + // + } + $this->connection = null; + } + } +} diff --git a/app/Helpers/Toast.php b/app/Helpers/Toast.php new file mode 100644 index 0000000..12aed46 --- /dev/null +++ b/app/Helpers/Toast.php @@ -0,0 +1,40 @@ +toast('success', $message); + } + + public function error(string $message): void + { + $this->toast('error', $message); + } + + public function warning(string $message): void + { + $this->toast('warning', $message); + } + + public function info(string $message): void + { + $this->toast('info', $message); + } + + private function toast(string $type, string $message): void + { + $this->component->dispatchBrowserEvent('toast', [ + 'type' => $type, + 'message' => $message, + ]); + } +} diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php new file mode 100644 index 0000000..494a106 --- /dev/null +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -0,0 +1,48 @@ +authenticate(); + + $request->session()->regenerate(); + + return redirect()->intended(RouteServiceProvider::HOME); + } + + /** + * Destroy an authenticated session. + */ + public function destroy(Request $request): RedirectResponse + { + Auth::guard('web')->logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + return redirect('/'); + } +} diff --git a/app/Http/Controllers/Auth/ConfirmablePasswordController.php b/app/Http/Controllers/Auth/ConfirmablePasswordController.php new file mode 100644 index 0000000..523ddda --- /dev/null +++ b/app/Http/Controllers/Auth/ConfirmablePasswordController.php @@ -0,0 +1,41 @@ +validate([ + 'email' => $request->user()->email, + 'password' => $request->password, + ])) { + throw ValidationException::withMessages([ + 'password' => __('auth.password'), + ]); + } + + $request->session()->put('auth.password_confirmed_at', time()); + + return redirect()->intended(RouteServiceProvider::HOME); + } +} diff --git a/app/Http/Controllers/Auth/NewPasswordController.php b/app/Http/Controllers/Auth/NewPasswordController.php new file mode 100644 index 0000000..79ac3cd --- /dev/null +++ b/app/Http/Controllers/Auth/NewPasswordController.php @@ -0,0 +1,61 @@ + $request]); + } + + /** + * Handle an incoming new password request. + * + * @throws \Illuminate\Validation\ValidationException + */ + public function store(Request $request): RedirectResponse + { + $request->validate([ + 'token' => ['required'], + 'email' => ['required', 'email'], + 'password' => ['required', 'confirmed', Rules\Password::defaults()], + ]); + + // Here we will attempt to reset the user's password. If it is successful we + // will update the password on an actual user model and persist it to the + // database. Otherwise we will parse the error and return the response. + $status = Password::reset( + $request->only('email', 'password', 'password_confirmation', 'token'), + function ($user) use ($request) { + $user->forceFill([ + 'password' => Hash::make($request->password), + 'remember_token' => Str::random(60), + ])->save(); + + event(new PasswordReset($user)); + } + ); + + // If the password was successfully reset, we will redirect the user back to + // the application's home authenticated view. If there is an error we can + // redirect them back to where they came from with their error message. + return $status == Password::PASSWORD_RESET + ? redirect()->route('login')->with('status', __($status)) + : back()->withInput($request->only('email')) + ->withErrors(['email' => __($status)]); + } +} diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php new file mode 100644 index 0000000..6916409 --- /dev/null +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -0,0 +1,29 @@ +validateWithBag('updatePassword', [ + 'current_password' => ['required', 'current_password'], + 'password' => ['required', Password::defaults(), 'confirmed'], + ]); + + $request->user()->update([ + 'password' => Hash::make($validated['password']), + ]); + + return back()->with('status', 'password-updated'); + } +} diff --git a/app/Http/Controllers/Auth/PasswordResetLinkController.php b/app/Http/Controllers/Auth/PasswordResetLinkController.php new file mode 100644 index 0000000..bf1ebfa --- /dev/null +++ b/app/Http/Controllers/Auth/PasswordResetLinkController.php @@ -0,0 +1,44 @@ +validate([ + 'email' => ['required', 'email'], + ]); + + // We will send the password reset link to this user. Once we have attempted + // to send the link, we will examine the response then see the message we + // need to show to the user. Finally, we'll send out a proper response. + $status = Password::sendResetLink( + $request->only('email') + ); + + return $status == Password::RESET_LINK_SENT + ? back()->with('status', __($status)) + : back()->withInput($request->only('email')) + ->withErrors(['email' => __($status)]); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php new file mode 100644 index 0000000..77ec359 --- /dev/null +++ b/app/Http/Controllers/Controller.php @@ -0,0 +1,12 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/DaemonController.php b/app/Http/Controllers/DaemonController.php new file mode 100644 index 0000000..933d439 --- /dev/null +++ b/app/Http/Controllers/DaemonController.php @@ -0,0 +1,15 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php new file mode 100644 index 0000000..51707f9 --- /dev/null +++ b/app/Http/Controllers/DatabaseController.php @@ -0,0 +1,15 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/FirewallController.php b/app/Http/Controllers/FirewallController.php new file mode 100644 index 0000000..4afe79f --- /dev/null +++ b/app/Http/Controllers/FirewallController.php @@ -0,0 +1,15 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/PHPController.php b/app/Http/Controllers/PHPController.php new file mode 100644 index 0000000..b9850e3 --- /dev/null +++ b/app/Http/Controllers/PHPController.php @@ -0,0 +1,15 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/SSHKeyController.php b/app/Http/Controllers/SSHKeyController.php new file mode 100644 index 0000000..a463945 --- /dev/null +++ b/app/Http/Controllers/SSHKeyController.php @@ -0,0 +1,15 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php new file mode 100644 index 0000000..a16ffbf --- /dev/null +++ b/app/Http/Controllers/ServerController.php @@ -0,0 +1,28 @@ + $server, + ]); + } +} diff --git a/app/Http/Controllers/SiteController.php b/app/Http/Controllers/SiteController.php new file mode 100644 index 0000000..d100795 --- /dev/null +++ b/app/Http/Controllers/SiteController.php @@ -0,0 +1,72 @@ + $server, + ]); + } + + public function create(Server $server): View + { + return view('sites.create', [ + 'server' => $server, + ]); + } + + public function show(Server $server, Site $site): View + { + return view('sites.show', [ + 'server' => $server, + 'site' => $site, + ]); + } + + public function application(Server $server, Site $site): View + { + return view('sites.application', [ + 'server' => $server, + 'site' => $site, + ]); + } + + public function ssl(Server $server, Site $site): View + { + return view('sites.ssl', [ + 'server' => $server, + 'site' => $site, + ]); + } + + public function queues(Server $server, Site $site): View + { + return view('sites.queues', [ + 'server' => $server, + 'site' => $site, + ]); + } + + public function settings(Server $server, Site $site): View + { + return view('sites.settings', [ + 'server' => $server, + 'site' => $site, + ]); + } + + public function logs(Server $server, Site $site): View + { + return view('sites.logs', [ + 'server' => $server, + 'site' => $site, + ]); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php new file mode 100644 index 0000000..c34cdcf --- /dev/null +++ b/app/Http/Kernel.php @@ -0,0 +1,67 @@ + + */ + protected $middleware = [ + // \App\Http\Middleware\TrustHosts::class, + \App\Http\Middleware\TrustProxies::class, + \Illuminate\Http\Middleware\HandleCors::class, + \App\Http\Middleware\PreventRequestsDuringMaintenance::class, + \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, + \App\Http\Middleware\TrimStrings::class, + \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array> + */ + protected $middlewareGroups = [ + 'web' => [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + + 'api' => [ + // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + ]; + + /** + * The application's middleware aliases. + * + * Aliases may be used to conveniently assign middleware to routes and groups. + * + * @var array + */ + protected $middlewareAliases = [ + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, + 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, + 'signed' => \App\Http\Middleware\ValidateSignature::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + ]; +} diff --git a/app/Http/Livewire/Application/ChangeBranch.php b/app/Http/Livewire/Application/ChangeBranch.php new file mode 100644 index 0000000..f528e0a --- /dev/null +++ b/app/Http/Livewire/Application/ChangeBranch.php @@ -0,0 +1,35 @@ +branch = $this->site->branch; + } + + public function change(): void + { + app(UpdateBranch::class)->update($this->site, $this->all()); + + session()->flash('status', 'updating-branch'); + } + + public function render(): View + { + return view('livewire.application.change-branch'); + } +} diff --git a/app/Http/Livewire/Application/Deploy.php b/app/Http/Livewire/Application/Deploy.php new file mode 100644 index 0000000..3f6545a --- /dev/null +++ b/app/Http/Livewire/Application/Deploy.php @@ -0,0 +1,40 @@ +site->deploy(); + + $this->toast()->success(__('Deployment started!')); + + $this->emitTo(DeploymentsList::class, '$refresh'); + + $this->emitTo(DeploymentScript::class, '$refresh'); + } catch (SourceControlIsNotConnected $e) { + session()->flash('toast.type', 'error'); + session()->flash('toast.message', $e->getMessage()); + $this->redirect(route('source-controls')); + } + } + + public function render(): View + { + return view('livewire.application.deploy'); + } +} diff --git a/app/Http/Livewire/Application/DeploymentScript.php b/app/Http/Livewire/Application/DeploymentScript.php new file mode 100644 index 0000000..c36857b --- /dev/null +++ b/app/Http/Livewire/Application/DeploymentScript.php @@ -0,0 +1,37 @@ +script = $this->site->deploymentScript->content; + } + + public function save(): void + { + app(UpdateDeploymentScript::class)->update($this->site, $this->all()); + + session()->flash('status', 'script-updated'); + + $this->emit(Deploy::class, '$refresh'); + } + + public function render(): View + { + return view('livewire.application.deployment-script'); + } +} diff --git a/app/Http/Livewire/Application/DeploymentsList.php b/app/Http/Livewire/Application/DeploymentsList.php new file mode 100644 index 0000000..da037ae --- /dev/null +++ b/app/Http/Livewire/Application/DeploymentsList.php @@ -0,0 +1,34 @@ +site->deployments()->findOrFail($id); + $this->logContent = $deployment->log->content; + + $this->dispatchBrowserEvent('open-modal', 'show-log'); + } + + public function render(): View + { + return view('livewire.application.deployments-list', [ + 'deployments' => $this->site->deployments()->latest()->simplePaginate(10), + ]); + } +} diff --git a/app/Http/Livewire/Application/LaravelApp.php b/app/Http/Livewire/Application/LaravelApp.php new file mode 100644 index 0000000..11d44b1 --- /dev/null +++ b/app/Http/Livewire/Application/LaravelApp.php @@ -0,0 +1,20 @@ +create($this->server, $this->all()); + + $this->emitTo(CronjobsList::class, '$refresh'); + + $this->dispatchBrowserEvent('created', true); + } + + public function render(): View + { + return view('livewire.cronjobs.create-cronjob'); + } +} diff --git a/app/Http/Livewire/Cronjobs/CronjobsList.php b/app/Http/Livewire/Cronjobs/CronjobsList.php new file mode 100644 index 0000000..0d34f1e --- /dev/null +++ b/app/Http/Livewire/Cronjobs/CronjobsList.php @@ -0,0 +1,35 @@ +server->cronJobs()->where('id', $this->deleteId)->firstOrFail(); + + $cronjob->removeFromServer(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.cronjobs.cronjobs-list', [ + 'cronjobs' => $this->server->cronJobs, + ]); + } +} diff --git a/app/Http/Livewire/Databases/DatabaseList.php b/app/Http/Livewire/Databases/DatabaseList.php new file mode 100644 index 0000000..5beb528 --- /dev/null +++ b/app/Http/Livewire/Databases/DatabaseList.php @@ -0,0 +1,65 @@ +create($this->server, $this->all()); + + if ($this->all()['user']) { + app(CreateDatabaseUser::class)->create($this->server, $this->all()); + } + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('database-created', true); + } + + public function delete(): void + { + $database = Database::query()->findOrFail($this->deleteId); + + $database->deleteFromServer(); + + $this->refreshComponent([]); + + $this->emitTo(DatabaseUserList::class, '$refresh'); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.databases.database-list', [ + 'databases' => $this->server->databases, + ]); + } +} diff --git a/app/Http/Livewire/Databases/DatabaseUserList.php b/app/Http/Livewire/Databases/DatabaseUserList.php new file mode 100644 index 0000000..f35230c --- /dev/null +++ b/app/Http/Livewire/Databases/DatabaseUserList.php @@ -0,0 +1,94 @@ +create($this->server, $this->all()); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('database-user-created', true); + } + + public function delete(): void + { + $databaseUser = DatabaseUser::query()->findOrFail($this->deleteId); + + $databaseUser->deleteFromServer(); + + $this->refreshComponent([]); + + $this->emitTo(DatabaseList::class, '$refresh'); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function viewPassword(int $id): void + { + $databaseUser = DatabaseUser::query()->findOrFail($id); + + $this->viewPassword = $databaseUser->password; + + $this->dispatchBrowserEvent('open-modal', 'database-user-password'); + } + + public function showLink(int $id): void + { + $databaseUser = DatabaseUser::query()->findOrFail($id); + + $this->linkId = $id; + $this->link = $databaseUser->databases; + + $this->dispatchBrowserEvent('open-modal', 'link-database-user'); + } + + public function link(): void + { + $databaseUser = DatabaseUser::query()->findOrFail($this->linkId); + + app(LinkUser::class)->link($databaseUser, $this->link); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('linked', true); + } + + public function render(): View + { + return view('livewire.databases.database-user-list', [ + 'databases' => $this->server->databases, + 'databaseUsers' => $this->server->databaseUsers, + ]); + } +} diff --git a/app/Http/Livewire/Firewall/CreateFirewallRule.php b/app/Http/Livewire/Firewall/CreateFirewallRule.php new file mode 100644 index 0000000..cd4f235 --- /dev/null +++ b/app/Http/Livewire/Firewall/CreateFirewallRule.php @@ -0,0 +1,40 @@ +create($this->server, $this->all()); + + $this->emitTo(FirewallRulesList::class, '$refresh'); + + $this->dispatchBrowserEvent('created', true); + } + + public function render(): View + { + return view('livewire.firewall.create-firewall-rule'); + } +} diff --git a/app/Http/Livewire/Firewall/FirewallRulesList.php b/app/Http/Livewire/Firewall/FirewallRulesList.php new file mode 100644 index 0000000..080f9ba --- /dev/null +++ b/app/Http/Livewire/Firewall/FirewallRulesList.php @@ -0,0 +1,36 @@ +findOrFail($this->deleteId); + + $rule->removeFromServer(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.firewall.firewall-rules-list', [ + 'rules' => $this->server->firewallRules, + ]); + } +} diff --git a/app/Http/Livewire/NotificationChannels/AddChannel.php b/app/Http/Livewire/NotificationChannels/AddChannel.php new file mode 100644 index 0000000..8b7fe83 --- /dev/null +++ b/app/Http/Livewire/NotificationChannels/AddChannel.php @@ -0,0 +1,34 @@ +add( + auth()->user(), + $this->all() + ); + + $this->emitTo(KeysList::class, '$refresh'); + + $this->dispatchBrowserEvent('added', true); + } + + public function render(): View + { + return view('livewire.notification-channels.add-channel'); + } +} diff --git a/app/Http/Livewire/NotificationChannels/ChannelsList.php b/app/Http/Livewire/NotificationChannels/ChannelsList.php new file mode 100644 index 0000000..4c34cd7 --- /dev/null +++ b/app/Http/Livewire/NotificationChannels/ChannelsList.php @@ -0,0 +1,37 @@ +findOrFail($this->deleteId); + + $channel->delete(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.notification-channels.channels-list', [ + 'channels' => NotificationChannel::query()->latest()->get(), + ]); + } +} diff --git a/app/Http/Livewire/Php/DefaultCli.php b/app/Http/Livewire/Php/DefaultCli.php new file mode 100644 index 0000000..1a998d5 --- /dev/null +++ b/app/Http/Livewire/Php/DefaultCli.php @@ -0,0 +1,30 @@ +server->php($version)->handler()->setDefaultCli(); + + $this->refreshComponent([]); + } + + public function render(): View + { + return view('livewire.php.default-cli', [ + 'defaultPHP' => $this->server->defaultService('php'), + 'phps' => $this->server->services()->where('type', 'php')->get(), // + ]); + } +} diff --git a/app/Http/Livewire/Php/InstalledVersions.php b/app/Http/Livewire/Php/InstalledVersions.php new file mode 100644 index 0000000..52aac21 --- /dev/null +++ b/app/Http/Livewire/Php/InstalledVersions.php @@ -0,0 +1,85 @@ +install($this->server, [ + 'version' => $version, + ]); + + $this->refreshComponent([]); + } + + public function restart(int $id): void + { + $service = Service::query()->findOrFail($id); + $service->restart(); + + $this->refreshComponent([]); + } + + public function uninstall(): void + { + $service = Service::query()->findOrFail($this->uninstallId); + $service->uninstall(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function loadIni(int $id): void + { + $this->iniId = $id; + $this->ini = 'Loading php.ini'; + + $service = Service::query()->findOrFail($this->iniId); + + try { + $this->ini = $service->server->ssh()->exec(new GetPHPIniCommand($service->version)); + } catch (Throwable) { + // + } + } + + public function saveIni(): void + { + $service = Service::query()->findOrFail($this->iniId); + + app(UpdatePHPIni::class)->update($service, $this->all()['ini']); + + $this->refreshComponent([]); + + session()->flash('status', 'ini-updated'); + } + + public function render(): View + { + return view('livewire.php.installed-versions', [ + 'phps' => $this->server->services()->where('type', 'php')->get(), + ]); + } +} diff --git a/app/Http/Livewire/Profile/UpdatePassword.php b/app/Http/Livewire/Profile/UpdatePassword.php new file mode 100644 index 0000000..f6d7126 --- /dev/null +++ b/app/Http/Livewire/Profile/UpdatePassword.php @@ -0,0 +1,32 @@ +update(auth()->user(), $this->all()); + + $this->current_password = ''; + $this->password = ''; + $this->password_confirmation = ''; + + session()->flash('status', 'password-updated'); + } + + public function render(): View + { + return view('livewire.profile.update-password'); + } +} diff --git a/app/Http/Livewire/Profile/UpdateProfileInformation.php b/app/Http/Livewire/Profile/UpdateProfileInformation.php new file mode 100644 index 0000000..b6107ba --- /dev/null +++ b/app/Http/Livewire/Profile/UpdateProfileInformation.php @@ -0,0 +1,48 @@ +name = auth()->user()->name; + $this->email = auth()->user()->email; + } + + /** + * @throws Exception + */ + public function submit(): void + { + app(UpdateUserProfileInformation::class)->update(auth()->user(), $this->all()); + + session()->flash('status', 'profile-updated'); + + $this->emitTo(UserDropdown::class, '$refresh'); + } + + public function sendVerificationEmail(): void + { + if (! auth()->user()->hasVerifiedEmail()) { + auth()->user()->sendEmailVerificationNotification(); + + session()->flash('status', 'verification-link-sent'); + } + } + + public function render(): View + { + return view('livewire.profile.update-profile-information'); + } +} diff --git a/app/Http/Livewire/Queues/CreateQueue.php b/app/Http/Livewire/Queues/CreateQueue.php new file mode 100644 index 0000000..2ce35b5 --- /dev/null +++ b/app/Http/Livewire/Queues/CreateQueue.php @@ -0,0 +1,36 @@ +create($this->site, $this->all()); + + $this->emitTo(QueuesList::class, '$refresh'); + + $this->dispatchBrowserEvent('created', true); + } + + public function render(): View + { + return view('livewire.queues.create-queue'); + } +} diff --git a/app/Http/Livewire/Queues/QueuesList.php b/app/Http/Livewire/Queues/QueuesList.php new file mode 100644 index 0000000..30d90fa --- /dev/null +++ b/app/Http/Livewire/Queues/QueuesList.php @@ -0,0 +1,57 @@ +site->queues()->findOrFail($this->deleteId); + + $queue->remove(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function start(Queue $queue): void + { + $queue->start(); + + $this->refreshComponent([]); + } + + public function restart(Queue $queue): void + { + $queue->restart(); + + $this->refreshComponent([]); + } + + public function stop(Queue $queue): void + { + $queue->stop(); + + $this->refreshComponent([]); + } + + public function render(): View + { + return view('livewire.queues.queues-list', [ + 'queues' => $this->site->queues, + ]); + } +} diff --git a/app/Http/Livewire/ServerLogs/LogsList.php b/app/Http/Livewire/ServerLogs/LogsList.php new file mode 100644 index 0000000..41af618 --- /dev/null +++ b/app/Http/Livewire/ServerLogs/LogsList.php @@ -0,0 +1,58 @@ +server->logs()->findOrFail($id); + $this->logContent = $log->content; + + $this->dispatchBrowserEvent('open-modal', 'show-log'); + } + + public function render(): View + { + if ($this->site) { + return $this->renderSite(); + } + + if ($this->count) { + $logs = $this->server->logs()->latest()->take(10)->get(); + } else { + $logs = $this->server->logs()->latest()->simplePaginate(10); + } + + return view('livewire.server-logs.logs-list', compact('logs')); + } + + private function renderSite(): View + { + if ($this->count) { + $logs = $this->site->logs()->latest()->take(10)->get(); + } else { + $logs = $this->site->logs()->latest()->simplePaginate(10); + } + + return view('livewire.server-logs.logs-list', compact('logs')); + } +} diff --git a/app/Http/Livewire/ServerProviders/ConnectProvider.php b/app/Http/Livewire/ServerProviders/ConnectProvider.php new file mode 100644 index 0000000..2c87207 --- /dev/null +++ b/app/Http/Livewire/ServerProviders/ConnectProvider.php @@ -0,0 +1,40 @@ +create(auth()->user(), $this->all()); + + $this->emitTo(ProvidersList::class, '$refresh'); + + $this->dispatchBrowserEvent('connected', true); + } + + public function render(): View + { + if (request()->query('provider')) { + $this->provider = request()->query('provider'); + } + + return view('livewire.server-providers.connect-provider', [ + 'open' => ! is_null(request()->query('provider')), + ]); + } +} diff --git a/app/Http/Livewire/ServerProviders/ProvidersList.php b/app/Http/Livewire/ServerProviders/ProvidersList.php new file mode 100644 index 0000000..3d9f793 --- /dev/null +++ b/app/Http/Livewire/ServerProviders/ProvidersList.php @@ -0,0 +1,37 @@ +findOrFail($this->deleteId); + + $provider->delete(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.server-providers.providers-list', [ + 'providers' => ServerProvider::query()->latest()->get(), + ]); + } +} diff --git a/app/Http/Livewire/ServerSettings/CheckConnection.php b/app/Http/Livewire/ServerSettings/CheckConnection.php new file mode 100644 index 0000000..d95c66f --- /dev/null +++ b/app/Http/Livewire/ServerSettings/CheckConnection.php @@ -0,0 +1,24 @@ +server->checkConnection(); + + session()->flash('status', 'checking-connection'); + } + + public function render(): View + { + return view('livewire.server-settings.check-connection'); + } +} diff --git a/app/Http/Livewire/ServerSettings/EditServer.php b/app/Http/Livewire/ServerSettings/EditServer.php new file mode 100644 index 0000000..75721be --- /dev/null +++ b/app/Http/Livewire/ServerSettings/EditServer.php @@ -0,0 +1,40 @@ +name = $this->server->name; + $this->ip = $this->server->ip; + $this->port = $this->server->port; + } + + public function update(): void + { + app(\App\Actions\Server\EditServer::class)->edit($this->server, $this->all()); + + session()->flash('status', 'server-updated'); + } + + public function render(): View + { + return view('livewire.server-settings.edit-server'); + } +} diff --git a/app/Http/Livewire/ServerSettings/RebootServer.php b/app/Http/Livewire/ServerSettings/RebootServer.php new file mode 100644 index 0000000..cd908fd --- /dev/null +++ b/app/Http/Livewire/ServerSettings/RebootServer.php @@ -0,0 +1,24 @@ +server->reboot(); + + session()->flash('status', 'rebooting-server'); + } + + public function render(): View + { + return view('livewire.server-settings.reboot-server'); + } +} diff --git a/app/Http/Livewire/ServerSettings/ServerDetails.php b/app/Http/Livewire/ServerSettings/ServerDetails.php new file mode 100644 index 0000000..5991e09 --- /dev/null +++ b/app/Http/Livewire/ServerSettings/ServerDetails.php @@ -0,0 +1,20 @@ +findOrFail($this->all()['key_id']); + + $key->deployTo($this->server); + + $this->emitTo(ServerKeysList::class, '$refresh'); + + $this->dispatchBrowserEvent('added', true); + } + + public function render(): View + { + return view('livewire.server-ssh-keys.add-existing-key', [ + 'keys' => SshKey::all(), + ]); + } +} diff --git a/app/Http/Livewire/ServerSshKeys/AddNewKey.php b/app/Http/Livewire/ServerSshKeys/AddNewKey.php new file mode 100644 index 0000000..edf4496 --- /dev/null +++ b/app/Http/Livewire/ServerSshKeys/AddNewKey.php @@ -0,0 +1,36 @@ +create( + auth()->user(), + $this->all() + ); + + $key->deployTo($this->server); + + $this->emitTo(ServerKeysList::class, '$refresh'); + + $this->dispatchBrowserEvent('added', true); + } + + public function render(): View + { + return view('livewire.server-ssh-keys.add-new-key'); + } +} diff --git a/app/Http/Livewire/ServerSshKeys/ServerKeysList.php b/app/Http/Livewire/ServerSshKeys/ServerKeysList.php new file mode 100644 index 0000000..b90ece4 --- /dev/null +++ b/app/Http/Livewire/ServerSshKeys/ServerKeysList.php @@ -0,0 +1,40 @@ +findOrFail($this->deleteId); + + $key->deleteFrom($this->server); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.server-ssh-keys.server-keys-list', [ + 'keys' => $this->server->sshKeys, + ]); + } +} diff --git a/app/Http/Livewire/Servers/CreateServer.php b/app/Http/Livewire/Servers/CreateServer.php new file mode 100644 index 0000000..326d191 --- /dev/null +++ b/app/Http/Livewire/Servers/CreateServer.php @@ -0,0 +1,64 @@ +create( + auth()->user(), + $this->all() + ); + + $this->redirect(route('servers.show', ['server' => $server])); + } + + public function render(): View + { + $serverProviders = ServerProvider::query()->where('provider', $this->provider)->get(); + + return view( + 'livewire.servers.create-server', + compact([ + 'serverProviders', + ]) + ); + } +} diff --git a/app/Http/Livewire/Servers/DeleteServer.php b/app/Http/Livewire/Servers/DeleteServer.php new file mode 100644 index 0000000..7c63d23 --- /dev/null +++ b/app/Http/Livewire/Servers/DeleteServer.php @@ -0,0 +1,29 @@ +server = $server; + } + + public function delete(): void + { + $this->server->delete(); + + $this->redirect(route('servers')); + } + + public function render(): View + { + return view('livewire.servers.delete-server'); + } +} diff --git a/app/Http/Livewire/Servers/ServersList.php b/app/Http/Livewire/Servers/ServersList.php new file mode 100644 index 0000000..2d3e9d3 --- /dev/null +++ b/app/Http/Livewire/Servers/ServersList.php @@ -0,0 +1,20 @@ + Server::all(), + ]); + } +} diff --git a/app/Http/Livewire/Servers/ShowServer.php b/app/Http/Livewire/Servers/ShowServer.php new file mode 100644 index 0000000..b08d7ab --- /dev/null +++ b/app/Http/Livewire/Servers/ShowServer.php @@ -0,0 +1,31 @@ +redirect(route('servers.show', ['server' => $this->server])); + + return; + } + + $this->emit('refreshComponent'); + } + + public function render(): View + { + return view('livewire.servers.show-server'); + } +} diff --git a/app/Http/Livewire/Services/ServicesList.php b/app/Http/Livewire/Services/ServicesList.php new file mode 100644 index 0000000..fe09460 --- /dev/null +++ b/app/Http/Livewire/Services/ServicesList.php @@ -0,0 +1,49 @@ +server->services()->where('id', $id)->firstOrFail(); + + $service->stop(); + + $this->refreshComponent([]); + } + + public function start(int $id): void + { + $service = $this->server->services()->where('id', $id)->firstOrFail(); + + $service->start(); + + $this->refreshComponent([]); + } + + public function restart(int $id): void + { + $service = $this->server->services()->where('id', $id)->firstOrFail(); + + $service->restart(); + + $this->refreshComponent([]); + } + + public function render(): View + { + return view('livewire.services.services-list', [ + 'services' => $this->server->services, + ]); + } +} diff --git a/app/Http/Livewire/Sites/ChangePhpVersion.php b/app/Http/Livewire/Sites/ChangePhpVersion.php new file mode 100644 index 0000000..07ef34e --- /dev/null +++ b/app/Http/Livewire/Sites/ChangePhpVersion.php @@ -0,0 +1,41 @@ +version = $site->php_version; + } + + public function change(): void + { + $this->site->changePHPVersion($this->version); + + session()->flash('status', 'changing-php-version'); + } + + public function refreshComponent(array $data): void + { + if (isset($data['type'])) { + session()->flash('status', $data['type']); + } + } + + public function render(): View + { + return view('livewire.sites.change-php-version'); + } +} diff --git a/app/Http/Livewire/Sites/CreateSite.php b/app/Http/Livewire/Sites/CreateSite.php new file mode 100644 index 0000000..19a7c05 --- /dev/null +++ b/app/Http/Livewire/Sites/CreateSite.php @@ -0,0 +1,59 @@ +create( + $this->server, + $this->all() + ); + + $this->redirect(route('servers.sites.show', [ + 'server' => $site->server, + 'site' => $site, + ])); + } + + public function render(): View + { + return view('livewire.sites.create-site', [ + 'sourceControls' => SourceControl::all(), + ]); + } +} diff --git a/app/Http/Livewire/Sites/DeleteSite.php b/app/Http/Livewire/Sites/DeleteSite.php new file mode 100644 index 0000000..4ad1056 --- /dev/null +++ b/app/Http/Livewire/Sites/DeleteSite.php @@ -0,0 +1,27 @@ +site->remove(); + + $this->redirect(route('servers.sites', ['server' => $this->site->server])); + } + + public function render(): View + { + return view('livewire.sites.delete-site'); + } +} diff --git a/app/Http/Livewire/Sites/ShowSite.php b/app/Http/Livewire/Sites/ShowSite.php new file mode 100644 index 0000000..f3a2724 --- /dev/null +++ b/app/Http/Livewire/Sites/ShowSite.php @@ -0,0 +1,20 @@ +redirect( + route('servers.sites.show', [ + 'server' => $this->server, + 'site' => $data['data']['site']['id'], + ]) + ); + + return; + } + + $this->emit('refreshComponent'); + } + + public function render(): View + { + return view('livewire.sites.sites-list', [ + 'sites' => $this->server->sites()->latest()->get(), + ]); + } +} diff --git a/app/Http/Livewire/SourceControls/Bitbucket.php b/app/Http/Livewire/SourceControls/Bitbucket.php new file mode 100644 index 0000000..a635494 --- /dev/null +++ b/app/Http/Livewire/SourceControls/Bitbucket.php @@ -0,0 +1,36 @@ +token = SourceControl::query() + ->where('provider', \App\Enums\SourceControl::BITBUCKET) + ->first()?->access_token ?? ''; + } + + public function connect(): void + { + app(ConnectSourceControl::class)->connect(\App\Enums\SourceControl::BITBUCKET, $this->all()); + + session()->flash('status', 'bitbucket-updated'); + } + + public function render(): View + { + return view('livewire.source-controls.bitbucket', [ + 'sourceControl' => SourceControl::query() + ->where('provider', \App\Enums\SourceControl::BITBUCKET) + ->first(), + ]); + } +} diff --git a/app/Http/Livewire/SourceControls/Github.php b/app/Http/Livewire/SourceControls/Github.php new file mode 100644 index 0000000..6e8949d --- /dev/null +++ b/app/Http/Livewire/SourceControls/Github.php @@ -0,0 +1,36 @@ +token = SourceControl::query() + ->where('provider', \App\Enums\SourceControl::GITHUB) + ->first()?->access_token ?? ''; + } + + public function connect(): void + { + app(ConnectSourceControl::class)->connect(\App\Enums\SourceControl::GITHUB, $this->all()); + + session()->flash('status', 'github-updated'); + } + + public function render(): View + { + return view('livewire.source-controls.github', [ + 'sourceControl' => SourceControl::query() + ->where('provider', \App\Enums\SourceControl::GITHUB) + ->first(), + ]); + } +} diff --git a/app/Http/Livewire/SourceControls/Gitlab.php b/app/Http/Livewire/SourceControls/Gitlab.php new file mode 100644 index 0000000..6a90b72 --- /dev/null +++ b/app/Http/Livewire/SourceControls/Gitlab.php @@ -0,0 +1,36 @@ +token = SourceControl::query() + ->where('provider', \App\Enums\SourceControl::GITLAB) + ->first()?->access_token ?? ''; + } + + public function connect(): void + { + app(ConnectSourceControl::class)->connect(\App\Enums\SourceControl::GITLAB, $this->all()); + + session()->flash('status', 'gitlab-updated'); + } + + public function render(): View + { + return view('livewire.source-controls.gitlab', [ + 'sourceControl' => SourceControl::query() + ->where('provider', \App\Enums\SourceControl::GITLAB) + ->first(), + ]); + } +} diff --git a/app/Http/Livewire/SshKeys/AddKey.php b/app/Http/Livewire/SshKeys/AddKey.php new file mode 100644 index 0000000..d8c0615 --- /dev/null +++ b/app/Http/Livewire/SshKeys/AddKey.php @@ -0,0 +1,31 @@ +create( + auth()->user(), + $this->all() + ); + + $this->emitTo(KeysList::class, '$refresh'); + + $this->dispatchBrowserEvent('added', true); + } + + public function render(): View + { + return view('livewire.ssh-keys.add-key'); + } +} diff --git a/app/Http/Livewire/SshKeys/KeysList.php b/app/Http/Livewire/SshKeys/KeysList.php new file mode 100644 index 0000000..4b53741 --- /dev/null +++ b/app/Http/Livewire/SshKeys/KeysList.php @@ -0,0 +1,37 @@ +findOrFail($this->deleteId); + + $key->delete(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function render(): View + { + return view('livewire.ssh-keys.keys-list', [ + 'keys' => SshKey::query()->latest()->get(), + ]); + } +} diff --git a/app/Http/Livewire/Ssl/CreateSsl.php b/app/Http/Livewire/Ssl/CreateSsl.php new file mode 100644 index 0000000..604443b --- /dev/null +++ b/app/Http/Livewire/Ssl/CreateSsl.php @@ -0,0 +1,35 @@ +create($this->site, $this->all()); + + $this->emitTo(SslsList::class, '$refresh'); + + $this->dispatchBrowserEvent('created', true); + } + + public function render(): View + { + return view('livewire.ssl.create-ssl'); + } +} diff --git a/app/Http/Livewire/Ssl/SslsList.php b/app/Http/Livewire/Ssl/SslsList.php new file mode 100644 index 0000000..bc05180 --- /dev/null +++ b/app/Http/Livewire/Ssl/SslsList.php @@ -0,0 +1,46 @@ +site->ssls()->where('id', $this->deleteId)->firstOrFail(); + + $ssl->remove(); + + $this->refreshComponent([]); + + $this->dispatchBrowserEvent('confirmed', true); + } + + public function refreshComponent(array $data): void + { + if (isset($data['type']) && $data['type'] == 'deploy-ssl-failed') { + $this->toast()->error(__('SSL creation failed!')); + } + + $this->emit('refreshComponent'); + } + + public function render(): View + { + return view('livewire.ssl.ssls-list', [ + 'ssls' => $this->site->ssls, + ]); + } +} diff --git a/app/Http/Livewire/UserDropdown.php b/app/Http/Livewire/UserDropdown.php new file mode 100644 index 0000000..69db7c3 --- /dev/null +++ b/app/Http/Livewire/UserDropdown.php @@ -0,0 +1,18 @@ +expectsJson() ? null : route('login'); + } +} diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php new file mode 100644 index 0000000..867695b --- /dev/null +++ b/app/Http/Middleware/EncryptCookies.php @@ -0,0 +1,17 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Middleware/PreventRequestsDuringMaintenance.php b/app/Http/Middleware/PreventRequestsDuringMaintenance.php new file mode 100644 index 0000000..74cbd9a --- /dev/null +++ b/app/Http/Middleware/PreventRequestsDuringMaintenance.php @@ -0,0 +1,17 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php new file mode 100644 index 0000000..afc78c4 --- /dev/null +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -0,0 +1,30 @@ +check()) { + return redirect(RouteServiceProvider::HOME); + } + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php new file mode 100644 index 0000000..88cadca --- /dev/null +++ b/app/Http/Middleware/TrimStrings.php @@ -0,0 +1,19 @@ + + */ + protected $except = [ + 'current_password', + 'password', + 'password_confirmation', + ]; +} diff --git a/app/Http/Middleware/TrustHosts.php b/app/Http/Middleware/TrustHosts.php new file mode 100644 index 0000000..c9c58bd --- /dev/null +++ b/app/Http/Middleware/TrustHosts.php @@ -0,0 +1,20 @@ + + */ + public function hosts(): array + { + return [ + $this->allSubdomainsOfApplicationUrl(), + ]; + } +} diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php new file mode 100644 index 0000000..3391630 --- /dev/null +++ b/app/Http/Middleware/TrustProxies.php @@ -0,0 +1,28 @@ +|string|null + */ + protected $proxies; + + /** + * The headers that should be used to detect proxies. + * + * @var int + */ + protected $headers = + Request::HEADER_X_FORWARDED_FOR | + Request::HEADER_X_FORWARDED_HOST | + Request::HEADER_X_FORWARDED_PORT | + Request::HEADER_X_FORWARDED_PROTO | + Request::HEADER_X_FORWARDED_AWS_ELB; +} diff --git a/app/Http/Middleware/ValidateSignature.php b/app/Http/Middleware/ValidateSignature.php new file mode 100644 index 0000000..093bf64 --- /dev/null +++ b/app/Http/Middleware/ValidateSignature.php @@ -0,0 +1,22 @@ + + */ + protected $except = [ + // 'fbclid', + // 'utm_campaign', + // 'utm_content', + // 'utm_medium', + // 'utm_source', + // 'utm_term', + ]; +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php new file mode 100644 index 0000000..9e86521 --- /dev/null +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -0,0 +1,17 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Requests/Auth/LoginRequest.php b/app/Http/Requests/Auth/LoginRequest.php new file mode 100644 index 0000000..7a19bc0 --- /dev/null +++ b/app/Http/Requests/Auth/LoginRequest.php @@ -0,0 +1,85 @@ + + */ + public function rules(): array + { + return [ + 'email' => ['required', 'string', 'email'], + 'password' => ['required', 'string'], + ]; + } + + /** + * Attempt to authenticate the request's credentials. + * + * @throws \Illuminate\Validation\ValidationException + */ + public function authenticate(): void + { + $this->ensureIsNotRateLimited(); + + if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) { + RateLimiter::hit($this->throttleKey()); + + throw ValidationException::withMessages([ + 'email' => trans('auth.failed'), + ]); + } + + RateLimiter::clear($this->throttleKey()); + } + + /** + * Ensure the login request is not rate limited. + * + * @throws \Illuminate\Validation\ValidationException + */ + public function ensureIsNotRateLimited(): void + { + if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { + return; + } + + event(new Lockout($this)); + + $seconds = RateLimiter::availableIn($this->throttleKey()); + + throw ValidationException::withMessages([ + 'email' => trans('auth.throttle', [ + 'seconds' => $seconds, + 'minutes' => ceil($seconds / 60), + ]), + ]); + } + + /** + * Get the rate limiting throttle key for the request. + */ + public function throttleKey(): string + { + return Str::transliterate(Str::lower($this->input('email')).'|'.$this->ip()); + } +} diff --git a/app/Http/Requests/ProfileUpdateRequest.php b/app/Http/Requests/ProfileUpdateRequest.php new file mode 100644 index 0000000..327ce6f --- /dev/null +++ b/app/Http/Requests/ProfileUpdateRequest.php @@ -0,0 +1,23 @@ + + */ + public function rules(): array + { + return [ + 'name' => ['string', 'max:255'], + 'email' => ['email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)], + ]; + } +} diff --git a/app/Jobs/Backup/RestoreDatabase.php b/app/Jobs/Backup/RestoreDatabase.php new file mode 100644 index 0000000..bc3144e --- /dev/null +++ b/app/Jobs/Backup/RestoreDatabase.php @@ -0,0 +1,47 @@ +backupFile = $backupFile; + $this->database = $database; + } + + public function handle(): void + { + $this->database->server->database()->handler()->restoreBackup($this->backupFile, $this->database->name); + + $this->backupFile->status = 'restored'; + $this->backupFile->restored_at = now(); + $this->backupFile->save(); + + event( + new Broadcast('backup-restore-finished', [ + 'file' => $this->backupFile, + ]) + ); + } + + public function failed(): void + { + $this->backupFile->status = 'restore_failed'; + $this->backupFile->save(); + event( + new Broadcast('backup-restore-failed', [ + 'file' => $this->backupFile, + ]) + ); + } +} diff --git a/app/Jobs/Backup/RunBackup.php b/app/Jobs/Backup/RunBackup.php new file mode 100644 index 0000000..f45bb93 --- /dev/null +++ b/app/Jobs/Backup/RunBackup.php @@ -0,0 +1,44 @@ +backupFile = $backupFile; + } + + public function handle(): void + { + if ($this->backupFile->backup->type === 'database') { + $this->backupFile->backup->server->database()->handler()->runBackup($this->backupFile); + } + + $this->backupFile->status = 'finished'; + $this->backupFile->save(); + + event( + new Broadcast('run-backup-finished', [ + 'file' => $this->backupFile, + ]) + ); + } + + public function failed(): void + { + $this->backupFile->status = 'failed'; + $this->backupFile->save(); + event( + new Broadcast('run-backup-failed', [ + 'file' => $this->backupFile, + ]) + ); + } +} diff --git a/app/Jobs/CronJob/AddToServer.php b/app/Jobs/CronJob/AddToServer.php new file mode 100644 index 0000000..b2a5326 --- /dev/null +++ b/app/Jobs/CronJob/AddToServer.php @@ -0,0 +1,48 @@ +cronJob = $cronJob; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->cronJob->server->ssh()->exec( + new UpdateCronJobsCommand($this->cronJob->user, $this->cronJob->crontab), + 'update-crontab' + ); + $this->cronJob->status = CronjobStatus::READY; + $this->cronJob->save(); + event( + new Broadcast('add-cronjob-finished', [ + 'cronJob' => $this->cronJob, + ]) + ); + } + + public function failed(): void + { + $this->cronJob->delete(); + event( + new Broadcast('add-cronjob-failed', [ + 'cronJob' => $this->cronJob, + ]) + ); + } +} diff --git a/app/Jobs/CronJob/RemoveFromServer.php b/app/Jobs/CronJob/RemoveFromServer.php new file mode 100644 index 0000000..88d1fa0 --- /dev/null +++ b/app/Jobs/CronJob/RemoveFromServer.php @@ -0,0 +1,46 @@ +cronJob = $cronJob; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->cronJob->server->ssh()->exec( + new UpdateCronJobsCommand($this->cronJob->user, $this->cronJob->crontab), + 'update-crontab' + ); + $this->cronJob->delete(); + event( + new Broadcast('remove-cronjob-finished', [ + 'id' => $this->cronJob->id, + ]) + ); + } + + public function failed(): void + { + $this->cronJob->save(); + event( + new Broadcast('remove-cronjob-failed', [ + 'cronJob' => $this->cronJob, + ]) + ); + } +} diff --git a/app/Jobs/Database/CreateOnServer.php b/app/Jobs/Database/CreateOnServer.php new file mode 100644 index 0000000..eee40a2 --- /dev/null +++ b/app/Jobs/Database/CreateOnServer.php @@ -0,0 +1,35 @@ +database = $database; + } + + public function handle(): void + { + $this->database->server->database()->handler()->create($this->database->name); + $this->database->status = DatabaseStatus::READY; + $this->database->save(); + event(new Broadcast('create-database-finished', [ + 'id' => $this->database->id, + ])); + } + + public function failed(): void + { + event(new Broadcast('create-database-failed', [ + 'id' => $this->database->id, + ])); + } +} diff --git a/app/Jobs/Database/DeleteFromServer.php b/app/Jobs/Database/DeleteFromServer.php new file mode 100644 index 0000000..57e432e --- /dev/null +++ b/app/Jobs/Database/DeleteFromServer.php @@ -0,0 +1,37 @@ +database = $database; + } + + public function handle(): void + { + $this->database->server->database()->handler()->delete($this->database->name); + event( + new Broadcast('delete-database-finished', [ + 'id' => $this->database->id, + ]) + ); + $this->database->delete(); + } + + public function failed(): void + { + event( + new Broadcast('delete-database-failed', [ + 'id' => $this->database->id, + ]) + ); + } +} diff --git a/app/Jobs/DatabaseUser/CreateOnServer.php b/app/Jobs/DatabaseUser/CreateOnServer.php new file mode 100644 index 0000000..0c2e669 --- /dev/null +++ b/app/Jobs/DatabaseUser/CreateOnServer.php @@ -0,0 +1,43 @@ +databaseUser = $databaseUser; + } + + public function handle(): void + { + $this->databaseUser->server->database()->handler()->createUser( + $this->databaseUser->username, + $this->databaseUser->password, + $this->databaseUser->host + ); + $this->databaseUser->status = DatabaseUserStatus::READY; + $this->databaseUser->save(); + event( + new Broadcast('create-database-user-finished', [ + 'id' => $this->databaseUser->id, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('create-database-user-failed', [ + 'id' => $this->databaseUser->id, + ]) + ); + } +} diff --git a/app/Jobs/DatabaseUser/DeleteFromServer.php b/app/Jobs/DatabaseUser/DeleteFromServer.php new file mode 100644 index 0000000..65e58cb --- /dev/null +++ b/app/Jobs/DatabaseUser/DeleteFromServer.php @@ -0,0 +1,40 @@ +databaseUser = $databaseUser; + } + + public function handle(): void + { + $this->databaseUser->server->database()->handler()->deleteUser( + $this->databaseUser->username, + $this->databaseUser->host + ); + event( + new Broadcast('delete-database-user-finished', [ + 'id' => $this->databaseUser->id, + ]) + ); + $this->databaseUser->delete(); + } + + public function failed(): void + { + event( + new Broadcast('delete-database-user-failed', [ + 'id' => $this->databaseUser->id, + ]) + ); + } +} diff --git a/app/Jobs/DatabaseUser/LinkUser.php b/app/Jobs/DatabaseUser/LinkUser.php new file mode 100644 index 0000000..dfd6add --- /dev/null +++ b/app/Jobs/DatabaseUser/LinkUser.php @@ -0,0 +1,40 @@ +databaseUser = $databaseUser; + } + + public function handle(): void + { + $this->databaseUser->server->database()->handler()->link( + $this->databaseUser->username, + $this->databaseUser->host, + $this->databaseUser->databases + ); + event( + new Broadcast('link-database-user-finished', [ + 'id' => $this->databaseUser->id, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('link-database-user-failed', [ + 'id' => $this->databaseUser->id, + ]) + ); + } +} diff --git a/app/Jobs/DatabaseUser/UnlinkUser.php b/app/Jobs/DatabaseUser/UnlinkUser.php new file mode 100644 index 0000000..8ca8ffb --- /dev/null +++ b/app/Jobs/DatabaseUser/UnlinkUser.php @@ -0,0 +1,39 @@ +databaseUser = $databaseUser; + } + + public function handle(): void + { + $this->databaseUser->server->database()->handler()->unlink( + $this->databaseUser->username, + $this->databaseUser->host, + ); + event( + new Broadcast('unlink-database-user-finished', [ + 'id' => $this->databaseUser->id, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('unlink-database-user-failed', [ + 'id' => $this->databaseUser->id, + ]) + ); + } +} diff --git a/app/Jobs/Firewall/AddToServer.php b/app/Jobs/Firewall/AddToServer.php new file mode 100644 index 0000000..912a93b --- /dev/null +++ b/app/Jobs/Firewall/AddToServer.php @@ -0,0 +1,48 @@ +firewallRule = $firewallRule; + } + + public function handle(): void + { + $this->firewallRule->server->firewall() + ->handler() + ->addRule( + $this->firewallRule->type, + $this->firewallRule->real_protocol, + $this->firewallRule->port, + $this->firewallRule->source, + $this->firewallRule->mask + ); + $this->firewallRule->status = FirewallRuleStatus::READY; + $this->firewallRule->save(); + event( + new Broadcast('create-firewall-rule-finished', [ + 'firewallRule' => $this->firewallRule, + ]) + ); + } + + public function failed(): void + { + $this->firewallRule->delete(); + event( + new Broadcast('create-firewall-rule-failed', [ + 'firewallRule' => $this->firewallRule, + ]) + ); + } +} diff --git a/app/Jobs/Firewall/RemoveFromServer.php b/app/Jobs/Firewall/RemoveFromServer.php new file mode 100644 index 0000000..fc3644f --- /dev/null +++ b/app/Jobs/Firewall/RemoveFromServer.php @@ -0,0 +1,48 @@ +firewallRule = $firewallRule; + } + + public function handle(): void + { + $this->firewallRule->server->firewall() + ->handler() + ->removeRule( + $this->firewallRule->type, + $this->firewallRule->real_protocol, + $this->firewallRule->port, + $this->firewallRule->source, + $this->firewallRule->mask + ); + $this->firewallRule->delete(); + event( + new Broadcast('delete-firewall-rule-finished', [ + 'id' => $this->firewallRule->id, + ]) + ); + } + + public function failed(): void + { + $this->firewallRule->status = FirewallRuleStatus::READY; + $this->firewallRule->save(); + event( + new Broadcast('delete-firewall-rule-failed', [ + 'firewallRule' => $this->firewallRule, + ]) + ); + } +} diff --git a/app/Jobs/Installation/ContinueInstallation.php b/app/Jobs/Installation/ContinueInstallation.php new file mode 100644 index 0000000..9e8f2ad --- /dev/null +++ b/app/Jobs/Installation/ContinueInstallation.php @@ -0,0 +1,34 @@ +server = $server; + $this->attempts = 2; + } + + public function handle(): void + { + if ($this->server->provider()->isRunning()) { + $this->server->install(); + } else { + $this->attempts--; + if ($this->attempts > 0) { + sleep(120); + $this->handle(); + } else { + event(new Broadcast('install-server-failed', $this->server->toArray())); + } + } + } +} diff --git a/app/Jobs/Installation/Initialize.php b/app/Jobs/Installation/Initialize.php new file mode 100755 index 0000000..f427c30 --- /dev/null +++ b/app/Jobs/Installation/Initialize.php @@ -0,0 +1,75 @@ +server = $server->refresh(); + $this->asUser = $asUser; + $this->defaultKeys = $defaultKeys; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->authentication(); + $this->publicKey(); + // $this->setHostname(); + } + + /** + * @throws Throwable + */ + protected function authentication(): void + { + $this->server + ->ssh($this->asUser ?? $this->server->ssh_user, $this->defaultKeys) + ->exec( + new CreateUserCommand( + $this->server->authentication['user'], + $this->server->authentication['pass'], + $this->server->sshKey()['public_key'] + ), + 'create-user' + ); + + $this->server->ssh_user = config('core.ssh_user'); + $this->server->save(); + } + + /** + * @throws Throwable + */ + protected function publicKey(): void + { + $publicKey = $this->server->ssh()->exec(new GetPublicKeyCommand()); + $this->server->update([ + 'public_key' => $publicKey, + ]); + } + + /** + * @throws Throwable + */ + protected function setHostname(): void + { + $this->server + ->ssh() + ->exec('sudo hostnamectl set-hostname '.$this->server->hostname); + } +} diff --git a/app/Jobs/Installation/InstallCertbot.php b/app/Jobs/Installation/InstallCertbot.php new file mode 100755 index 0000000..c4c647e --- /dev/null +++ b/app/Jobs/Installation/InstallCertbot.php @@ -0,0 +1,25 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec(new InstallCertbotCommand(), 'install-certbot'); + } +} diff --git a/app/Jobs/Installation/InstallComposer.php b/app/Jobs/Installation/InstallComposer.php new file mode 100755 index 0000000..cb15851 --- /dev/null +++ b/app/Jobs/Installation/InstallComposer.php @@ -0,0 +1,25 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec(new InstallComposerCommand(), 'install-composer'); + } +} diff --git a/app/Jobs/Installation/InstallMariadb.php b/app/Jobs/Installation/InstallMariadb.php new file mode 100755 index 0000000..219f576 --- /dev/null +++ b/app/Jobs/Installation/InstallMariadb.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallMariadbCommand(), 'install-mariadb'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'mariadb-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallMysql.php b/app/Jobs/Installation/InstallMysql.php new file mode 100755 index 0000000..586b28e --- /dev/null +++ b/app/Jobs/Installation/InstallMysql.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallMysqlCommand($this->service->version), 'install-mysql'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'mysql-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallNginx.php b/app/Jobs/Installation/InstallNginx.php new file mode 100755 index 0000000..0d3244c --- /dev/null +++ b/app/Jobs/Installation/InstallNginx.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallNginxCommand(), 'install-nginx'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'nginx-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallNodejs.php b/app/Jobs/Installation/InstallNodejs.php new file mode 100755 index 0000000..9d65895 --- /dev/null +++ b/app/Jobs/Installation/InstallNodejs.php @@ -0,0 +1,25 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec(new InstallNodejsCommand(), 'install-nodejs'); + } +} diff --git a/app/Jobs/Installation/InstallPHP.php b/app/Jobs/Installation/InstallPHP.php new file mode 100755 index 0000000..1702858 --- /dev/null +++ b/app/Jobs/Installation/InstallPHP.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallPHPCommand($this->service->version), 'install-php'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'php-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallPHPMyAdmin.php b/app/Jobs/Installation/InstallPHPMyAdmin.php new file mode 100644 index 0000000..9f759d7 --- /dev/null +++ b/app/Jobs/Installation/InstallPHPMyAdmin.php @@ -0,0 +1,103 @@ +service = $service; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->setUpFirewall(); + $this->downloadSource(); + $this->setUpVHost(); + $this->restartPHP(); + } + + /** + * @throws Throwable + */ + private function setUpFirewall(): void + { + $this->firewallRule = FirewallRule::query() + ->where('server_id', $this->service->server_id) + ->where('port', '54331') + ->first(); + if ($this->firewallRule) { + $this->firewallRule->source = $this->service->type_data['allowed_ip']; + $this->firewallRule->save(); + } else { + $this->firewallRule = app(CreateRule::class)->create( + $this->service->server, + [ + 'type' => 'allow', + 'protocol' => 'tcp', + 'port' => '54331', + 'source' => $this->service->type_data['allowed_ip'], + 'mask' => '0', + ] + ); + } + } + + /** + * @throws Throwable + */ + private function downloadSource(): void + { + $this->service->server->ssh()->exec( + new DownloadPHPMyAdminCommand(), + 'download-phpmyadmin' + ); + } + + /** + * @throws Throwable + */ + private function setUpVHost(): void + { + $vhost = File::get(base_path('system/command-templates/nginx/phpmyadmin-vhost.conf')); + $vhost = Str::replace('__php_version__', $this->service->server->defaultService('php')->version, $vhost); + $this->service->server->ssh()->exec( + new CreateNginxPHPMyAdminVHostCommand($vhost), + 'create-phpmyadmin-vhost' + ); + } + + private function restartPHP(): void + { + $this->service->server->service( + 'php', + $this->service->type_data['php'] + )?->restart(); + } + + /** + * @throws Throwable + */ + public function failed(Throwable $throwable): Throwable + { + $this->firewallRule?->removeFromServer(); + throw $throwable; + } +} diff --git a/app/Jobs/Installation/InstallRedis.php b/app/Jobs/Installation/InstallRedis.php new file mode 100755 index 0000000..ccec2e7 --- /dev/null +++ b/app/Jobs/Installation/InstallRedis.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallRedisCommand(), 'install-redis'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'redis-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallRequirements.php b/app/Jobs/Installation/InstallRequirements.php new file mode 100755 index 0000000..bb8f782 --- /dev/null +++ b/app/Jobs/Installation/InstallRequirements.php @@ -0,0 +1,28 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec(new InstallRequirementsCommand( + $this->server->creator->email, + $this->server->creator->name, + ), 'install-requirements'); + } +} diff --git a/app/Jobs/Installation/InstallSupervisor.php b/app/Jobs/Installation/InstallSupervisor.php new file mode 100755 index 0000000..694d2e2 --- /dev/null +++ b/app/Jobs/Installation/InstallSupervisor.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallSupervisorCommand(), 'install-supervisor'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'supervisor-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallUfw.php b/app/Jobs/Installation/InstallUfw.php new file mode 100755 index 0000000..3ec1309 --- /dev/null +++ b/app/Jobs/Installation/InstallUfw.php @@ -0,0 +1,35 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new InstallUfwCommand(), 'install-ufw'); + $status = $ssh->exec(new ServiceStatusCommand($this->service->unit), 'ufw-status'); + $this->service->validateInstall($status); + $this->service->update([ + 'status' => ServiceStatus::READY, + ]); + } +} diff --git a/app/Jobs/Installation/InstallationJob.php b/app/Jobs/Installation/InstallationJob.php new file mode 100755 index 0000000..b31bcf5 --- /dev/null +++ b/app/Jobs/Installation/InstallationJob.php @@ -0,0 +1,17 @@ +service = $service; + } + + /** + * @throws InstallationFailed + * @throws Throwable + */ + public function handle(): void + { + $ssh = $this->service->server->ssh(); + $ssh->exec(new UninstallPHPCommand($this->service->version), 'uninstall-php'); + } +} diff --git a/app/Jobs/Installation/UninstallPHPMyAdmin.php b/app/Jobs/Installation/UninstallPHPMyAdmin.php new file mode 100644 index 0000000..c750f3c --- /dev/null +++ b/app/Jobs/Installation/UninstallPHPMyAdmin.php @@ -0,0 +1,63 @@ +service = $service; + } + + /** + * @throws Exception + * @throws Throwable + */ + public function handle(): void + { + $this->removeFirewallRule(); + $this->deleteVHost(); + $this->restartPHP(); + } + + /** + * @throws Exception + */ + private function removeFirewallRule(): void + { + /** @var ?FirewallRule $rule */ + $rule = FirewallRule::query() + ->where('server_id', $this->service->server_id) + ->where('port', '54331') + ->first(); + $rule?->removeFromServer(); + } + + /** + * @throws Throwable + */ + private function deleteVHost(): void + { + $this->service->server->ssh()->exec( + new DeleteNginxPHPMyAdminVHost('/home/vito/phpmyadmin'), + 'delete-phpmyadmin-vhost' + ); + } + + private function restartPHP(): void + { + $this->service->server->service( + 'php', + $this->service->type_data['php'] + )?->restart(); + } +} diff --git a/app/Jobs/Installation/Upgrade.php b/app/Jobs/Installation/Upgrade.php new file mode 100755 index 0000000..5d9cc51 --- /dev/null +++ b/app/Jobs/Installation/Upgrade.php @@ -0,0 +1,25 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec(new UpgradeCommand(), 'upgrade'); + } +} diff --git a/app/Jobs/Job.php b/app/Jobs/Job.php new file mode 100755 index 0000000..aaa4938 --- /dev/null +++ b/app/Jobs/Job.php @@ -0,0 +1,15 @@ +service = $service; + $this->name = $name; + } + + /** + * @throws ProcessFailed + * @throws Throwable + */ + public function handle(): void + { + $result = $this->service->server->ssh()->exec( + new InstallPHPExtensionCommand($this->service->version, $this->name), + 'install-php-extension' + ); + $result = Str::substr($result, strpos($result, '[PHP Modules]')); + if (! Str::contains($result, $this->name)) { + throw new ProcessFailed('Extension failed'); + } + $typeData = $this->service->type_data; + $typeData['extensions'][] = $this->name; + $this->service->type_data = $typeData; + $this->service->save(); + event( + new Broadcast('install-php-extension-finished', [ + 'service' => $this->service, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('install-php-extension-failed', [ + 'service' => $this->service, + ]) + ); + } +} diff --git a/app/Jobs/PHP/SetDefaultCli.php b/app/Jobs/PHP/SetDefaultCli.php new file mode 100644 index 0000000..5dae951 --- /dev/null +++ b/app/Jobs/PHP/SetDefaultCli.php @@ -0,0 +1,46 @@ +service = $service; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->service->server->ssh()->exec( + new ChangeDefaultPHPCommand($this->service->version), + 'change-default-php' + ); + $this->service->server->defaultService('php')->update(['is_default' => 0]); + $this->service->update(['is_default' => 1]); + $this->service->update(['status' => ServiceStatus::READY]); + event( + new Broadcast('set-default-cli-finished', [ + 'defaultPHP' => $this->service->server->defaultService('php'), + ]) + ); + } + + public function failed(): void + { + event(new Broadcast('set-default-cli-failed', [ + 'defaultPHP' => $this->service->server->defaultService('php'), + ])); + } +} diff --git a/app/Jobs/PHP/UpdatePHPSettings.php b/app/Jobs/PHP/UpdatePHPSettings.php new file mode 100755 index 0000000..44fe4af --- /dev/null +++ b/app/Jobs/PHP/UpdatePHPSettings.php @@ -0,0 +1,58 @@ +service = $service; + $this->settings = $settings; + } + + /** + * Execute the job. + * + * @throws Throwable + */ + public function handle(): void + { + $commands = []; + foreach ($this->settings as $key => $value) { + $commands[] = new UpdatePHPSettingsCommand( + $this->service->version, + $key, + $value.' '.config('core.php_settings_unit')[$key] + ); + } + $this->service->server->ssh()->exec($commands, 'update-php-settings'); + $typeData = $this->service->type_data; + $typeData['settings'] = $this->settings; + $this->service->type_data = $typeData; + $this->service->save(); + event( + new Broadcast('update-php-settings-finished', [ + 'service' => $this->service, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('update-php-settings-failed', [ + 'service' => $this->service, + ]) + ); + } +} diff --git a/app/Jobs/Queue/Deploy.php b/app/Jobs/Queue/Deploy.php new file mode 100644 index 0000000..93cc46f --- /dev/null +++ b/app/Jobs/Queue/Deploy.php @@ -0,0 +1,49 @@ +worker = $worker; + } + + public function handle(): void + { + $this->worker->server->processManager()->handler()->create( + $this->worker->id, + $this->worker->command, + $this->worker->user, + $this->worker->auto_start, + $this->worker->auto_restart, + $this->worker->numprocs, + $this->worker->log_file, + $this->worker->site_id + ); + $this->worker->status = QueueStatus::RUNNING; + $this->worker->save(); + event( + new Broadcast('deploy-queue-finished', [ + 'queue' => $this->worker, + ]) + ); + } + + public function failed(): void + { + $this->worker->delete(); + event( + new Broadcast('deploy-queue-failed', [ + 'queue' => $this->worker, + ]) + ); + } +} diff --git a/app/Jobs/Queue/GetLogs.php b/app/Jobs/Queue/GetLogs.php new file mode 100644 index 0000000..6fe00cc --- /dev/null +++ b/app/Jobs/Queue/GetLogs.php @@ -0,0 +1,37 @@ +worker = $worker; + } + + public function handle(): void + { + $logs = $this->worker->server->processManager()->handler()->getLogs($this->worker->log_file); + event( + new Broadcast('get-logs-finished', [ + 'id' => $this->worker->id, + 'logs' => $logs, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('get-logs-failed', [ + 'message' => __('Failed to download the logs!'), + ]) + ); + } +} diff --git a/app/Jobs/Queue/Manage.php b/app/Jobs/Queue/Manage.php new file mode 100644 index 0000000..8fa1b7c --- /dev/null +++ b/app/Jobs/Queue/Manage.php @@ -0,0 +1,68 @@ +worker = $worker; + $this->action = $action; + $this->successStatus = $successStatus; + $this->failStatus = $failStatus; + $this->failMessage = $failMessage; + } + + public function handle(): void + { + switch ($this->action) { + case 'start': + $this->worker->server->processManager()->handler()->start($this->worker->id, $this->worker->site_id); + break; + case 'stop': + $this->worker->server->processManager()->handler()->stop($this->worker->id, $this->worker->site_id); + break; + case 'restart': + $this->worker->server->processManager()->handler()->restart($this->worker->id, $this->worker->site_id); + break; + } + $this->worker->status = $this->successStatus; + $this->worker->save(); + event( + new Broadcast('manage-queue-finished', [ + 'queue' => $this->worker, + ]) + ); + } + + public function failed(): void + { + $this->worker->status = $this->failStatus; + $this->worker->save(); + event( + new Broadcast('manage-queue-failed', [ + 'message' => $this->failMessage, + 'queue' => $this->worker, + ]) + ); + } +} diff --git a/app/Jobs/Queue/Remove.php b/app/Jobs/Queue/Remove.php new file mode 100644 index 0000000..60291c2 --- /dev/null +++ b/app/Jobs/Queue/Remove.php @@ -0,0 +1,41 @@ +worker = $worker; + } + + public function handle(): void + { + $this->worker->server->processManager()->handler()->delete($this->worker->id, $this->worker->site_id); + $this->worker->delete(); + event( + new Broadcast('remove-queue-finished', [ + 'id' => $this->worker->id, + ]) + ); + } + + public function failed(): void + { + $this->worker->status = QueueStatus::FAILED; + $this->worker->save(); + event( + new Broadcast('remove-queue-failed', [ + 'message' => __('Failed to delete worker!'), + 'id' => $this->worker->id, + ]) + ); + } +} diff --git a/app/Jobs/Redirect/AddToServer.php b/app/Jobs/Redirect/AddToServer.php new file mode 100644 index 0000000..b8915f6 --- /dev/null +++ b/app/Jobs/Redirect/AddToServer.php @@ -0,0 +1,42 @@ +redirect = $redirect; + } + + public function handle(): void + { + /** @var array $redirects */ + $redirects = Redirect::query()->where('site_id', $this->redirect->site_id)->get(); + $this->redirect->site->server->webserver()->handler()->updateRedirects($this->redirect->site, $redirects); + $this->redirect->status = 'ready'; + $this->redirect->save(); + event( + new Broadcast('create-redirect-finished', [ + 'redirect' => $this->redirect, + ]) + ); + } + + public function failed(): void + { + $this->redirect->status = 'failed'; + $this->redirect->delete(); + event( + new Broadcast('create-redirect-failed', [ + 'redirect' => $this->redirect, + ]) + ); + } +} diff --git a/app/Jobs/Redirect/DeleteFromServer.php b/app/Jobs/Redirect/DeleteFromServer.php new file mode 100644 index 0000000..38afd00 --- /dev/null +++ b/app/Jobs/Redirect/DeleteFromServer.php @@ -0,0 +1,44 @@ +redirect = $redirect; + } + + public function handle(): void + { + /** @var array $redirects */ + $redirects = Redirect::query() + ->where('site_id', $this->redirect->site_id) + ->where('id', '!=', $this->redirect->id) + ->get(); + $this->redirect->site->server->webserver()->handler()->updateRedirects($this->redirect->site, $redirects); + $this->redirect->delete(); + event( + new Broadcast('delete-redirect-finished', [ + 'id' => $this->redirect->id, + ]) + ); + } + + public function failed(): void + { + $this->redirect->status = 'failed'; + $this->redirect->save(); + event( + new Broadcast('delete-redirect-failed', [ + 'redirect' => $this->redirect, + ]) + ); + } +} diff --git a/app/Jobs/Script/ExecuteOn.php b/app/Jobs/Script/ExecuteOn.php new file mode 100644 index 0000000..58998dd --- /dev/null +++ b/app/Jobs/Script/ExecuteOn.php @@ -0,0 +1,61 @@ +script = $script; + $this->server = $server; + $this->user = $user; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->scriptExecution = $this->script->executions()->create([ + 'server_id' => $this->server->id, + 'user' => $this->user, + ]); + $this->server->ssh($this->scriptExecution->user)->exec( + $this->script->content, + 'execute-script' + ); + $this->scriptExecution->finished_at = now(); + $this->scriptExecution->save(); + event( + new Broadcast('execute-script-finished', [ + 'execution' => $this->scriptExecution, + ]) + ); + } + + public function failed(): void + { + $this->scriptExecution->finished_at = now(); + $this->scriptExecution->save(); + event( + new Broadcast('execute-script-failed', [ + 'execution' => $this->scriptExecution, + ]) + ); + } +} diff --git a/app/Jobs/Server/CheckConnection.php b/app/Jobs/Server/CheckConnection.php new file mode 100644 index 0000000..08b3770 --- /dev/null +++ b/app/Jobs/Server/CheckConnection.php @@ -0,0 +1,49 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $status = $this->server->status; + $this->server->ssh()->connect(); + $this->server->refresh(); + if ($status == 'disconnected') { + $this->server->status = 'ready'; + $this->server->save(); + } + event( + new Broadcast('server-status-finished', [ + 'server' => $this->server, + ]) + ); + } + + public function failed(): void + { + $this->server->status = 'disconnected'; + $this->server->save(); + /** @todo notify */ + event( + new Broadcast('server-status-failed', [ + 'server' => $this->server, + ]) + ); + } +} diff --git a/app/Jobs/Server/RebootServer.php b/app/Jobs/Server/RebootServer.php new file mode 100644 index 0000000..dbc8f5d --- /dev/null +++ b/app/Jobs/Server/RebootServer.php @@ -0,0 +1,45 @@ +server = $server; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec(new RebootCommand(), 'reboot'); + event( + new Broadcast('reboot-server-finished', [ + 'message' => __('The server is being rebooted. It can take several minutes to boot up'), + 'id' => $this->server->id, + ]) + ); + } + + public function failed(): void + { + $this->server->status = 'ready'; + $this->server->save(); + event( + new Broadcast('reboot-server-failed', [ + 'message' => __('Failed to reboot the server'), + 'server' => $this->server, + ]) + ); + } +} diff --git a/app/Jobs/Service/Install.php b/app/Jobs/Service/Install.php new file mode 100644 index 0000000..78896a9 --- /dev/null +++ b/app/Jobs/Service/Install.php @@ -0,0 +1,24 @@ +service = $service; + } + + public function handle() + { + } + + public function failed(\Throwable $throwable) + { + } +} diff --git a/app/Jobs/Service/Manage.php b/app/Jobs/Service/Manage.php new file mode 100644 index 0000000..d4e7672 --- /dev/null +++ b/app/Jobs/Service/Manage.php @@ -0,0 +1,75 @@ +service = $service; + $this->action = $action; + $this->successStatus = $successStatus; + $this->failStatus = $failStatus; + $this->failMessage = $failMessage; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $command = match ($this->action) { + 'start' => new StartServiceCommand($this->service->unit), + 'stop' => new StopServiceCommand($this->service->unit), + 'restart' => new RestartServiceCommand($this->service->unit), + default => throw new Exception('Invalid action'), + }; + $this->service->server->ssh()->exec( + $command, + $this->action.'-'.$this->service->name + ); + $this->service->status = $this->successStatus; + $this->service->save(); + event( + new Broadcast('update-service-finished', [ + 'service' => $this->service, + ]) + ); + } + + public function failed(): void + { + $this->service->status = $this->failStatus; + $this->service->save(); + event( + new Broadcast('update-service-failed', [ + 'message' => $this->service->name.' '.$this->failMessage, + 'service' => $this->service, + ]) + ); + } +} diff --git a/app/Jobs/Site/ChangePHPVersion.php b/app/Jobs/Site/ChangePHPVersion.php new file mode 100644 index 0000000..e2b9c87 --- /dev/null +++ b/app/Jobs/Site/ChangePHPVersion.php @@ -0,0 +1,43 @@ +site = $site; + $this->version = $version; + } + + public function handle(): void + { + $this->site->php_version = $this->version; + $this->site->server->webserver()->handler()->changePHPVersion($this->site, $this->version); + $this->site->save(); + event( + new Broadcast('change-site-php-finished', [ + 'id' => $this->site->id, + 'php_version' => $this->site->php_version, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('change-site-php-failed', [ + 'message' => __('Failed to change PHP!'), + 'id' => $this->site->id, + ]) + ); + } +} diff --git a/app/Jobs/Site/CloneRepository.php b/app/Jobs/Site/CloneRepository.php new file mode 100755 index 0000000..db4cba3 --- /dev/null +++ b/app/Jobs/Site/CloneRepository.php @@ -0,0 +1,34 @@ +site = $site; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->site->server->ssh()->exec( + new CloneRepositoryCommand( + $this->site->full_repository_url, + $this->site->path, + $this->site->branch + ), + 'clone-repository', + $this->site->id + ); + } +} diff --git a/app/Jobs/Site/ComposerInstall.php b/app/Jobs/Site/ComposerInstall.php new file mode 100755 index 0000000..795d472 --- /dev/null +++ b/app/Jobs/Site/ComposerInstall.php @@ -0,0 +1,34 @@ +site = $site; + } + + /** + * @throws ComposerInstallFailed + * @throws Throwable + */ + public function handle(): void + { + $this->site->server->ssh()->exec( + new ComposerInstallCommand( + $this->site->path + ), + 'composer-install', + $this->site->id + ); + } +} diff --git a/app/Jobs/Site/CreateVHost.php b/app/Jobs/Site/CreateVHost.php new file mode 100755 index 0000000..95a93e2 --- /dev/null +++ b/app/Jobs/Site/CreateVHost.php @@ -0,0 +1,21 @@ +site = $site; + } + + public function handle(): void + { + $this->site->server->webserver()->handler()->createVHost($this->site); + } +} diff --git a/app/Jobs/Site/DeleteSite.php b/app/Jobs/Site/DeleteSite.php new file mode 100755 index 0000000..1242144 --- /dev/null +++ b/app/Jobs/Site/DeleteSite.php @@ -0,0 +1,40 @@ +site = $site; + } + + public function handle(): void + { + $this->site->server->webserver()->handler()->deleteSite($this->site); + $this->site->delete(); + event( + new Broadcast('delete-site-finished', [ + 'site' => $this->site, + ]) + ); + } + + public function failed(): void + { + $this->site->status = SiteStatus::READY; + $this->site->save(); + event( + new Broadcast('delete-site-failed', [ + 'site' => $this->site, + ]) + ); + } +} diff --git a/app/Jobs/Site/Deploy.php b/app/Jobs/Site/Deploy.php new file mode 100644 index 0000000..8dcc8ac --- /dev/null +++ b/app/Jobs/Site/Deploy.php @@ -0,0 +1,64 @@ +deployment = $deployment; + $this->path = $path; + $this->script = $script; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->ssh = $this->deployment->site->server->ssh(); + $this->ssh->exec( + new RunScript($this->path, $this->script), + 'deploy', + $this->deployment->site_id + ); + $this->deployment->status = DeploymentStatus::FINISHED; + $this->deployment->log_id = $this->ssh->log->id; + $this->deployment->save(); + event( + new Broadcast('deploy-site-finished', [ + 'deployment' => $this->deployment, + ]) + ); + } + + public function failed(): void + { + $this->deployment->status = DeploymentStatus::FAILED; + if ($this->ssh->log) { + $this->deployment->log_id = $this->ssh->log->id; + } + $this->deployment->save(); + event( + new Broadcast('deploy-site-failed', [ + 'deployment' => $this->deployment, + ]) + ); + } +} diff --git a/app/Jobs/Site/DeployEnv.php b/app/Jobs/Site/DeployEnv.php new file mode 100644 index 0000000..72809ec --- /dev/null +++ b/app/Jobs/Site/DeployEnv.php @@ -0,0 +1,46 @@ +site = $site; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->site->server->ssh()->exec( + new EditFileCommand( + $this->site->path.'/.env', + $this->site->env + ) + ); + event( + new Broadcast('deploy-site-env-finished', [ + 'site' => $this->site, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('deploy-site-env-failed', [ + 'site' => $this->site, + ]) + ); + } +} diff --git a/app/Jobs/Site/InstallWordpress.php b/app/Jobs/Site/InstallWordpress.php new file mode 100755 index 0000000..593f823 --- /dev/null +++ b/app/Jobs/Site/InstallWordpress.php @@ -0,0 +1,109 @@ +site = $site; + } + + /** + * @throws ValidationException + * @throws FailedToInstallWordpress + * @throws Throwable + */ + public function handle(): void + { + $this->setupDatabase(); + + $result = $this->site->server->ssh()->exec( + new InstallWordpressCommand( + $this->site->path, + $this->site->domain, + $this->database->name, + $this->databaseUser->username, + $this->databaseUser->password, + 'localhost', + 'wp_', + $this->site->type_data['username'], + $this->site->type_data['password'], + $this->site->type_data['email'], + $this->site->type_data['title'], + ), + 'install-wordpress', + $this->site->id + ); + + if (! Str::contains($result, 'Wordpress installed!')) { + throw new FailedToInstallWordpress($result); + } + } + + /** + * @throws ValidationException + */ + private function setupDatabase() + { + // create database + $this->database = $this->site->server->databases()->where('name', $this->site->type_data['database'])->first(); + if (! $this->database) { + $this->database = new Database([ + 'server_id' => $this->site->server_id, + 'name' => $this->site->type_data['database'], + ]); + $this->database->server->database()->handler()->create($this->database->name); + $this->database->is_created = true; + $this->database->save(); + } + + // create database user + $this->databaseUser = $this->site->server->databaseUsers()->where('username', $this->site->type_data['database_user'])->first(); + if (! $this->databaseUser) { + $this->databaseUser = new DatabaseUser([ + 'server_id' => $this->site->server_id, + 'username' => $this->site->type_data['database_user'], + 'password' => Str::random(10), + 'host' => 'localhost', + ]); + $this->databaseUser->save(); + $this->databaseUser->server->database()->handler()->createUser($this->databaseUser->username, $this->databaseUser->password, $this->databaseUser->host); + $this->databaseUser->is_created = true; + $this->databaseUser->save(); + } + + // link database user + $linkedDatabases = $this->databaseUser->databases ?? []; + if (! in_array($this->database->name, $linkedDatabases)) { + $linkedDatabases[] = $this->database->name; + $this->databaseUser->databases = $linkedDatabases; + $this->databaseUser->server->database()->handler()->unlink( + $this->databaseUser->username, + $this->databaseUser->host, + ); + $this->databaseUser->server->database()->handler()->link( + $this->databaseUser->username, + $this->databaseUser->host, + $this->databaseUser->databases + ); + $this->databaseUser->save(); + } + } +} diff --git a/app/Jobs/Site/UpdateBranch.php b/app/Jobs/Site/UpdateBranch.php new file mode 100644 index 0000000..a9063ef --- /dev/null +++ b/app/Jobs/Site/UpdateBranch.php @@ -0,0 +1,53 @@ +site = $site; + $this->branch = $branch; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->site->server->ssh()->exec( + new UpdateBranchCommand( + $this->site->path, + $this->branch + ), + 'update-branch', + $this->site->id + ); + $this->site->branch = $this->branch; + $this->site->save(); + event( + new Broadcast('update-branch-finished', [ + 'site' => $this->site, + ]) + ); + } + + public function failed(): void + { + event( + new Broadcast('update-branch-failed', [ + 'site' => $this->site, + ]) + ); + } +} diff --git a/app/Jobs/Site/UpdateSourceControlsRemote.php b/app/Jobs/Site/UpdateSourceControlsRemote.php new file mode 100644 index 0000000..a000ff5 --- /dev/null +++ b/app/Jobs/Site/UpdateSourceControlsRemote.php @@ -0,0 +1,41 @@ +sourceControl = $sourceControl; + } + + /** + * Execute the job. + * + * @throws Throwable + */ + public function handle(): void + { + $sites = Site::query() + ->where('user_id', $this->sourceControl->user_id) + ->where('source_control', $this->sourceControl->provider) + ->get(); + foreach ($sites as $site) { + $site->server->ssh()->exec( + 'cd '.$site->path.' && git remote set-url origin '.$site->full_repository_url + ); + } + } +} diff --git a/app/Jobs/Site/UpdateVHost.php b/app/Jobs/Site/UpdateVHost.php new file mode 100755 index 0000000..6dd616e --- /dev/null +++ b/app/Jobs/Site/UpdateVHost.php @@ -0,0 +1,21 @@ +site = $site; + } + + public function handle(): void + { + $this->site->server->webserver()->handler()->updateVHost($this->site); + } +} diff --git a/app/Jobs/SshKey/DeleteSshKeyFromServer.php b/app/Jobs/SshKey/DeleteSshKeyFromServer.php new file mode 100644 index 0000000..06883df --- /dev/null +++ b/app/Jobs/SshKey/DeleteSshKeyFromServer.php @@ -0,0 +1,50 @@ +server = $server; + $this->sshKey = $sshKey; + } + + /** + * @throws Throwable + */ + public function handle() + { + $this->server->ssh()->exec( + new DeleteSshKeyCommand($this->sshKey->public_key), + 'delete-ssh-key' + ); + $this->server->sshKeys()->detach($this->sshKey); + event( + new Broadcast('delete-ssh-key-finished', [ + 'sshKey' => $this->sshKey, + ]) + ); + } + + public function failed(): void + { + $this->server->sshKeys()->attach($this->sshKey); + event( + new Broadcast('delete-ssh-key-failed', [ + 'sshKey' => $this->sshKey, + ]) + ); + } +} diff --git a/app/Jobs/SshKey/DeploySshKeyToServer.php b/app/Jobs/SshKey/DeploySshKeyToServer.php new file mode 100644 index 0000000..8a58816 --- /dev/null +++ b/app/Jobs/SshKey/DeploySshKeyToServer.php @@ -0,0 +1,53 @@ +server = $server; + $this->sshKey = $sshKey; + } + + /** + * @throws Throwable + */ + public function handle(): void + { + $this->server->ssh()->exec( + new DeploySshKeyCommand($this->sshKey->public_key), + 'deploy-ssh-key' + ); + $this->sshKey->servers()->updateExistingPivot($this->server->id, [ + 'status' => SshKeyStatus::ADDED, + ]); + event( + new Broadcast('deploy-ssh-key-finished', [ + 'sshKey' => $this->sshKey, + ]) + ); + } + + public function failed(): void + { + $this->server->sshKeys()->detach($this->sshKey); + event( + new Broadcast('deploy-ssh-key-failed', [ + 'sshKey' => $this->sshKey, + ]) + ); + } +} diff --git a/app/Jobs/Ssl/Deploy.php b/app/Jobs/Ssl/Deploy.php new file mode 100644 index 0000000..cead66d --- /dev/null +++ b/app/Jobs/Ssl/Deploy.php @@ -0,0 +1,48 @@ +ssl = $ssl; + } + + public function handle(): void + { + $this->ssl->site->server->webserver()->handler()->setupSSL($this->ssl); + $this->ssl->status = SslStatus::CREATED; + $this->ssl->save(); + event( + new Broadcast('deploy-ssl-finished', [ + 'ssl' => $this->ssl, + ]) + ); + if ($this->ssl->site->type == SiteType::WORDPRESS) { + $typeData = $this->ssl->site->type_data; + $typeData['url'] = $this->ssl->site->url; + $this->ssl->site->type_data = $typeData; + $this->ssl->site->save(); + $this->ssl->site->type()->edit(); + } + } + + public function failed(): void + { + event( + new Broadcast('deploy-ssl-failed', [ + 'ssl' => $this->ssl, + ]) + ); + $this->ssl->delete(); + } +} diff --git a/app/Jobs/Ssl/Remove.php b/app/Jobs/Ssl/Remove.php new file mode 100644 index 0000000..6134155 --- /dev/null +++ b/app/Jobs/Ssl/Remove.php @@ -0,0 +1,39 @@ +ssl = $ssl; + } + + public function handle(): void + { + $this->ssl->site->server->webserver()->handler()->removeSSL($this->ssl); + $this->ssl->delete(); + event( + new Broadcast('remove-ssl-finished', [ + 'ssl' => $this->ssl, + ]) + ); + } + + public function failed(): void + { + $this->ssl->status = 'failed'; + $this->ssl->save(); + event( + new Broadcast('remove-ssl-failed', [ + 'ssl' => $this->ssl, + ]) + ); + } +} diff --git a/app/Jobs/StorageProvider/DeleteFile.php b/app/Jobs/StorageProvider/DeleteFile.php new file mode 100644 index 0000000..ae715c8 --- /dev/null +++ b/app/Jobs/StorageProvider/DeleteFile.php @@ -0,0 +1,24 @@ +storageProvider = $storageProvider; + $this->paths = $paths; + } + + public function handle(): void + { + $this->storageProvider->provider()->delete($this->paths); + } +} diff --git a/app/Mail/NotificationChannelMessage.php b/app/Mail/NotificationChannelMessage.php new file mode 100644 index 0000000..24219d3 --- /dev/null +++ b/app/Mail/NotificationChannelMessage.php @@ -0,0 +1,47 @@ +subject = $subject; + $this->text = $text; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + if ($this->text instanceof MailMessage) { + return $this->markdown('vendor.notifications.email', $this->text->data()); + } + + return $this->markdown('emails.notification-channel-message', [ + 'subject' => $this->subject, + 'text' => $this->text, + ]); + } +} diff --git a/app/Models/AbstractModel.php b/app/Models/AbstractModel.php new file mode 100755 index 0000000..9983913 --- /dev/null +++ b/app/Models/AbstractModel.php @@ -0,0 +1,24 @@ +{$field}; + $current[$key] = $value; + $this->{$field} = $current; + if ($save) { + $this->save(); + } + } +} diff --git a/app/Models/Backup.php b/app/Models/Backup.php new file mode 100644 index 0000000..422e251 --- /dev/null +++ b/app/Models/Backup.php @@ -0,0 +1,87 @@ + 'integer', + 'storage_id' => 'integer', + 'database_id' => 'integer', + 'keep_backups' => 'integer', + ]; + + public static function boot(): void + { + parent::boot(); + + static::deleting(function (Backup $backup) { + $backup->files()->delete(); + }); + } + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function storage(): BelongsTo + { + return $this->belongsTo(StorageProvider::class, 'storage_id'); + } + + public function database(): BelongsTo + { + return $this->belongsTo(Database::class); + } + + public function files(): HasMany + { + return $this->hasMany(BackupFile::class, 'backup_id'); + } + + public function run(): void + { + $file = new BackupFile([ + 'backup_id' => $this->id, + 'name' => Str::of($this->name)->slug().'-'.now()->format('YmdHis'), + 'status' => 'creating', + ]); + $file->save(); + + dispatch(new RunBackup($file))->onConnection('ssh'); + } +} diff --git a/app/Models/BackupFile.php b/app/Models/BackupFile.php new file mode 100644 index 0000000..c62a30a --- /dev/null +++ b/app/Models/BackupFile.php @@ -0,0 +1,88 @@ + 'integer', + 'restored_at' => 'datetime', + ]; + + protected static function booted(): void + { + static::created(function (BackupFile $backupFile) { + $keep = $backupFile->backup->keep_backups; + if ($backupFile->backup->files()->count() > $keep) { + /* @var BackupFile $lastFileToKeep */ + $lastFileToKeep = $backupFile->backup->files()->orderByDesc('id')->skip($keep)->first(); + if ($lastFileToKeep) { + $files = $backupFile->backup->files() + ->where('id', '<=', $lastFileToKeep->id) + ->get(); + foreach ($files as $file) { + $file->delete(); + } + } + } + }); + + static::deleted(function (BackupFile $backupFile) { + dispatch(new DeleteFile( + $backupFile->backup->storage, + [$backupFile->storage_path] + )); + }); + } + + public function backup(): BelongsTo + { + return $this->belongsTo(Backup::class); + } + + public function getPathAttribute(): string + { + return '/home/'.$this->backup->server->ssh_user.'/'.$this->name.'.zip'; + } + + public function getStoragePathAttribute(): string + { + return '/'.$this->backup->name.'/'.$this->name.'.zip'; + } + + public function restore(Database $database): void + { + $this->status = 'restoring'; + $this->restored_to = $database->name; + $this->save(); + dispatch(new RestoreDatabase($this, $database))->onConnection('ssh'); + } +} diff --git a/app/Models/CronJob.php b/app/Models/CronJob.php new file mode 100755 index 0000000..cba2ee4 --- /dev/null +++ b/app/Models/CronJob.php @@ -0,0 +1,90 @@ + 'integer', + 'hidden' => 'boolean', + ]; + + protected $appends = [ + 'frequency_label', + ]; + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function getCrontabAttribute(): string + { + $data = ''; + $cronJobs = $this->server->cronJobs()->where('user', $this->user)->get(); + foreach ($cronJobs as $key => $cronJob) { + $data .= $cronJob->frequency.' '.$cronJob->command; + if ($key != count($cronJobs) - 1) { + $data .= "\n"; + } + } + + return $data; + } + + public function addToServer(): void + { + dispatch(new AddToServer($this))->onConnection('ssh'); + } + + public function removeFromServer(): void + { + $this->status = CronjobStatus::DELETING; + $this->save(); + dispatch(new RemoveFromServer($this))->onConnection('ssh'); + } + + public function getFrequencyLabelAttribute(): string + { + $labels = [ + '* * * * *' => 'Every minute', + '0 * * * *' => 'Hourly', + '0 0 * * *' => 'Daily', + '0 0 * * 0' => 'Weekly', + '0 0 1 * *' => 'Monthly', + ]; + if (isset($labels[$this->frequency])) { + return $labels[$this->frequency]; + } + + return $this->frequency; + } +} diff --git a/app/Models/Database.php b/app/Models/Database.php new file mode 100755 index 0000000..8c8562e --- /dev/null +++ b/app/Models/Database.php @@ -0,0 +1,79 @@ + 'integer', + ]; + + public static function boot(): void + { + parent::boot(); + + static::deleting(function (Database $database) { + $database->server->databaseUsers()->each(function (DatabaseUser $user) use ($database) { + $databases = $user->databases; + if ($databases && in_array($database->name, $databases)) { + unset($databases[array_search($database->name, $databases)]); + $user->databases = $databases; + $user->save(); + } + }); + $database->backups()->each(function (Backup $backup) { + $backup->delete(); + }); + }); + } + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + /** + * create database on server + */ + public function createOnServer(): void + { + dispatch(new CreateOnServer($this))->onConnection('ssh'); + } + + /** + * delete database from server + */ + public function deleteFromServer(): void + { + $this->status = DatabaseStatus::DELETING; + $this->save(); + dispatch(new DeleteFromServer($this))->onConnection('ssh'); + } + + public function backups(): HasMany + { + return $this->hasMany(Backup::class)->where('type', 'database'); + } +} diff --git a/app/Models/DatabaseUser.php b/app/Models/DatabaseUser.php new file mode 100755 index 0000000..8a61bbf --- /dev/null +++ b/app/Models/DatabaseUser.php @@ -0,0 +1,96 @@ + 'integer', + 'password' => 'encrypted', + 'databases' => 'array', + ]; + + protected $hidden = [ + 'password', + ]; + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function scopeHasDatabase(Builder $query, string $databaseName): Builder + { + return $query->where('databases', 'like', "%\"$databaseName\"%"); + } + + public function createOnServer(): void + { + dispatch(new CreateOnServer($this))->onConnection('ssh'); + } + + public function deleteFromServer(): void + { + $this->status = DatabaseStatus::DELETING; + $this->save(); + + dispatch(new DeleteFromServer($this))->onConnection('ssh'); + } + + public function linkNewDatabase(string $name): void + { + $linkedDatabases = $this->databases ?? []; + if (! in_array($name, $linkedDatabases)) { + $linkedDatabases[] = $name; + $this->databases = $linkedDatabases; + $this->unlinkUser(); + $this->linkUser(); + $this->save(); + } + } + + public function linkUser(): void + { + dispatch(new LinkUser($this))->onConnection('ssh'); + } + + public function unlinkUser(): void + { + dispatch(new UnlinkUser($this))->onConnection('ssh'); + } + + public function getFullUserAttribute(): string + { + return $this->username.'@'.$this->host; + } +} diff --git a/app/Models/Deployment.php b/app/Models/Deployment.php new file mode 100755 index 0000000..4626af7 --- /dev/null +++ b/app/Models/Deployment.php @@ -0,0 +1,67 @@ + 'integer', + 'deployment_script_id' => 'integer', + 'log_id' => 'integer', + 'commit_data' => 'json', + ]; + + protected $appends = [ + 'commit_id_short', + ]; + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } + + public function deploymentScript(): BelongsTo + { + return $this->belongsTo(DeploymentScript::class); + } + + public function log(): BelongsTo + { + return $this->belongsTo(ServerLog::class, 'log_id'); + } + + public function getCommitIdShortAttribute(): string + { + if ($this->commit_id) { + return substr($this->commit_id, 0, 7); + } + + return ''; + } +} diff --git a/app/Models/DeploymentScript.php b/app/Models/DeploymentScript.php new file mode 100644 index 0000000..4dd0a02 --- /dev/null +++ b/app/Models/DeploymentScript.php @@ -0,0 +1,32 @@ + 'integer', + ]; + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } +} diff --git a/app/Models/FirewallRule.php b/app/Models/FirewallRule.php new file mode 100755 index 0000000..0169d18 --- /dev/null +++ b/app/Models/FirewallRule.php @@ -0,0 +1,68 @@ + 'integer', + 'port' => 'integer', + ]; + + protected $appends = [ + 'real_protocol', + ]; + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function addToServer(): void + { + dispatch(new AddToServer($this))->onConnection('ssh'); + } + + public function removeFromServer(): void + { + $this->status = FirewallRuleStatus::DELETING; + $this->save(); + dispatch(new RemoveFromServer($this))->onConnection('ssh'); + } + + public function getRealProtocolAttribute(): string + { + return $this->protocol === 'udp' ? 'udp' : 'tcp'; + } +} diff --git a/app/Models/GitHook.php b/app/Models/GitHook.php new file mode 100755 index 0000000..89f03fc --- /dev/null +++ b/app/Models/GitHook.php @@ -0,0 +1,83 @@ + 'integer', + 'source_control_id' => 'integer', + 'events' => 'array', + 'actions' => 'array', + 'hook_response' => 'json', + ]; + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } + + public function sourceControl(): BelongsTo + { + return $this->belongsTo(SourceControl::class); + } + + public function scopeHasEvent(Builder $query, string $event): Builder + { + return $query->where('events', 'like', "%\"{$event}\"%"); + } + + /** + * @throws FailedToDeployGitHook + */ + public function deployHook(): void + { + $this->update( + $this->sourceControl->provider()->deployHook($this->site->repository, $this->events, $this->secret) + ); + } + + /** + * @throws Throwable + */ + public function destroyHook(): void + { + try { + DB::beginTransaction(); + $this->sourceControl->provider()->destroyHook($this->site->repository, $this->hook_id); + $this->delete(); + DB::commit(); + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } +} diff --git a/app/Models/NotificationChannel.php b/app/Models/NotificationChannel.php new file mode 100644 index 0000000..b60b682 --- /dev/null +++ b/app/Models/NotificationChannel.php @@ -0,0 +1,39 @@ + 'json', + 'connected' => 'boolean', + 'is_default' => 'boolean', + ]; + + public function provider(): \App\Contracts\NotificationChannel + { + $provider = config('core.notification_channels_providers_class')[$this->provider]; + + return new $provider($this); + } +} diff --git a/app/Models/Queue.php b/app/Models/Queue.php new file mode 100644 index 0000000..ccecb4d --- /dev/null +++ b/app/Models/Queue.php @@ -0,0 +1,143 @@ + 'integer', + 'site_id' => 'integer', + 'auto_start' => 'boolean', + 'auto_restart' => 'boolean', + 'numprocs' => 'integer', + 'redirect_stderr' => 'boolean', + ]; + + public function getServerIdAttribute(int $value): int + { + if (! $value) { + $value = $this->site->server_id; + $this->fill(['server_id' => $this->site->server_id]); + $this->save(); + } + + return $value; + } + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } + + public function getLogDirectoryAttribute(): string + { + return '/home/'.$this->user.'/.logs/workers'; + } + + public function getLogFileAttribute(): string + { + return $this->log_directory.'/'.$this->id.'.log'; + } + + public function deploy(): void + { + dispatch(new Deploy($this))->onConnection('ssh'); + } + + private function action(string $type, string $status, string $successStatus, string $failStatus, string $failMessage): void + { + $this->status = $status; + $this->save(); + dispatch(new Manage($this, $type, $successStatus, $failStatus, $failMessage)) + ->onConnection('ssh'); + } + + public function start(): void + { + $this->action( + 'start', + QueueStatus::STARTING, + QueueStatus::RUNNING, + QueueStatus::FAILED, + __('Failed to start') + ); + } + + public function stop(): void + { + $this->action( + 'stop', + QueueStatus::STOPPING, + QueueStatus::STOPPED, + QueueStatus::FAILED, + __('Failed to stop') + ); + } + + public function restart(): void + { + $this->action( + 'restart', + QueueStatus::RESTARTING, + QueueStatus::RUNNING, + QueueStatus::FAILED, + __('Failed to restart') + ); + } + + public function remove(): void + { + $this->status = QueueStatus::DELETING; + $this->save(); + dispatch(new Remove($this))->onConnection('ssh'); + } + + public function getLogs(): void + { + dispatch(new GetLogs($this))->onConnection('ssh'); + } +} diff --git a/app/Models/Redirect.php b/app/Models/Redirect.php new file mode 100644 index 0000000..214fc16 --- /dev/null +++ b/app/Models/Redirect.php @@ -0,0 +1,50 @@ + 'integer', + 'mode' => 'integer', + ]; + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } + + public function addToServer(): void + { + dispatch(new AddToServer($this))->onConnection('ssh'); + } + + public function deleteFromServer(): void + { + $this->status = 'deleting'; + $this->save(); + dispatch(new DeleteFromServer($this))->onConnection('ssh'); + } +} diff --git a/app/Models/Script.php b/app/Models/Script.php new file mode 100644 index 0000000..2abed49 --- /dev/null +++ b/app/Models/Script.php @@ -0,0 +1,44 @@ + 'integer', + ]; + + public function creator(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function executions(): HasMany + { + return $this->hasMany(ScriptExecution::class, 'script_id'); + } + + public function executeOn(Server $server, string $user): void + { + dispatch(new ExecuteOn($this, $server, $user))->onConnection('ssh'); + } +} diff --git a/app/Models/ScriptExecution.php b/app/Models/ScriptExecution.php new file mode 100644 index 0000000..f0aa0cd --- /dev/null +++ b/app/Models/ScriptExecution.php @@ -0,0 +1,42 @@ + 'integer', + 'server_id' => 'integer', + ]; + + public function script(): BelongsTo + { + return $this->belongsTo(Script::class); + } + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } +} diff --git a/app/Models/Server.php b/app/Models/Server.php new file mode 100755 index 0000000..2be36d3 --- /dev/null +++ b/app/Models/Server.php @@ -0,0 +1,388 @@ + 'integer', + 'type_data' => 'json', + 'port' => 'integer', + 'provider_data' => 'json', + 'authentication' => 'encrypted:json', + 'auto_update' => 'boolean', + 'available_updates' => 'integer', + 'security_updates' => 'integer', + 'progress' => 'integer', + ]; + + protected $hidden = [ + 'authentication', + ]; + + public static function boot(): void + { + parent::boot(); + + static::deleting(function (Server $server) { + $server->sites()->each(function (Site $site) { + $site->delete(); + }); + $server->provider()->delete(); + $server->logs()->delete(); + $server->services()->delete(); + $server->databases()->delete(); + $server->databaseUsers()->delete(); + $server->firewallRules()->delete(); + $server->cronJobs()->delete(); + $server->queues()->delete(); + $server->daemons()->delete(); + $server->scriptExecutions()->delete(); + $server->sshKeys()->detach(); + if (File::exists($server->sshKey()['public_key_path'])) { + File::delete($server->sshKey()['public_key_path']); + } + if (File::exists($server->sshKey()['private_key_path'])) { + File::delete($server->sshKey()['private_key_path']); + } + }); + } + + public function creator(): BelongsTo + { + return $this->belongsTo(User::class, 'user_id'); + } + + public function serverProvider(): BelongsTo + { + return $this->belongsTo(ServerProvider::class, 'provider_id'); + } + + public function logs(): HasMany + { + return $this->hasMany(ServerLog::class); + } + + public function sites(): HasMany + { + return $this->hasMany(Site::class); + } + + public function services(): HasMany + { + return $this->hasMany(Service::class); + } + + public function databases(): HasMany + { + return $this->hasMany(Database::class); + } + + public function databaseUsers(): HasMany + { + return $this->hasMany(DatabaseUser::class); + } + + public function firewallRules(): HasMany + { + return $this->hasMany(FirewallRule::class); + } + + public function cronJobs(): HasMany + { + return $this->hasMany(CronJob::class); + } + + public function queues(): HasMany + { + return $this->hasMany(Queue::class); + } + + public function scriptExecutions(): HasMany + { + return $this->hasMany(ScriptExecution::class); + } + + public function backups(): HasMany + { + return $this->hasMany(Backup::class); + } + + public function daemons(): HasMany + { + return $this->queues()->whereNull('site_id'); + } + + public function service($type, $version = null): ?Service + { + /* @var Service $service */ + $service = $this->services() + ->where(function ($query) use ($type, $version) { + $query->where('type', $type); + if ($version) { + $query->where('version', $version); + } + }) + ->first(); + + return $service; + } + + public function defaultService($type): ?Service + { + /* @var Service $service */ + $service = $this->services() + ->where('type', $type) + ->where('is_default', 1) + ->first(); + + return $service; + } + + public function getServiceByUnit($unit): ?Service + { + /* @var Service $service */ + $service = $this->services() + ->where('unit', $unit) + ->where('is_default', 1) + ->first(); + + return $service; + } + + public function install(): void + { + $this->type()->install(); + // $this->team->notify(new ServerInstallationStarted($this)); + } + + public function ssh(string $user = null, bool $defaultKeys = false): \App\Helpers\SSH|SSHFake + { + return SSH::init($this, $user, $defaultKeys); + } + + public function installedPHPVersions(): array + { + $versions = []; + $phps = $this->services()->where('type', 'php')->get(['version']); + foreach ($phps as $php) { + $versions[] = $php->version; + } + + return $versions; + } + + public function type(): ServerType + { + $typeClass = config('core.server_types_class')[$this->type]; + + return new $typeClass($this); + } + + public function provider(): \App\Contracts\ServerProvider + { + $providerClass = config('core.server_providers_class')[$this->provider]; + + return new $providerClass($this); + } + + public function webserver(string $version = null): ?Service + { + if (! $version) { + return $this->defaultService('webserver'); + } + + return $this->service('webserver', $version); + } + + public function database(string $version = null): ?Service + { + if (! $version) { + return $this->defaultService('database'); + } + + return $this->service('database', $version); + } + + public function firewall(string $version = null): ?Service + { + if (! $version) { + return $this->defaultService('firewall'); + } + + return $this->service('firewall', $version); + } + + public function processManager(string $version = null): ?Service + { + if (! $version) { + return $this->defaultService('process_manager'); + } + + return $this->service('process_manager', $version); + } + + public function php(string $version = null): ?Service + { + if (! $version) { + return $this->defaultService('php'); + } + + return $this->service('php', $version); + } + + public function sshKeys(): BelongsToMany + { + return $this->belongsToMany(SshKey::class, 'server_ssh_keys') + ->withPivot('status') + ->withTimestamps(); + } + + public function getSshUserAttribute(string $value): string + { + if ($value) { + return $value; + } + + return config('core.ssh_user'); + } + + public function sshKey(bool $default = false): array + { + if (app()->environment() == 'testing') { + return [ + 'public_key' => 'public', + 'public_key_path' => '/path', + 'private_key_path' => '/path', + ]; + } + + if ($default) { + return [ + 'public_key' => Str::replace("\n", '', File::get(storage_path(config('core.ssh_public_key_name')))), + 'public_key_path' => storage_path(config('core.ssh_public_key_name')), + 'private_key_path' => storage_path(config('core.ssh_private_key_name')), + ]; + } + + return [ + 'public_key' => Str::replace("\n", '', Storage::disk(config('core.key_pairs_disk'))->get($this->id.'.pub')), + 'public_key_path' => Storage::disk(config('core.key_pairs_disk'))->path($this->id.'.pub'), + 'private_key_path' => Storage::disk(config('core.key_pairs_disk'))->path((string) $this->id), + ]; + } + + public function getServiceUnits(): array + { + $units = []; + $services = $this->services; + foreach ($services as $service) { + if ($service->unit) { + $units[] = $service->unit; + } + } + + return $units; + } + + public function checkConnection(): void + { + dispatch(new CheckConnection($this))->onConnection('ssh'); + } + + public function installUpdates(): void + { + $this->available_updates = 0; + $this->security_updates = 0; + $this->save(); + dispatch(new Upgrade($this))->onConnection('ssh'); + } + + public function reboot(): void + { + $this->status = 'disconnected'; + $this->save(); + dispatch(new RebootServer($this))->onConnection('ssh'); + } + + public function getHostnameAttribute(): string + { + return Str::of($this->name)->slug(); + } +} diff --git a/app/Models/ServerLog.php b/app/Models/ServerLog.php new file mode 100755 index 0000000..ab4a5dd --- /dev/null +++ b/app/Models/ServerLog.php @@ -0,0 +1,72 @@ + 'integer', + 'site_id' => 'integer', + ]; + + public function getRouteKey(): string + { + return 'log'; + } + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } + + public function write($buf): void + { + if (Str::contains($buf, 'VITO_SSH_ERROR')) { + $buf = str_replace('VITO_SSH_ERROR', '', $buf); + } + if (Storage::disk($this->disk)->exists($this->name)) { + Storage::disk($this->disk)->append($this->name, $buf); + } else { + Storage::disk($this->disk)->put($this->name, $buf); + } + } + + public function getContentAttribute(): ?string + { + if (Storage::disk($this->disk)->exists($this->name)) { + return Storage::disk($this->disk)->get($this->name); + } + + return ''; + } +} diff --git a/app/Models/ServerProvider.php b/app/Models/ServerProvider.php new file mode 100644 index 0000000..366663c --- /dev/null +++ b/app/Models/ServerProvider.php @@ -0,0 +1,43 @@ + 'integer', + 'credentials' => 'encrypted:array', + 'connected' => 'boolean', + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function getCredentials(): array + { + return $this->credentials; + } +} diff --git a/app/Models/Service.php b/app/Models/Service.php new file mode 100755 index 0000000..58d05c5 --- /dev/null +++ b/app/Models/Service.php @@ -0,0 +1,217 @@ + 'integer', + 'type_data' => 'json', + 'is_default' => 'boolean', + ]; + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function handler(): Database|Firewall|Webserver|PHP|ProcessManager + { + $handler = config('core.service_handlers')[$this->name]; + + return new $handler($this); + } + + public function installer(): mixed + { + $installer = config('core.service_installers')[$this->name]; + + return new $installer($this); + } + + public function uninstaller(): mixed + { + $uninstaller = config('core.service_uninstallers')[$this->name]; + + return new $uninstaller($this); + } + + public function getUnitAttribute($value): string + { + if ($value) { + return $value; + } + if (isset(config('core.service_units')[$this->name])) { + $value = config('core.service_units')[$this->name][$this->server->os][$this->version]; + if ($value) { + $this->fill(['unit' => $value]); + $this->save(); + } + } + + return $value; + } + + public function install(): void + { + Bus::chain([ + $this->installer(), + function () { + event( + new Broadcast('install-service-finished', [ + 'service' => $this, + ]) + ); + }, + ])->catch(function () { + event( + new Broadcast('install-service-failed', [ + 'service' => $this, + ]) + ); + })->onConnection('ssh-long')->dispatch(); + } + + /** + * @throws InstallationFailed + */ + public function validateInstall($result): void + { + if (Str::contains($result, 'Active: active')) { + event( + new Broadcast('install-service-finished', [ + 'service' => $this, + ]) + ); + } else { + event( + new Broadcast('install-service-failed', [ + 'service' => $this, + ]) + ); + throw new InstallationFailed(); + } + } + + public function uninstall(): void + { + $this->status = ServiceStatus::UNINSTALLING; + $this->save(); + Bus::chain([ + $this->uninstaller(), + function () { + event( + new Broadcast('uninstall-service-finished', [ + 'service' => $this, + ]) + ); + $this->delete(); + }, + ])->catch(function () { + $this->status = ServiceStatus::FAILED; + $this->save(); + event( + new Broadcast('uninstall-service-failed', [ + 'service' => $this, + ]) + ); + })->onConnection('ssh')->dispatch(); + } + + public function start(): void + { + $this->action( + 'start', + ServiceStatus::STARTING, + ServiceStatus::READY, + ServiceStatus::STOPPED, + __('Failed to start') + ); + } + + public function stop(): void + { + $this->action( + 'stop', + ServiceStatus::STOPPING, + ServiceStatus::STOPPED, + ServiceStatus::FAILED, + __('Failed to stop') + ); + } + + public function restart(): void + { + $this->action( + 'restart', + ServiceStatus::RESTARTING, + ServiceStatus::READY, + ServiceStatus::FAILED, + __('Failed to restart') + ); + } + + public function action( + string $type, + string $status, + string $successStatus, + string $failStatus, + string $failMessage + ): void { + $this->status = $status; + $this->save(); + dispatch(new Manage($this, $type, $successStatus, $failStatus, $failMessage)) + ->onConnection('ssh'); + } + + public function installedVersions(): array + { + $versions = []; + $services = $this->server->services()->where('type', $this->type)->get(['version']); + foreach ($services as $service) { + $versions[] = $service->version; + } + + return $versions; + } +} diff --git a/app/Models/Site.php b/app/Models/Site.php new file mode 100755 index 0000000..e895e8e --- /dev/null +++ b/app/Models/Site.php @@ -0,0 +1,397 @@ + 'integer', + 'type_data' => 'json', + 'port' => 'integer', + 'progress' => 'integer', + 'auto_deployment' => 'boolean', + 'aliases' => 'array', + ]; + + protected $appends = [ + 'url', + 'auto_deployment', + ]; + + public static function boot(): void + { + parent::boot(); + + static::deleting(function (Site $site) { + $site->redirects()->delete(); + $site->queues()->delete(); + $site->ssls()->delete(); + $site->deployments()->delete(); + $site->deploymentScript()->delete(); + }); + + static::created(function (Site $site) { + $site->deploymentScript()->create([ + 'name' => 'default', + 'content' => '' + ]); + }); + } + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function logs(): HasMany + { + return $this->hasMany(ServerLog::class); + } + + public function deployments(): HasMany + { + return $this->hasMany(Deployment::class); + } + + public function gitHook(): HasOne + { + return $this->hasOne(GitHook::class); + } + + public function deploymentScript(): HasOne + { + return $this->hasOne(DeploymentScript::class); + } + + public function redirects(): HasMany + { + return $this->hasMany(Redirect::class); + } + + public function queues(): HasMany + { + return $this->hasMany(Queue::class); + } + + public function ssls(): HasMany + { + return $this->hasMany(Ssl::class); + } + + /** + * @throws SourceControlIsNotConnected + */ + public function sourceControl(): SourceControl|HasOne|null + { + if (! $this->source_control) { + return null; + } + + if ($this->source_control == 'custom') { + return new SourceControl([ + 'user_id' => $this->id, + 'provider' => 'custom', + 'token' => '', + 'connected' => true, + ]); + } + + $sourceControl = SourceControl::query()->where('provider', $this->source_control)->first(); + + if (! $sourceControl) { + throw new SourceControlIsNotConnected($this->source_control); + } + + return $sourceControl; + } + + /** + * @throws SourceControlIsNotConnected + */ + public function getFullRepositoryUrlAttribute() + { + return $this->sourceControl()->provider()->fullRepoUrl($this->repository); + } + + public function getAliasesStringAttribute(): string + { + if (count($this->aliases) > 0) { + return implode(' ', $this->aliases); + } + + return ''; + } + + public function type(): SiteType + { + $typeClass = config('core.site_types_class.'.$this->type); + + return new $typeClass($this); + } + + public function install(): void + { + $this->type()->install(); + } + + public function remove(): void + { + $this->update([ + 'status' => SiteStatus::DELETING, + ]); + $this->type()->delete(); + } + + public function php(): ?Service + { + if ($this->php_version) { + return $this->server->php($this->php_version); + } + + return null; + } + + public function changePHPVersion($version): void + { + dispatch(new ChangePHPVersion($this, $version))->onConnection('ssh'); + } + + public function getDeploymentScriptTextAttribute(): string + { + /* @var DeploymentScript $script */ + $script = $this->deploymentScript()->firstOrCreate([ + 'site_id' => $this->id, + ], [ + 'site_id' => $this->id, + 'name' => 'default', + ]); + + return $script->content; + } + + /** + * @throws SourceControlIsNotConnected + */ + public function deploy(): Deployment + { + if ($this->sourceControl()) { + $this->sourceControl()->getRepo($this->repository); + } + + $deployment = new Deployment([ + 'site_id' => $this->id, + 'deployment_script_id' => $this->deploymentScript->id, + 'status' => DeploymentStatus::DEPLOYING, + ]); + $lastCommit = $this->sourceControl()->provider()->getLastCommit($this->repository, $this->branch); + if ($lastCommit) { + $deployment->commit_id = $lastCommit['commit_id']; + $deployment->commit_data = $lastCommit['commit_data']; + } + $deployment->save(); + + dispatch( + new Deploy( + $deployment, + $this->path, + $this->deployment_script_text + ) + )->onConnection('ssh'); + + return $deployment; + } + + public function getEnvAttribute(): string + { + $typeData = $this->type_data; + if (! isset($typeData['env'])) { + $typeData['env'] = ''; + $this->type_data = $typeData; + $this->save(); + } + + return $typeData['env']; + } + + public function deployEnv(): void + { + dispatch(new DeployEnv($this))->onConnection('ssh'); + } + + public function activeSsl(): HasOne + { + return $this->hasOne(Ssl::class) + ->where('expires_at', '>=', now()) + ->orderByDesc('id'); + } + + public function createFreeSsl(): void + { + $ssl = new Ssl([ + 'site_id' => $this->id, + 'type' => 'letsencrypt', + 'expires_at' => now()->addMonths(3), + 'status' => SslStatus::CREATING, + ]); + $ssl->save(); + $ssl->deploy(); + } + + public function createCustomSsl(string $certificate, string $pk): void + { + $ssl = new Ssl([ + 'site_id' => $this->id, + 'type' => 'custom', + 'certificate' => $certificate, + 'pk' => $pk, + 'expires_at' => '', + 'status' => SslStatus::CREATING, + ]); + $ssl->save(); + $ssl->deploy(); + } + + public function getUrlAttribute(): string + { + if ($this->activeSsl) { + return 'https://'.$this->domain; + } + + return 'http://'.$this->domain; + } + + public function getWebDirectoryPathAttribute(): string + { + if ($this->web_directory) { + return $this->path.'/'.$this->web_directory; + } + + return $this->path; + } + + /** + * @throws SourceControlIsNotConnected + * @throws ValidationException + * @throws FailedToDeployGitHook + * @throws Throwable + */ + public function enableAutoDeployment(): void + { + if ($this->gitHook) { + throw ValidationException::withMessages([ + 'auto_deployment' => __('Auto deployment already enabled'), + ])->errorBag('auto_deployment'); + } + + if (! $this->sourceControl()) { + throw ValidationException::withMessages([ + 'auto_deployment' => __('Your application does not use any source controls'), + ])->errorBag('auto_deployment'); + } + + try { + DB::beginTransaction(); + $gitHook = new GitHook([ + 'site_id' => $this->id, + 'source_control_id' => $this->sourceControl()->id, + 'secret' => generate_uid(), + 'actions' => ['deploy'], + 'events' => ['push'], + ]); + $gitHook->save(); + $gitHook->deployHook(); + DB::commit(); + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + /** + * @throws Throwable + */ + public function disableAutoDeployment(): void + { + $this->gitHook?->destroyHook(); + } + + public function getAutoDeploymentAttribute(): bool + { + return (bool) $this->gitHook; + } + + public function updateBranch(string $branch): void + { + dispatch(new UpdateBranch($this, $branch))->onConnection('ssh'); + } +} diff --git a/app/Models/SourceControl.php b/app/Models/SourceControl.php new file mode 100755 index 0000000..16d7fd4 --- /dev/null +++ b/app/Models/SourceControl.php @@ -0,0 +1,36 @@ + 'encrypted', + ]; + + public function provider(): SourceControlProvider + { + $providerClass = config('core.source_control_providers_class')[$this->provider]; + + return new $providerClass($this); + } + + public function getRepo(string $repo = null): ?array + { + return $this->provider()->getRepo($repo); + } +} diff --git a/app/Models/SshKey.php b/app/Models/SshKey.php new file mode 100644 index 0000000..4f80343 --- /dev/null +++ b/app/Models/SshKey.php @@ -0,0 +1,66 @@ + 'integer', + 'public_key' => 'encrypted', + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function servers(): BelongsToMany + { + return $this->belongsToMany(Server::class, 'server_ssh_keys') + ->withPivot('status') + ->withTimestamps(); + } + + public function existsOnServer(Server $server): bool + { + return (bool) $this->servers()->where('id', $server->id)->first(); + } + + public function deployTo(Server $server): void + { + $server->sshKeys()->attach($this, [ + 'status' => SshKeyStatus::ADDING, + ]); + dispatch(new DeploySshKeyToServer($server, $this))->onConnection('ssh'); + } + + public function deleteFrom(Server $server): void + { + $this->servers()->updateExistingPivot($server->id, [ + 'status' => SshKeyStatus::DELETING, + ]); + dispatch(new DeleteSshKeyFromServer($server, $this))->onConnection('ssh'); + } +} diff --git a/app/Models/Ssl.php b/app/Models/Ssl.php new file mode 100644 index 0000000..b16baf2 --- /dev/null +++ b/app/Models/Ssl.php @@ -0,0 +1,132 @@ + 'integer', + 'certificate' => 'encrypted', + 'pk' => 'encrypted', + 'ca' => 'encrypted', + 'expires_at' => 'datetime', + ]; + + public function site(): BelongsTo + { + return $this->belongsTo(Site::class); + } + + public function getCertsDirectoryPathAttribute(): ?string + { + if ($this->type == 'letsencrypt') { + return '/etc/letsencrypt/live/'.$this->site->domain; + } + + if ($this->type == 'custom') { + return '/etc/ssl/'.$this->site->domain; + } + + return ''; + } + + public function getCertificatePathAttribute(): ?string + { + if ($this->type == 'letsencrypt') { + return $this->certificate; + } + + if ($this->type == 'custom') { + return $this->certs_directory_path.'/cert.pem'; + } + + return ''; + } + + public function getPkPathAttribute(): ?string + { + if ($this->type == 'letsencrypt') { + return $this->pk; + } + + if ($this->type == 'custom') { + return $this->certs_directory_path.'/privkey.pem'; + } + + return ''; + } + + public function getCaPathAttribute(): ?string + { + if ($this->type == 'letsencrypt') { + return $this->ca; + } + + if ($this->type == 'custom') { + return $this->certs_directory_path.'/fullchain.pem'; + } + + return ''; + } + + public function deploy(): void + { + dispatch(new Deploy($this))->onConnection('ssh'); + } + + public function remove(): void + { + $this->status = SslStatus::DELETING; + $this->save(); + dispatch(new Remove($this))->onConnection('ssh'); + } + + public function validateSetup(string $result): bool + { + if (! Str::contains($result, 'Successfully received certificate')) { + return false; + } + + if ($this->type == 'letsencrypt') { + $this->certificate = $this->certs_directory_path.'/fullchain.pem'; + $this->pk = $this->certs_directory_path.'/privkey.pem'; + $this->save(); + } + + return true; + } +} diff --git a/app/Models/StorageProvider.php b/app/Models/StorageProvider.php new file mode 100644 index 0000000..0282794 --- /dev/null +++ b/app/Models/StorageProvider.php @@ -0,0 +1,50 @@ + 'integer', + 'connected' => 'boolean', + 'token_expires_at' => 'datetime', + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function provider(): \App\Contracts\StorageProvider + { + $providerClass = config('core.storage_providers_class')[$this->provider]; + + return new $providerClass($this); + } +} diff --git a/app/Models/User.php b/app/Models/User.php new file mode 100755 index 0000000..722c7e2 --- /dev/null +++ b/app/Models/User.php @@ -0,0 +1,106 @@ +hasMany(SshKey::class); + } + + public function sourceControls(): HasMany + { + return $this->hasMany(SourceControl::class); + } + + public function serverProviders(): HasMany + { + return $this->hasMany(ServerProvider::class); + } + + public function scripts(): HasMany + { + return $this->hasMany(Script::class, 'user_id'); + } + + public function sourceControl(string $provider): HasOne + { + return $this->hasOne(SourceControl::class)->where('provider', $provider); + } + + public function storageProviders(): HasMany + { + return $this->hasMany(StorageProvider::class); + } + + public function storageProvider(string $provider): HasOne + { + return $this->hasOne(StorageProvider::class)->where('provider', $provider); + } + + public function connectedStorageProviders(): HasMany + { + return $this->storageProviders()->where('connected', true); + } + + public function connectedSourceControls(): array + { + $connectedSourceControls = []; + $sourceControls = $this->sourceControls() + ->where('connected', 1) + ->get(['provider']); + foreach ($sourceControls as $sourceControl) { + $connectedSourceControls[] = $sourceControl->provider; + } + + return $connectedSourceControls; + } +} diff --git a/app/NotificationChannels/AbstractProvider.php b/app/NotificationChannels/AbstractProvider.php new file mode 100644 index 0000000..3eab49e --- /dev/null +++ b/app/NotificationChannels/AbstractProvider.php @@ -0,0 +1,16 @@ +notificationChannel = $notificationChannel; + } +} diff --git a/app/NotificationChannels/Discord.php b/app/NotificationChannels/Discord.php new file mode 100644 index 0000000..b806d8d --- /dev/null +++ b/app/NotificationChannels/Discord.php @@ -0,0 +1,58 @@ + 'required|url', + ]; + } + + public function data(array $input): array + { + return [ + 'webhook_url' => $input['webhook_url'], + ]; + } + + public function connect(): bool + { + $connect = $this->checkConnection( + __('Congratulations! 🎉'), + __("You've connected your Discord to Vito")."\n". + __('Manage your notification channels')."\n". + route('notification-channels') + ); + + if (! $connect) { + return false; + } + + return true; + } + + public function sendMessage(string $subject, string $text): void + { + dispatch(function () use ($subject, $text) { + $data = $this->notificationChannel->data; + Http::post($data['webhook_url'], [ + 'content' => '*'.$subject.'*'."\n".$text, + ]); + })->onQueue('default'); + } + + private function checkConnection(string $subject, string $text): bool + { + $data = $this->notificationChannel->data; + $connect = Http::post($data['webhook_url'], [ + 'content' => '*'.$subject.'*'."\n".$text, + ]); + + return $connect->ok(); + } +} diff --git a/app/NotificationChannels/Email.php b/app/NotificationChannels/Email.php new file mode 100644 index 0000000..8f5b86f --- /dev/null +++ b/app/NotificationChannels/Email.php @@ -0,0 +1,37 @@ + 'required|email', + ]; + } + + public function data(array $input): array + { + return [ + 'email' => $input['email'], + ]; + } + + public function connect(): bool + { + $this->notificationChannel->connected = true; + $this->notificationChannel->save(); + + return true; + } + + public function sendMessage(string $subject, mixed $text): void + { + $data = $this->notificationChannel->data; + Mail::to($data['email'])->send(new NotificationChannelMessage($subject, $text)); + } +} diff --git a/app/NotificationChannels/Slack.php b/app/NotificationChannels/Slack.php new file mode 100644 index 0000000..5b1d68f --- /dev/null +++ b/app/NotificationChannels/Slack.php @@ -0,0 +1,58 @@ + 'required|url', + ]; + } + + public function data(array $input): array + { + return [ + 'webhook_url' => $input['webhook_url'], + ]; + } + + public function connect(): bool + { + $connect = $this->checkConnection( + __('Congratulations! 🎉'), + __("You've connected your Slack to Vito")."\n". + __('Manage your notification channels')."\n". + route('notification-channels') + ); + + if (! $connect) { + return false; + } + + return true; + } + + public function sendMessage(string $subject, string $text): void + { + dispatch(function () use ($subject, $text) { + $data = $this->notificationChannel->data; + Http::post($data['webhook_url'], [ + 'text' => '*'.$subject.'*'."\n".$text, + ]); + })->onQueue('default'); + } + + private function checkConnection(string $subject, string $text): bool + { + $data = $this->notificationChannel->data; + $connect = Http::post($data['webhook_url'], [ + 'text' => '*'.$subject.'*'."\n".$text, + ]); + + return $connect->ok(); + } +} diff --git a/app/Notifications/FailedToDeleteServerFromProvider.php b/app/Notifications/FailedToDeleteServerFromProvider.php new file mode 100644 index 0000000..f45b598 --- /dev/null +++ b/app/Notifications/FailedToDeleteServerFromProvider.php @@ -0,0 +1,44 @@ +server = $server; + } + + public function subject(): string + { + return __('Failed to delete the server from the provider!'); + } + + public function message(bool $mail = false): mixed + { + if ($mail) { + return $this->mail(); + } + + return __("We couldn't delete [:server] \nfrom :provider \nPlease check your provider and delete it manually", [ + 'server' => $this->server->name, + 'provider' => $this->server->provider, + ]); + } + + public function mail(): MailMessage + { + return (new MailMessage) + ->line("We couldn't delete [".$this->server->name.'] from '.$this->server->provider) + ->line('Please check your provider and delete it manually'); + } +} diff --git a/app/Notifications/SSLExpirationAlert.php b/app/Notifications/SSLExpirationAlert.php new file mode 100644 index 0000000..0fb7b0c --- /dev/null +++ b/app/Notifications/SSLExpirationAlert.php @@ -0,0 +1,26 @@ +ssl = $ssl; + } + + public function subject(): string + { + return __('SSL expiring soon!'); + } + + public function message(bool $mail = false): string + { + return $this->ssl->site->domain."'s ".__('SSL is expiring on').' '.$this->ssl->expires_at->format('Y-m-d'); + } +} diff --git a/app/Notifications/ServerDisconnected.php b/app/Notifications/ServerDisconnected.php new file mode 100644 index 0000000..80cadb5 --- /dev/null +++ b/app/Notifications/ServerDisconnected.php @@ -0,0 +1,40 @@ +server = $server; + } + + public function subject(): string + { + return __('Server disconnected!'); + } + + public function message(bool $mail = false): mixed + { + if ($mail) { + return $this->mail(); + } + + return __("We've disconnected from your server [:server]", [ + 'server' => $this->server->name, + ]); + } + + public function mail(): MailMessage + { + return (new MailMessage) + ->line("We've disconnected from your server [".$this->server->name.'].') + ->line('Please check your sever is online and make sure that has our public keys in it'); + } +} diff --git a/app/Notifications/ServerInstallationFailed.php b/app/Notifications/ServerInstallationFailed.php new file mode 100644 index 0000000..f20dc4e --- /dev/null +++ b/app/Notifications/ServerInstallationFailed.php @@ -0,0 +1,42 @@ +server = $server; + } + + public function subject(): string + { + return __('Server installation failed!'); + } + + public function message(bool $mail = false): mixed + { + if ($mail) { + return $this->mail(); + } + + return __("Installation failed for server [:server] \nCheck your server's logs \n:logs", [ + 'server' => $this->server->name, + 'logs' => url('/servers/'.$this->server->id.'/logs'), + ]); + } + + private function mail(): MailMessage + { + return (new MailMessage) + ->line('Your server ['.$this->server->name.'] installation has been failed.') + ->line('Check your server logs') + ->action('View Logs', url('/servers/'.$this->server->id.'/logs')); + } +} diff --git a/app/Notifications/ServerInstallationStarted.php b/app/Notifications/ServerInstallationStarted.php new file mode 100644 index 0000000..ac9f00d --- /dev/null +++ b/app/Notifications/ServerInstallationStarted.php @@ -0,0 +1,44 @@ +server = $server; + } + + public function subject(): string + { + return __('Server installation started!'); + } + + public function message(bool $mail = false): mixed + { + if ($mail) { + return $this->mail(); + } + + return __("Installation started for server [:server]\nThis may take several minutes depending on many things like your server's internet speed.\nAs soon as it finishes, We will notify you through this channel.\nYou can check the progress live on your dashboard.\n:progress", [ + 'server' => $this->server->name, + 'progress' => url('/servers/'.$this->server->id), + ]); + } + + public function mail(): MailMessage + { + return (new MailMessage) + ->line('Your server\'s ['.$this->server->name.'] installation has been started.') + ->line("This may take several minutes depending on many things like your server's internet speed.") + ->line('As soon as it finishes, We will notify you through this channel.') + ->line('You can check the progress live on your dashboard.') + ->action('Installation Progress', url('/servers/'.$this->server->id)); + } +} diff --git a/app/Notifications/ServerInstallationSucceed.php b/app/Notifications/ServerInstallationSucceed.php new file mode 100644 index 0000000..0e3a589 --- /dev/null +++ b/app/Notifications/ServerInstallationSucceed.php @@ -0,0 +1,51 @@ +server = $server; + } + + public function subject(): string + { + return __('Server installation succeed!'); + } + + public function message(bool $mail = false): mixed + { + $this->server->refresh(); + + if ($mail) { + return $this->mail(); + } + + return __("Installation succeed for server [:server] \nServer IP: :ip \nUser: :user\nPassword: :password\n:link", [ + 'server' => $this->server->name, + 'ip' => $this->server->ip, + 'user' => $this->server->authentication['user'], + 'password' => $this->server->authentication['pass'], + 'link' => url('/servers/'.$this->server->id), + ]); + } + + public function mail(): MailMessage + { + $this->server->refresh(); + + return (new MailMessage) + ->line('Your server ['.$this->server->name.'] has been installed successfully.') + ->line('Server IP: '.$this->server->ip) + ->line('User: '.$this->server->authentication['user']) + ->line('Password: '.$this->server->authentication['pass']) + ->action('Manage Your Server', url('/login')); + } +} diff --git a/app/Notifications/SourceControlDisconnected.php b/app/Notifications/SourceControlDisconnected.php new file mode 100644 index 0000000..73e48c1 --- /dev/null +++ b/app/Notifications/SourceControlDisconnected.php @@ -0,0 +1,42 @@ +sourceControl = $sourceControl; + } + + public function via(): array + { + return ['mail']; + } + + public function toMail(): MailMessage + { + return (new MailMessage) + ->subject('Lost connection to your '.$this->sourceControl) + ->line("We've lost connection to your $this->sourceControl account.") + ->line("We'll not able to do any deployments until you reconnect.") + ->line("To reconnect your $this->sourceControl account please click on the bellow button.") + ->action('Reconnect', url('/source-controls')); + } + + public function toArray(): array + { + return [ + // + ]; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php new file mode 100644 index 0000000..98a8c83 --- /dev/null +++ b/app/Providers/AppServiceProvider.php @@ -0,0 +1,51 @@ +app->bind('ssh', function () { + return new SSH; + }); + + $this->extendSocialite(); + } + + /** + * @throws BindingResolutionException + */ + private function extendSocialite(): void + { + $socialite = $this->app->make('Laravel\Socialite\Contracts\Factory'); + $socialite->extend( + 'dropbox', + function ($app) use ($socialite) { + $config = $app['config']['services.dropbox']; + + return $socialite->buildProvider(DropboxProvider::class, $config); + } + ); + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php new file mode 100644 index 0000000..dafcbee --- /dev/null +++ b/app/Providers/AuthServiceProvider.php @@ -0,0 +1,26 @@ + + */ + protected $policies = [ + // 'App\Models\Model' => 'App\Policies\ModelPolicy', + ]; + + /** + * Register any authentication / authorization services. + */ + public function boot(): void + { + // + } +} diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php new file mode 100644 index 0000000..2be04f5 --- /dev/null +++ b/app/Providers/BroadcastServiceProvider.php @@ -0,0 +1,19 @@ +> + */ + protected $listen = [ + Registered::class => [ + SendEmailVerificationNotification::class, + ], + ]; + + /** + * Register any events for your application. + */ + public function boot(): void + { + // + } + + /** + * Determine if events and listeners should be automatically discovered. + */ + public function shouldDiscoverEvents(): bool + { + return false; + } +} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..3102c1c --- /dev/null +++ b/app/Providers/RouteServiceProvider.php @@ -0,0 +1,48 @@ +configureRateLimiting(); + + $this->routes(function () { + Route::middleware('api') + ->prefix('api') + ->group(base_path('routes/api.php')); + + Route::middleware('web') + ->group(base_path('routes/web.php')); + }); + } + + /** + * Configure the rate limiters for the application. + */ + protected function configureRateLimiting(): void + { + RateLimiter::for('api', function (Request $request) { + return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); + }); + } +} diff --git a/app/Providers/TelescopeServiceProvider.php b/app/Providers/TelescopeServiceProvider.php new file mode 100644 index 0000000..d13b001 --- /dev/null +++ b/app/Providers/TelescopeServiceProvider.php @@ -0,0 +1,65 @@ +hideSensitiveRequestDetails(); + + Telescope::filter(function (IncomingEntry $entry) { + if ($this->app->environment('local')) { + return true; + } + + return $entry->isReportableException() || + $entry->isFailedRequest() || + $entry->isFailedJob() || + $entry->isScheduledTask() || + $entry->hasMonitoredTag(); + }); + } + + /** + * Prevent sensitive request details from being logged by Telescope. + */ + protected function hideSensitiveRequestDetails(): void + { + if ($this->app->environment('local')) { + return; + } + + Telescope::hideRequestParameters(['_token']); + + Telescope::hideRequestHeaders([ + 'cookie', + 'x-csrf-token', + 'x-xsrf-token', + ]); + } + + /** + * Register the Telescope gate. + * + * This gate determines who can access Telescope in non-local environments. + */ + protected function gate(): void + { + Gate::define('viewTelescope', function ($user) { + return in_array($user->email, [ + // + ]); + }); + } +} diff --git a/app/SSHCommands/ChangeDefaultPHPCommand.php b/app/SSHCommands/ChangeDefaultPHPCommand.php new file mode 100755 index 0000000..ff60fad --- /dev/null +++ b/app/SSHCommands/ChangeDefaultPHPCommand.php @@ -0,0 +1,32 @@ +version = $version; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/change-default-php.sh')); + } + + public function content(string $os): string + { + return Str::replace('__version__', $this->version, $this->file($os)); + } +} diff --git a/app/SSHCommands/ChangeNginxPHPVersionCommand.php b/app/SSHCommands/ChangeNginxPHPVersionCommand.php new file mode 100755 index 0000000..77907f3 --- /dev/null +++ b/app/SSHCommands/ChangeNginxPHPVersionCommand.php @@ -0,0 +1,47 @@ +domain = $domain; + $this->oldVersion = $oldVersion; + $this->newVersion = $newVersion; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/change-php-version.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__domain__', $this->domain, $this->file($os)); + $command = Str::replace('__old_version__', $this->oldVersion, $command); + + return Str::replace('__new_version__', $this->newVersion, $command); + } +} diff --git a/app/SSHCommands/CloneRepositoryCommand.php b/app/SSHCommands/CloneRepositoryCommand.php new file mode 100755 index 0000000..a5c5d93 --- /dev/null +++ b/app/SSHCommands/CloneRepositoryCommand.php @@ -0,0 +1,45 @@ +repository = $repository; + $this->path = $path; + $this->branch = $branch; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/clone-repository.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__repo__', $this->repository, $this->file($os)); + $command = Str::replace('__host__', get_hostname_from_repo($this->repository), $command); + $command = Str::replace('__branch__', $this->branch, $command); + + return Str::replace('__path__', $this->path, $command); + } +} diff --git a/app/SSHCommands/Command.php b/app/SSHCommands/Command.php new file mode 100755 index 0000000..ff7f7c2 --- /dev/null +++ b/app/SSHCommands/Command.php @@ -0,0 +1,10 @@ +path = $path; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/composer-install.sh')); + } + + public function content(string $os): string + { + return Str::replace('__path__', $this->path, $this->file($os)); + } +} diff --git a/app/SSHCommands/CreateCustomSSLCommand.php b/app/SSHCommands/CreateCustomSSLCommand.php new file mode 100755 index 0000000..fc7a140 --- /dev/null +++ b/app/SSHCommands/CreateCustomSSLCommand.php @@ -0,0 +1,43 @@ +path = $path; + $this->certificate = $certificate; + $this->pk = $pk; + $this->certificatePath = $certificatePath; + $this->pkPath = $pkPath; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/create-custom-ssl.sh')); + } + + public function content(string $os): string + { + $content = $this->file($os); + $content = str_replace('__path__', $this->path, $content); + $content = str_replace('__certificate__', $this->certificate, $content); + $content = str_replace('__pk__', $this->pk, $content); + $content = str_replace('__certificate_path__', $this->certificatePath, $content); + + return str_replace('__pk_path__', $this->pkPath, $content); + } +} diff --git a/app/SSHCommands/CreateLetsencryptSSLCommand.php b/app/SSHCommands/CreateLetsencryptSSLCommand.php new file mode 100755 index 0000000..a306397 --- /dev/null +++ b/app/SSHCommands/CreateLetsencryptSSLCommand.php @@ -0,0 +1,35 @@ +email = $email; + $this->domain = $domain; + $this->webDirectory = $webDirectory; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/create-letsencrypt-ssl.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__email__', $this->email, $this->file($os)); + $command = Str::replace('__web_directory__', $this->webDirectory, $command); + + return Str::replace('__domain__', $this->domain, $command); + } +} diff --git a/app/SSHCommands/CreateNginxPHPMyAdminVHostCommand.php b/app/SSHCommands/CreateNginxPHPMyAdminVHostCommand.php new file mode 100755 index 0000000..ef91428 --- /dev/null +++ b/app/SSHCommands/CreateNginxPHPMyAdminVHostCommand.php @@ -0,0 +1,29 @@ +vhost = $vhost; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/create-phpmyadmin-vhost.sh')); + } + + public function content(string $os): string + { + return Str::replace('__vhost__', $this->vhost, $this->file($os)); + } +} diff --git a/app/SSHCommands/CreateNginxVHostCommand.php b/app/SSHCommands/CreateNginxVHostCommand.php new file mode 100755 index 0000000..8b51299 --- /dev/null +++ b/app/SSHCommands/CreateNginxVHostCommand.php @@ -0,0 +1,50 @@ +domain = $domain; + $this->path = $path; + $this->vhost = $vhost; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/create-vhost.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__path__', $this->path, $this->file($os)); + $command = Str::replace('__domain__', $this->domain, $command); + + return Str::replace('__vhost__', $this->vhost, $command); + } +} diff --git a/app/SSHCommands/CreateUserCommand.php b/app/SSHCommands/CreateUserCommand.php new file mode 100755 index 0000000..293bafc --- /dev/null +++ b/app/SSHCommands/CreateUserCommand.php @@ -0,0 +1,39 @@ +user = $user; + $this->password = $password; + $this->key = $key; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/create-user.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + $command = Str::replace('__user__', $this->user, $command); + $command = Str::replace('__key__', $this->key, $command); + + return Str::replace('__password__', $this->password, $command); + } +} diff --git a/app/SSHCommands/Database/BackupDatabaseCommand.php b/app/SSHCommands/Database/BackupDatabaseCommand.php new file mode 100644 index 0000000..bbd25b1 --- /dev/null +++ b/app/SSHCommands/Database/BackupDatabaseCommand.php @@ -0,0 +1,36 @@ +provider = $provider; + $this->database = $database; + $this->fileName = $fileName; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/backup.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + $command = Str::replace('__database__', $this->database, $command); + + return Str::replace('__file__', $this->fileName, $command); + } +} diff --git a/app/SSHCommands/Database/CreateCommand.php b/app/SSHCommands/Database/CreateCommand.php new file mode 100755 index 0000000..38a4ce0 --- /dev/null +++ b/app/SSHCommands/Database/CreateCommand.php @@ -0,0 +1,36 @@ +provider = $provider; + $this->name = $name; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/create.sh')); + } + + public function content(string $os): string + { + return Str::replace('__name__', $this->name, $this->file($os)); + } +} diff --git a/app/SSHCommands/Database/CreateUserCommand.php b/app/SSHCommands/Database/CreateUserCommand.php new file mode 100755 index 0000000..5cc1b36 --- /dev/null +++ b/app/SSHCommands/Database/CreateUserCommand.php @@ -0,0 +1,51 @@ +provider = $provider; + $this->username = $username; + $this->password = $password; + $this->host = $host; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/create-user.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__username__', $this->username, $this->file($os)); + $command = Str::replace('__password__', $this->password, $command); + + return Str::replace('__host__', $this->host, $command); + } +} diff --git a/app/SSHCommands/Database/DeleteCommand.php b/app/SSHCommands/Database/DeleteCommand.php new file mode 100755 index 0000000..80926ee --- /dev/null +++ b/app/SSHCommands/Database/DeleteCommand.php @@ -0,0 +1,36 @@ +provider = $provider; + $this->name = $name; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/delete.sh')); + } + + public function content(string $os): string + { + return Str::replace('__name__', $this->name, $this->file($os)); + } +} diff --git a/app/SSHCommands/Database/DeleteUserCommand.php b/app/SSHCommands/Database/DeleteUserCommand.php new file mode 100755 index 0000000..585b905 --- /dev/null +++ b/app/SSHCommands/Database/DeleteUserCommand.php @@ -0,0 +1,44 @@ +provider = $provider; + $this->username = $username; + $this->host = $host; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/delete-user.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__username__', $this->username, $this->file($os)); + + return Str::replace('__host__', $this->host, $command); + } +} diff --git a/app/SSHCommands/Database/LinkCommand.php b/app/SSHCommands/Database/LinkCommand.php new file mode 100755 index 0000000..ee66a46 --- /dev/null +++ b/app/SSHCommands/Database/LinkCommand.php @@ -0,0 +1,48 @@ +provider = $provider; + $this->username = $username; + $this->host = $host; + $this->database = $database; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/link.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__username__', $this->username, $this->file($os)); + $command = Str::replace('__host__', $this->host, $command); + + return Str::replace('__database__', $this->database, $command); + } +} diff --git a/app/SSHCommands/Database/RestoreDatabaseCommand.php b/app/SSHCommands/Database/RestoreDatabaseCommand.php new file mode 100644 index 0000000..831a8a1 --- /dev/null +++ b/app/SSHCommands/Database/RestoreDatabaseCommand.php @@ -0,0 +1,36 @@ +provider = $provider; + $this->database = $database; + $this->fileName = $fileName; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/restore.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + $command = Str::replace('__database__', $this->database, $command); + + return Str::replace('__file__', $this->fileName, $command); + } +} diff --git a/app/SSHCommands/Database/UnlinkCommand.php b/app/SSHCommands/Database/UnlinkCommand.php new file mode 100755 index 0000000..7c049fc --- /dev/null +++ b/app/SSHCommands/Database/UnlinkCommand.php @@ -0,0 +1,41 @@ +provider = $provider; + $this->username = $username; + $this->host = $host; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/database/'.$this->provider.'/unlink.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__username__', $this->username, $this->file($os)); + + return Str::replace('__host__', $this->host, $command); + } +} diff --git a/app/SSHCommands/DeleteNginxPHPMyAdminVHost.php b/app/SSHCommands/DeleteNginxPHPMyAdminVHost.php new file mode 100755 index 0000000..73cdb29 --- /dev/null +++ b/app/SSHCommands/DeleteNginxPHPMyAdminVHost.php @@ -0,0 +1,30 @@ +path = $path; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/delete-phpmyadmin-vhost.sh')); + } + + public function content(string $os): string + { + return Str::replace('__path__', $this->path, $this->file($os)); + } +} diff --git a/app/SSHCommands/DeleteNginxSiteCommand.php b/app/SSHCommands/DeleteNginxSiteCommand.php new file mode 100755 index 0000000..c2dddb3 --- /dev/null +++ b/app/SSHCommands/DeleteNginxSiteCommand.php @@ -0,0 +1,40 @@ +domain = $domain; + $this->path = $path; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/delete-site.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__domain__', $this->domain, $this->file($os)); + + return Str::replace('__path__', $this->path, $command); + } +} diff --git a/app/SSHCommands/DeleteSshKeyCommand.php b/app/SSHCommands/DeleteSshKeyCommand.php new file mode 100755 index 0000000..966b295 --- /dev/null +++ b/app/SSHCommands/DeleteSshKeyCommand.php @@ -0,0 +1,32 @@ +key = $key; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/delete-ssh-key.sh')); + } + + public function content(string $os): string + { + return Str::replace('__key__', Str::replace('/', '\/', $this->key), $this->file($os)); + } +} diff --git a/app/SSHCommands/DeploySshKeyCommand.php b/app/SSHCommands/DeploySshKeyCommand.php new file mode 100755 index 0000000..c00798f --- /dev/null +++ b/app/SSHCommands/DeploySshKeyCommand.php @@ -0,0 +1,32 @@ +key = $key; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/deploy-ssh-key.sh')); + } + + public function content(string $os): string + { + return Str::replace('__key__', addslashes($this->key), $this->file($os)); + } +} diff --git a/app/SSHCommands/DownloadPHPMyAdminCommand.php b/app/SSHCommands/DownloadPHPMyAdminCommand.php new file mode 100644 index 0000000..117d56d --- /dev/null +++ b/app/SSHCommands/DownloadPHPMyAdminCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/EditFileCommand.php b/app/SSHCommands/EditFileCommand.php new file mode 100644 index 0000000..7687ba9 --- /dev/null +++ b/app/SSHCommands/EditFileCommand.php @@ -0,0 +1,31 @@ +path = $path; + $this->content = $content; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/edit-file.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__path__', $this->path, $this->file($os)); + + return Str::replace('__content__', addslashes($this->content), $command); + } +} diff --git a/app/SSHCommands/Firewall/AddRuleCommand.php b/app/SSHCommands/Firewall/AddRuleCommand.php new file mode 100755 index 0000000..ac6c321 --- /dev/null +++ b/app/SSHCommands/Firewall/AddRuleCommand.php @@ -0,0 +1,56 @@ +provider = $provider; + $this->type = $type; + $this->protocol = $protocol; + $this->port = $port; + $this->source = $source; + $this->mask = $mask; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/firewall/'.$this->provider.'/add-rule.sh')); + } +} diff --git a/app/SSHCommands/Firewall/CommandContent.php b/app/SSHCommands/Firewall/CommandContent.php new file mode 100755 index 0000000..5b7633c --- /dev/null +++ b/app/SSHCommands/Firewall/CommandContent.php @@ -0,0 +1,18 @@ +type, $this->file($os)); + $command = Str::replace('__protocol__', $this->protocol, $command); + $command = Str::replace('__source__', $this->source, $command); + $command = Str::replace('__mask__', $this->mask, $command); + + return Str::replace('__port__', $this->port, $command); + } +} diff --git a/app/SSHCommands/Firewall/RemoveRuleCommand.php b/app/SSHCommands/Firewall/RemoveRuleCommand.php new file mode 100755 index 0000000..4024b59 --- /dev/null +++ b/app/SSHCommands/Firewall/RemoveRuleCommand.php @@ -0,0 +1,56 @@ +provider = $provider; + $this->type = $type; + $this->protocol = $protocol; + $this->port = $port; + $this->source = $source; + $this->mask = $mask; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/firewall/'.$this->provider.'/remove-rule.sh')); + } +} diff --git a/app/SSHCommands/GetPHPIniCommand.php b/app/SSHCommands/GetPHPIniCommand.php new file mode 100755 index 0000000..567fbfd --- /dev/null +++ b/app/SSHCommands/GetPHPIniCommand.php @@ -0,0 +1,29 @@ +version = $version; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/get-php-ini.sh')); + } + + public function content(string $os): string + { + return Str::replace('__version__', $this->version, $this->file($os)); + } +} diff --git a/app/SSHCommands/GetPublicKeyCommand.php b/app/SSHCommands/GetPublicKeyCommand.php new file mode 100755 index 0000000..00ce95d --- /dev/null +++ b/app/SSHCommands/GetPublicKeyCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallCertbotCommand.php b/app/SSHCommands/InstallCertbotCommand.php new file mode 100755 index 0000000..6ff17df --- /dev/null +++ b/app/SSHCommands/InstallCertbotCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallComposerCommand.php b/app/SSHCommands/InstallComposerCommand.php new file mode 100755 index 0000000..502da17 --- /dev/null +++ b/app/SSHCommands/InstallComposerCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallDependenciesCommand.php b/app/SSHCommands/InstallDependenciesCommand.php new file mode 100755 index 0000000..4dac42f --- /dev/null +++ b/app/SSHCommands/InstallDependenciesCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallMariadbCommand.php b/app/SSHCommands/InstallMariadbCommand.php new file mode 100755 index 0000000..347caee --- /dev/null +++ b/app/SSHCommands/InstallMariadbCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallMysqlCommand.php b/app/SSHCommands/InstallMysqlCommand.php new file mode 100755 index 0000000..d291687 --- /dev/null +++ b/app/SSHCommands/InstallMysqlCommand.php @@ -0,0 +1,29 @@ +version = $version; + } + + public function file(string $os): string + { + if ($this->version == '8.0') { + return File::get(base_path('system/commands/ubuntu/install-mysql-8.sh')); + } + + return File::get(base_path('system/commands/ubuntu/install-mysql.sh')); + } + + public function content(string $os): string + { + return $this->file($os); + } +} diff --git a/app/SSHCommands/InstallNginxCommand.php b/app/SSHCommands/InstallNginxCommand.php new file mode 100755 index 0000000..0e82a31 --- /dev/null +++ b/app/SSHCommands/InstallNginxCommand.php @@ -0,0 +1,29 @@ +config(), $this->file($os)); + } + + /** + * @return string + */ + protected function config() + { + $config = File::get(base_path('system/command-templates/nginx/nginx.conf')); + + return Str::replace('__user__', config('core.ssh_user'), $config); + } +} diff --git a/app/SSHCommands/InstallNodejsCommand.php b/app/SSHCommands/InstallNodejsCommand.php new file mode 100755 index 0000000..b6c1411 --- /dev/null +++ b/app/SSHCommands/InstallNodejsCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallPHPCommand.php b/app/SSHCommands/InstallPHPCommand.php new file mode 100755 index 0000000..e1e3745 --- /dev/null +++ b/app/SSHCommands/InstallPHPCommand.php @@ -0,0 +1,34 @@ +version = $version; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/install-php.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__version__', $this->version, $this->file($os)); + + return Str::replace('__user__', config('core.ssh_user'), $command); + } +} diff --git a/app/SSHCommands/InstallPHPExtensionCommand.php b/app/SSHCommands/InstallPHPExtensionCommand.php new file mode 100755 index 0000000..a8f76df --- /dev/null +++ b/app/SSHCommands/InstallPHPExtensionCommand.php @@ -0,0 +1,37 @@ +version = $version; + $this->name = $name; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/install-php-extension.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__version__', $this->version, $this->file($os)); + + return Str::replace('__name__', $this->name, $command); + } +} diff --git a/app/SSHCommands/InstallRedisCommand.php b/app/SSHCommands/InstallRedisCommand.php new file mode 100755 index 0000000..94579f5 --- /dev/null +++ b/app/SSHCommands/InstallRedisCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallRequirementsCommand.php b/app/SSHCommands/InstallRequirementsCommand.php new file mode 100755 index 0000000..5002ac6 --- /dev/null +++ b/app/SSHCommands/InstallRequirementsCommand.php @@ -0,0 +1,28 @@ +email = $email; + $this->name = $name; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/install-requirements.sh')); + } + + public function content(string $os): string + { + return $this->file($os); + } +} diff --git a/app/SSHCommands/InstallSupervisorCommand.php b/app/SSHCommands/InstallSupervisorCommand.php new file mode 100755 index 0000000..8098300 --- /dev/null +++ b/app/SSHCommands/InstallSupervisorCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallUfwCommand.php b/app/SSHCommands/InstallUfwCommand.php new file mode 100755 index 0000000..5d302a7 --- /dev/null +++ b/app/SSHCommands/InstallUfwCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/InstallWordpressCommand.php b/app/SSHCommands/InstallWordpressCommand.php new file mode 100755 index 0000000..2e2bfec --- /dev/null +++ b/app/SSHCommands/InstallWordpressCommand.php @@ -0,0 +1,71 @@ +path = $path; + $this->domain = $domain; + $this->dbName = $dbName; + $this->dbUser = $dbUser; + $this->dbPass = $dbPass; + $this->dbHost = $dbHost; + $this->dbPrefix = $dbPrefix; + $this->username = $username; + $this->password = $password; + $this->email = $email; + $this->title = $title; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/wordpress/install.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + + $command = str_replace('__path__', $this->path, $command); + $command = str_replace('__domain__', $this->domain, $command); + $command = str_replace('__db_name__', $this->dbName, $command); + $command = str_replace('__db_user__', $this->dbUser, $command); + $command = str_replace('__db_pass__', $this->dbPass, $command); + $command = str_replace('__db_host__', $this->dbHost, $command); + $command = str_replace('__db_prefix__', $this->dbPrefix, $command); + $command = str_replace('__username__', $this->username, $command); + $command = str_replace('__password__', $this->password, $command); + $command = str_replace('__title__', $this->title, $command); + + return str_replace('__email__', $this->email, $command); + } +} diff --git a/app/SSHCommands/ManageServiceCommand.php b/app/SSHCommands/ManageServiceCommand.php new file mode 100755 index 0000000..5eff68e --- /dev/null +++ b/app/SSHCommands/ManageServiceCommand.php @@ -0,0 +1,40 @@ +unit = $unit; + $this->action = $action; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/manage-service.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__service__', $this->unit, $this->file($os)); + + return Str::replace('__action__', $this->action, $command); + } +} diff --git a/app/SSHCommands/ProcessManager/Supervisor/CreateWorkerCommand.php b/app/SSHCommands/ProcessManager/Supervisor/CreateWorkerCommand.php new file mode 100644 index 0000000..b813374 --- /dev/null +++ b/app/SSHCommands/ProcessManager/Supervisor/CreateWorkerCommand.php @@ -0,0 +1,33 @@ +id = $id; + $this->config = $config; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/process-manager/supervisor/create-worker.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + $command = Str::replace('__id__', $this->id, $command); + + return Str::replace('__config__', $this->config, $command); + } +} diff --git a/app/SSHCommands/ProcessManager/Supervisor/DeleteWorkerCommand.php b/app/SSHCommands/ProcessManager/Supervisor/DeleteWorkerCommand.php new file mode 100644 index 0000000..95d68f6 --- /dev/null +++ b/app/SSHCommands/ProcessManager/Supervisor/DeleteWorkerCommand.php @@ -0,0 +1,29 @@ +id = $id; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/process-manager/supervisor/delete-worker.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + + return Str::replace('__id__', $this->id, $command); + } +} diff --git a/app/SSHCommands/ProcessManager/Supervisor/RestartWorkerCommand.php b/app/SSHCommands/ProcessManager/Supervisor/RestartWorkerCommand.php new file mode 100644 index 0000000..5a0b247 --- /dev/null +++ b/app/SSHCommands/ProcessManager/Supervisor/RestartWorkerCommand.php @@ -0,0 +1,29 @@ +id = $id; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/process-manager/supervisor/restart-worker.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + + return Str::replace('__id__', $this->id, $command); + } +} diff --git a/app/SSHCommands/ProcessManager/Supervisor/StartWorkerCommand.php b/app/SSHCommands/ProcessManager/Supervisor/StartWorkerCommand.php new file mode 100644 index 0000000..fdbd3dd --- /dev/null +++ b/app/SSHCommands/ProcessManager/Supervisor/StartWorkerCommand.php @@ -0,0 +1,29 @@ +id = $id; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/process-manager/supervisor/start-worker.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + + return Str::replace('__id__', $this->id, $command); + } +} diff --git a/app/SSHCommands/ProcessManager/Supervisor/StopWorkerCommand.php b/app/SSHCommands/ProcessManager/Supervisor/StopWorkerCommand.php new file mode 100644 index 0000000..7bf46ba --- /dev/null +++ b/app/SSHCommands/ProcessManager/Supervisor/StopWorkerCommand.php @@ -0,0 +1,29 @@ +id = $id; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/process-manager/supervisor/stop-worker.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + + return Str::replace('__id__', $this->id, $command); + } +} diff --git a/app/SSHCommands/RebootCommand.php b/app/SSHCommands/RebootCommand.php new file mode 100644 index 0000000..49c4549 --- /dev/null +++ b/app/SSHCommands/RebootCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/SSHCommands/RemoveSSLCommand.php b/app/SSHCommands/RemoveSSLCommand.php new file mode 100755 index 0000000..f5f491a --- /dev/null +++ b/app/SSHCommands/RemoveSSLCommand.php @@ -0,0 +1,23 @@ +path = $path; + } + + public function file(string $os): string + { + return ''; + } + + public function content(string $os): string + { + return 'sudo rm -rf '.$this->path.'*'."\n"; + } +} diff --git a/app/SSHCommands/RestartServiceCommand.php b/app/SSHCommands/RestartServiceCommand.php new file mode 100644 index 0000000..2472efe --- /dev/null +++ b/app/SSHCommands/RestartServiceCommand.php @@ -0,0 +1,32 @@ +unit = $unit; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/restart-service.sh')); + } + + public function content(string $os): string + { + return Str::replace('__service__', $this->unit, $this->file($os)); + } +} diff --git a/app/SSHCommands/RunScript.php b/app/SSHCommands/RunScript.php new file mode 100644 index 0000000..fad9a87 --- /dev/null +++ b/app/SSHCommands/RunScript.php @@ -0,0 +1,31 @@ +path = $path; + $this->script = $script; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/run-script.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__path__', $this->path, $this->file($os)); + + return Str::replace('__script__', make_bash_script($this->script), $command); + } +} diff --git a/app/SSHCommands/ServiceStatusCommand.php b/app/SSHCommands/ServiceStatusCommand.php new file mode 100755 index 0000000..c16a46a --- /dev/null +++ b/app/SSHCommands/ServiceStatusCommand.php @@ -0,0 +1,32 @@ +unit = $unit; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/service-status.sh')); + } + + public function content(string $os): string + { + return Str::replace('__service__', $this->unit, $this->file($os)); + } +} diff --git a/app/SSHCommands/StartServiceCommand.php b/app/SSHCommands/StartServiceCommand.php new file mode 100644 index 0000000..4224bc5 --- /dev/null +++ b/app/SSHCommands/StartServiceCommand.php @@ -0,0 +1,32 @@ +unit = $unit; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/start-service.sh')); + } + + public function content(string $os): string + { + return Str::replace('__service__', $this->unit, $this->file($os)); + } +} diff --git a/app/SSHCommands/StopServiceCommand.php b/app/SSHCommands/StopServiceCommand.php new file mode 100644 index 0000000..c7a422b --- /dev/null +++ b/app/SSHCommands/StopServiceCommand.php @@ -0,0 +1,32 @@ +unit = $unit; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/stop-service.sh')); + } + + public function content(string $os): string + { + return Str::replace('__service__', $this->unit, $this->file($os)); + } +} diff --git a/app/SSHCommands/Storage/DownloadFromDropboxCommand.php b/app/SSHCommands/Storage/DownloadFromDropboxCommand.php new file mode 100644 index 0000000..b6857ee --- /dev/null +++ b/app/SSHCommands/Storage/DownloadFromDropboxCommand.php @@ -0,0 +1,37 @@ +src = $src; + $this->dest = $dest; + $this->token = $token; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/storage/download-from-dropbox.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + $command = Str::replace('__src__', $this->src, $command); + $command = Str::replace('__dest__', $this->dest, $command); + + return Str::replace('__token__', $this->token, $command); + } +} diff --git a/app/SSHCommands/Storage/UploadToDropboxCommand.php b/app/SSHCommands/Storage/UploadToDropboxCommand.php new file mode 100644 index 0000000..8025e97 --- /dev/null +++ b/app/SSHCommands/Storage/UploadToDropboxCommand.php @@ -0,0 +1,37 @@ +src = $src; + $this->dest = $dest; + $this->token = $token; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/storage/upload-to-dropbox.sh')); + } + + public function content(string $os): string + { + $command = $this->file($os); + $command = Str::replace('__src__', $this->src, $command); + $command = Str::replace('__dest__', $this->dest, $command); + + return Str::replace('__token__', $this->token, $command); + } +} diff --git a/app/SSHCommands/UninstallPHPCommand.php b/app/SSHCommands/UninstallPHPCommand.php new file mode 100755 index 0000000..fdba407 --- /dev/null +++ b/app/SSHCommands/UninstallPHPCommand.php @@ -0,0 +1,34 @@ +version = $version; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/uninstall-php.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__version__', $this->version, $this->file($os)); + + return Str::replace('__user__', config('core.ssh_user'), $command); + } +} diff --git a/app/SSHCommands/UpdateBranchCommand.php b/app/SSHCommands/UpdateBranchCommand.php new file mode 100644 index 0000000..d38f768 --- /dev/null +++ b/app/SSHCommands/UpdateBranchCommand.php @@ -0,0 +1,31 @@ +path = $path; + $this->branch = $branch; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/update-branch.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__path__', $this->path, $this->file($os)); + + return Str::replace('__branch__', $this->branch, $command); + } +} diff --git a/app/SSHCommands/UpdateCronJobsCommand.php b/app/SSHCommands/UpdateCronJobsCommand.php new file mode 100755 index 0000000..540eda9 --- /dev/null +++ b/app/SSHCommands/UpdateCronJobsCommand.php @@ -0,0 +1,34 @@ +user = $user; + $this->data = $data; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/common/update-cron-jobs.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__user__', $this->user, $this->file($os)); + + return Str::replace('__data__', $this->data, $command); + } +} diff --git a/app/SSHCommands/UpdateNginxRedirectsCommand.php b/app/SSHCommands/UpdateNginxRedirectsCommand.php new file mode 100755 index 0000000..c17d551 --- /dev/null +++ b/app/SSHCommands/UpdateNginxRedirectsCommand.php @@ -0,0 +1,43 @@ +domain = $domain; + $this->redirects = $redirects; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/update-redirects.sh')); + } + + public function content(string $os): string + { + info($this->redirects); + $command = Str::replace('__redirects__', addslashes($this->redirects), $this->file($os)); + + return Str::replace('__domain__', $this->domain, $command); + } +} diff --git a/app/SSHCommands/UpdateNginxVHostCommand.php b/app/SSHCommands/UpdateNginxVHostCommand.php new file mode 100755 index 0000000..dd4d842 --- /dev/null +++ b/app/SSHCommands/UpdateNginxVHostCommand.php @@ -0,0 +1,50 @@ +domain = $domain; + $this->path = $path; + $this->vhost = $vhost; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/webserver/nginx/update-vhost.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__path__', $this->path, $this->file($os)); + $command = Str::replace('__domain__', $this->domain, $command); + + return Str::replace('__vhost__', $this->vhost, $command); + } +} diff --git a/app/SSHCommands/UpdatePHPSettingsCommand.php b/app/SSHCommands/UpdatePHPSettingsCommand.php new file mode 100755 index 0000000..c13b1f9 --- /dev/null +++ b/app/SSHCommands/UpdatePHPSettingsCommand.php @@ -0,0 +1,41 @@ +version = $version; + $this->variable = $variable; + $this->value = $value; + } + + public function file(string $os): string + { + return File::get(base_path('system/commands/ubuntu/update-php-settings.sh')); + } + + public function content(string $os): string + { + $command = Str::replace('__version__', $this->version, $this->file($os)); + $command = Str::replace('__variable__', $this->variable, $command); + + return Str::replace('__value__', $this->value, $command); + } +} diff --git a/app/SSHCommands/UpdateWordpressCommand.php b/app/SSHCommands/UpdateWordpressCommand.php new file mode 100755 index 0000000..2a0351e --- /dev/null +++ b/app/SSHCommands/UpdateWordpressCommand.php @@ -0,0 +1,50 @@ +path = $path; + $this->url = $url; + $this->username = $username; + $this->password = $password; + $this->email = $email; + $this->title = $title; + } + + public function file(string $os): string + { + return ''; + } + + public function content(string $os): string + { + $command = ''; + if ($this->title) { + $command .= 'wp --path='.$this->path.' option update blogname "'.addslashes($this->title).'"'."\n"; + } + if ($this->url) { + $command .= 'wp --path='.$this->path.' option update siteurl "'.addslashes($this->url).'"'."\n"; + $command .= 'wp --path='.$this->path.' option update home "'.addslashes($this->url).'"'."\n"; + } + + return $command; + } +} diff --git a/app/SSHCommands/UpgradeCommand.php b/app/SSHCommands/UpgradeCommand.php new file mode 100755 index 0000000..030e5d0 --- /dev/null +++ b/app/SSHCommands/UpgradeCommand.php @@ -0,0 +1,18 @@ +file($os); + } +} diff --git a/app/ServerProviders/AWS.php b/app/ServerProviders/AWS.php new file mode 100755 index 0000000..7a9e75f --- /dev/null +++ b/app/ServerProviders/AWS.php @@ -0,0 +1,223 @@ + 'required|numeric|min:15|max:16000', + 'os' => 'required|in:'.implode(',', OperatingSystem::getValues()), + ]; + // plans + $plans = []; + foreach (config('serverproviders.aws.plans') as $plan) { + $plans[] = $plan['value']; + } + $rules['plan'] = 'required|in:'.implode(',', $plans); + // regions + $regions = []; + foreach (config('serverproviders.aws.regions') as $region) { + $regions[] = $region['value']; + } + $rules['region'] = 'required|in:'.implode(',', $regions); + + return $rules; + } + + public function credentialValidationRules(array $input): array + { + return [ + 'key' => 'required', + 'secret' => 'required', + ]; + } + + public function credentialData(array $input): array + { + return [ + 'key' => $input['key'], + 'secret' => $input['secret'], + ]; + } + + public function data(array $input): array + { + return [ + 'plan' => $input['plan'], + 'region' => $input['region'], + 'size' => $input['size'], + ]; + } + + /** + * @throws CouldNotConnectToProvider + */ + public function connect(array $credentials = null): bool + { + try { + $this->connectToEc2ClientTest($credentials); + $this->ec2Client->describeInstances(); + + return true; + } catch (Exception) { + throw new CouldNotConnectToProvider('AWS'); + } + } + + public function plans(): array + { + return config('serverproviders.aws.plans'); + } + + public function regions(): array + { + return config('serverproviders.aws.regions'); + } + + public function create(): void + { + $this->connectToEc2Client(); + $this->createKeyPair(); + $this->createSecurityGroup(); + $this->runInstance(); + } + + public function isRunning(): bool + { + $this->connectToEc2Client(); + $result = $this->ec2Client->describeInstances([ + 'InstanceIds' => [$this->server->provider_data['instance_id']], + ]); + + if (count($result['Reservations'][0]['Instances']) == 1) { + if (! $this->server->ip && isset($result['Reservations'][0]['Instances'][0]['PublicIpAddress'])) { + $this->server->ip = $result['Reservations'][0]['Instances'][0]['PublicIpAddress']; + $this->server->save(); + } + + if (isset($result['Reservations'][0]['Instances'][0]['State']) && isset($result['Reservations'][0]['Instances'][0]['State']['Name'])) { + $status = $result['Reservations'][0]['Instances'][0]['State']['Name']; + if ($status == 'running') { + return true; + } + } + + Log::info($result); + } + + return false; + } + + public function delete(): void + { + if (isset($this->server->provider_data['instance_id'])) { + try { + $this->connectToEc2Client(); + $this->ec2Client->terminateInstances([ + 'InstanceIds' => [$this->server->provider_data['instance_id']], + ]); + } catch (Exception) { + /** @todo notify */ + // $this->server->team->notify(new FailedToDeleteServerFromProvider($this->server)); + } + } + } + + private function connectToEc2Client(): void + { + $credentials = $this->server->serverProvider->getCredentials(); + + $this->ec2Client = new Ec2Client([ + 'region' => $this->server->provider_data['region'], + 'version' => '2016-11-15', + 'credentials' => [ + 'key' => $credentials['key'], + 'secret' => $credentials['secret'], + ], + ]); + } + + private function connectToEc2ClientTest($credentials): void + { + $this->ec2Client = new Ec2Client([ + 'region' => 'us-east-1', + 'version' => 'latest', + 'credentials' => [ + 'key' => $credentials['key'], + 'secret' => $credentials['secret'], + ], + ]); + } + + private function createKeyPair(): void + { + $keyName = $this->server->name.'-'.$this->server->id; + $result = $this->ec2Client->createKeyPair([ + 'KeyName' => $keyName, + ]); + Storage::disk(config('core.key_pairs_disk'))->put((string) $this->server->id, $result['KeyMaterial']); + generate_public_key( + Storage::disk(config('core.key_pairs_disk'))->path((string) $this->server->id), + Storage::disk(config('core.key_pairs_disk'))->path($this->server->id.'.pub'), + ); + } + + private function createSecurityGroup(): void + { + $groupName = $this->server->name.'-'.$this->server->id; + $result = $this->ec2Client->createSecurityGroup([ + 'GroupId' => $groupName, + 'GroupName' => $groupName, + 'Description' => $groupName, + ]); + $groupId = $result->get('GroupId'); + $this->ec2Client->authorizeSecurityGroupIngress([ + 'GroupName' => $groupName, + 'GroupId' => $groupId, + 'IpPermissions' => [ + [ + 'IpProtocol' => '-1', + 'FromPort' => 0, + 'ToPort' => 65535, + 'IpRanges' => [ + ['CidrIp' => '0.0.0.0/0'], + ], + ], + ], + ]); + } + + private function runInstance(): void + { + $keyName = $groupName = $this->server->name.'-'.$this->server->id; + $result = $this->ec2Client->runInstances([ + 'ImageId' => config('serverproviders.aws.images.'.$this->server->provider_data['region'].'.'.$this->server->os), + 'MinCount' => 1, + 'MaxCount' => 1, + 'InstanceType' => $this->server->provider_data['plan'], + 'KeyName' => $keyName, + 'SecurityGroupIds' => [$groupName], + ]); + $this->server->local_ip = $result['Instances'][0]['PrivateIpAddress']; + $providerData = $this->server->provider_data; + $providerData['instance_id'] = $result['Instances'][0]['InstanceId']; + $providerData['zone'] = $result['Instances'][0]['Placement']['AvailabilityZone']; + $this->server->provider_data = $providerData; + $this->server->save(); + } +} diff --git a/app/ServerProviders/AbstractProvider.php b/app/ServerProviders/AbstractProvider.php new file mode 100755 index 0000000..838fd50 --- /dev/null +++ b/app/ServerProviders/AbstractProvider.php @@ -0,0 +1,22 @@ +server = $server; + } + + protected function generateKeyPair(): void + { + generate_key_pair(Storage::disk(config('core.key_pairs_disk'))->path((string) $this->server->id)); + } +} diff --git a/app/ServerProviders/Custom.php b/app/ServerProviders/Custom.php new file mode 100755 index 0000000..265aae1 --- /dev/null +++ b/app/ServerProviders/Custom.php @@ -0,0 +1,72 @@ + [ + 'required', + 'ip', + Rule::unique('servers', 'ip'), + new RestrictedIPAddressesRule(), + ], + 'port' => [ + 'required', + 'numeric', + 'min:1', + 'max:65535', + ], + ]; + } + + public function credentialValidationRules(array $input): array + { + return []; + } + + public function credentialData(array $input): array + { + return []; + } + + public function data(array $input): array + { + return []; + } + + public function connect(array $credentials = null): bool + { + return true; + } + + public function plans(): array + { + return []; + } + + public function regions(): array + { + return []; + } + + public function create(): void + { + $this->generateKeyPair(); + } + + public function isRunning(): bool + { + return true; + } + + public function delete(): void + { + // + } +} diff --git a/app/ServerProviders/DigitalOcean.php b/app/ServerProviders/DigitalOcean.php new file mode 100644 index 0000000..089bf81 --- /dev/null +++ b/app/ServerProviders/DigitalOcean.php @@ -0,0 +1,158 @@ + 'required|in:'.implode(',', config('core.operating_systems')), + ]; + // plans + $plans = []; + foreach (config('serverproviders.digitalocean.plans') as $plan) { + $plans[] = $plan['value']; + } + $rules['plan'] = 'required|in:'.implode(',', $plans); + // regions + $regions = []; + foreach (config('serverproviders.digitalocean.regions') as $region) { + $regions[] = $region['value']; + } + $rules['region'] = 'required|in:'.implode(',', $regions); + + return $rules; + } + + public function credentialValidationRules(array $input): array + { + return [ + 'token' => 'required', + ]; + } + + public function credentialData(array $input): array + { + return [ + 'token' => $input['token'], + ]; + } + + public function data(array $input): array + { + return [ + 'plan' => $input['plan'], + 'region' => $input['region'], + ]; + } + + /** + * @throws CouldNotConnectToProvider + */ + public function connect(array $credentials = null): bool + { + $connect = Http::withToken($credentials['token'])->get($this->apiUrl.'/account'); + if (! $connect->ok()) { + throw new CouldNotConnectToProvider('DigitalOcean'); + } + + return true; + } + + public function plans(): array + { + return config('serverproviders.digitalocean.plans'); + } + + public function regions(): array + { + return config('serverproviders.digitalocean.regions'); + } + + /** + * @throws ServerProviderError + */ + public function create(): void + { + $this->generateKeyPair(); + + $createSshKey = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/account/keys', [ + 'public_key' => $this->server->sshKey()['public_key'], + 'name' => str($this->server->name)->slug().'-'.$this->server->id, + ]); + if ($createSshKey->status() != 201) { + throw new ServerProviderError('DigitalOcean SSH Key'); + } + + $create = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/droplets', [ + 'name' => str($this->server->name)->slug(), + 'region' => $this->server->provider_data['region'], + 'size' => $this->server->provider_data['plan'], + 'image' => config('serverproviders.digitalocean.images')[$this->server->os], + 'backups' => false, + 'ipv6' => false, + 'monitoring' => false, + 'ssh_keys' => [$createSshKey->json()['ssh_key']['id']], + ]); + if ($create->status() != 202) { + $msg = __('Failed to create server on DigitalOcean'); + Log::error('Failed to create server on DigitalOcean', $create->json()); + throw new ServerProviderError($msg); + } + $providerData = $this->server->provider_data; + $providerData['droplet_id'] = $create->json()['droplet']['id']; + $this->server->provider_data = $providerData; + $this->server->save(); + } + + public function isRunning(): bool + { + $status = Http::withToken($this->server->serverProvider->credentials['token']) + ->get($this->apiUrl.'/droplets/'.$this->server->provider_data['droplet_id']); + + if (! $status->ok()) { + return false; + } + + if (! $this->server->ip && count($status->json()['droplet']['networks']['v4']) > 0) { + foreach ($status->json()['droplet']['networks']['v4'] as $v4) { + if ($v4['type'] == 'public') { + $this->server->ip = $v4['ip_address']; + } else { + $this->server->local_ip = $v4['ip_address']; + } + } + $this->server->save(); + } + + return $status->json()['droplet']['status'] == 'active'; + } + + /** + * @throws Exception + */ + public function delete(): void + { + if (isset($this->server->provider_data['droplet_id'])) { + $delete = Http::withToken($this->server->serverProvider->credentials['token']) + ->delete($this->apiUrl.'/droplets/'.$this->server->provider_data['droplet_id']); + + /** @todo notify */ + // if (! $delete->ok()) { + // $this->server->team->notify(new FailedToDeleteServerFromProvider($this->server)); + // } + } + } +} diff --git a/app/ServerProviders/Hetzner.php b/app/ServerProviders/Hetzner.php new file mode 100644 index 0000000..3df9e63 --- /dev/null +++ b/app/ServerProviders/Hetzner.php @@ -0,0 +1,146 @@ + 'required|in:'.implode(',', config('core.operating_systems')), + 'plan' => 'required', + 'region' => 'required', + ]; + } + + public function credentialValidationRules(array $input): array + { + return [ + 'token' => 'required', + ]; + } + + public function credentialData(array $input): array + { + return [ + 'token' => $input['token'], + ]; + } + + public function data(array $input): array + { + return [ + 'plan' => $input['plan'], + 'region' => $input['region'], + ]; + } + + /** + * @throws CouldNotConnectToProvider + */ + public function connect(array $credentials = null): bool + { + $connect = Http::withToken($credentials['token'])->get($this->apiUrl.'/servers'); + if (! $connect->ok()) { + throw new CouldNotConnectToProvider('Hetzner'); + } + + return true; + } + + public function plans(): array + { + return config('serverproviders.hetzner.plans'); + } + + public function regions(): array + { + return config('serverproviders.hetzner.regions'); + } + + /** + * @throws ServerProviderError + */ + public function create(): void + { + $this->generateKeyPair(); + + $sshKey = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/ssh_keys', [ + 'name' => 'server-'.$this->server->id.'-key', + 'public_key' => $this->server->sshKey()['public_key'], + ]); + + if ($sshKey->status() != 201) { + $this->providerError($sshKey); + } + + $this->server->jsonUpdate('provider_data', 'ssh_key_id', $sshKey->json()['ssh_key']['id']); + + $create = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/servers', [ + 'automount' => false, + 'image' => config('serverproviders.hetzner.images')[$this->server->os], + // 'root_password' => $this->server->authentication['root_pass'], + 'ssh_keys' => [ + $sshKey->json()['ssh_key']['id'], + ], + 'name' => str($this->server->name)->slug(), + 'location' => $this->server->provider_data['region'], + 'server_type' => $this->server->provider_data['plan'], + ]); + if ($create->status() != 201) { + $this->providerError($create); + } + $this->server->jsonUpdate('provider_data', 'hetzner_id', $create->json()['server']['id'], false); + $this->server->ip = $create->json()['server']['public_net']['ipv4']['ip']; + $this->server->save(); + } + + public function isRunning(): bool + { + $status = Http::withToken($this->server->serverProvider->credentials['token']) + ->get($this->apiUrl.'/servers/'.$this->server->provider_data['hetzner_id']); + + if (! $status->ok()) { + return false; + } + + return $status->json()['server']['status'] == 'running'; + } + + public function delete(): void + { + if (isset($this->server->provider_data['hetzner_id'])) { + $delete = Http::withToken($this->server->serverProvider->credentials['token']) + ->delete($this->apiUrl.'/servers/'.$this->server->provider_data['hetzner_id']); + + /** @todo notify */ + // if (! $delete->ok()) { + // $this->server->team->notify(new FailedToDeleteServerFromProvider($this->server)); + // } + } + + // delete key + if (isset($this->server->provider_data['ssh_key_id'])) { + Http::withToken($this->server->serverProvider->credentials['token']) + ->delete($this->apiUrl.'/ssh_keys/'.$this->server->provider_data['ssh_key_id']); + } + } + + /** + * @throws ServerProviderError + */ + private function providerError(Response $response): void + { + throw new ServerProviderError($response->json('error')['message']); + } +} diff --git a/app/ServerProviders/Linode.php b/app/ServerProviders/Linode.php new file mode 100644 index 0000000..dbdbafb --- /dev/null +++ b/app/ServerProviders/Linode.php @@ -0,0 +1,139 @@ + 'required|in:'.implode(',', config('core.operating_systems')), + ]; + // plans + $plans = []; + foreach (config('serverproviders.linode.plans') as $plan) { + $plans[] = $plan['value']; + } + $rules['plan'] = 'required|in:'.implode(',', $plans); + // regions + $regions = []; + foreach (config('serverproviders.linode.regions') as $region) { + $regions[] = $region['value']; + } + $rules['region'] = 'required|in:'.implode(',', $regions); + + return $rules; + } + + public function credentialValidationRules($input): array + { + return [ + 'token' => 'required', + ]; + } + + public function credentialData($input): array + { + return [ + 'token' => $input['token'], + ]; + } + + public function data(array $input): array + { + return [ + 'plan' => $input['plan'], + 'region' => $input['region'], + ]; + } + + /** + * @throws CouldNotConnectToProvider + */ + public function connect(array $credentials = null): bool + { + $connect = Http::withToken($credentials['token'])->get($this->apiUrl.'/account'); + if (! $connect->ok()) { + throw new CouldNotConnectToProvider('Linode'); + } + + return true; + } + + public function plans(): array + { + return config('serverproviders.linode.plans'); + } + + public function regions(): array + { + return config('serverproviders.linode.regions'); + } + + /** + * @throws ServerProviderError + */ + public function create(): void + { + $this->generateKeyPair(); + + $create = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/linode/instances', [ + 'backups_enabled' => false, + 'image' => config('serverproviders.linode.images')[$this->server->os], + 'root_pass' => $this->server->authentication['root_pass'], + 'authorized_keys' => [ + $this->server->sshKey()['public_key'], + ], + 'booted' => true, + 'label' => str($this->server->name)->slug(), + 'type' => $this->server->provider_data['plan'], + 'region' => $this->server->provider_data['region'], + ]); + if (! $create->ok()) { + $msg = __('Failed to create server on Linode'); + $errors = $create->json('errors'); + if (count($errors) > 0) { + $msg = $errors[0]['reason']; + } + throw new ServerProviderError($msg); + } + $this->server->ip = $create->json()['ipv4'][0]; + $providerData = $this->server->provider_data; + $providerData['linode_id'] = $create->json()['id']; + $this->server->provider_data = $providerData; + $this->server->save(); + } + + public function isRunning(): bool + { + $status = Http::withToken($this->server->serverProvider->credentials['token']) + ->get($this->apiUrl.'/linode/instances/'.$this->server->provider_data['linode_id']); + + if (! $status->ok()) { + return false; + } + + return $status->json()['status'] == 'running'; + } + + public function delete(): void + { + if (isset($this->server->provider_data['linode_id'])) { + $delete = Http::withToken($this->server->serverProvider->credentials['token']) + ->delete($this->apiUrl.'/linode/instances/'.$this->server->provider_data['linode_id']); + + /** @todo notify */ + // if (! $delete->ok()) { + // $this->server->team->notify(new FailedToDeleteServerFromProvider($this->server)); + // } + } + } +} diff --git a/app/ServerProviders/Vultr.php b/app/ServerProviders/Vultr.php new file mode 100644 index 0000000..2e89e1f --- /dev/null +++ b/app/ServerProviders/Vultr.php @@ -0,0 +1,152 @@ + 'required|in:'.implode(',', config('core.operating_systems')), + ]; + // plans + $plans = []; + foreach (config('serverproviders.vultr.plans') as $plan) { + $plans[] = $plan['value']; + } + $rules['plan'] = 'required|in:'.implode(',', $plans); + // regions + $regions = []; + foreach (config('serverproviders.vultr.regions') as $region) { + $regions[] = $region['value']; + } + $rules['region'] = 'required|in:'.implode(',', $regions); + + return $rules; + } + + public function credentialValidationRules($input): array + { + return [ + 'token' => 'required', + ]; + } + + public function credentialData($input): array + { + return [ + 'token' => $input['token'], + ]; + } + + public function data(array $input): array + { + return [ + 'plan' => $input['plan'], + 'region' => $input['region'], + ]; + } + + /** + * @throws CouldNotConnectToProvider + */ + public function connect(array $credentials = null): bool + { + $connect = Http::withToken($credentials['token'])->get($this->apiUrl.'/account'); + if (! $connect->ok()) { + throw new CouldNotConnectToProvider('Vultr'); + } + + return true; + } + + public function plans(): array + { + return config('serverproviders.vultr.plans'); + } + + public function regions(): array + { + return config('serverproviders.vultr.regions'); + } + + /** + * @throws ServerProviderError + */ + public function create(): void + { + // generate key pair + generate_key_pair(Storage::disk(config('core.key_pairs_disk'))->path((string) $this->server->id)); + + $createSshKey = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/ssh-keys', [ + 'ssh_key' => $this->server->sshKey()['public_key'], + 'name' => $this->server->name.'_'.$this->server->id, + ]); + if ($createSshKey->status() != 201) { + throw new ServerProviderError('Error creating SSH Key on Vultr'); + } + + $create = Http::withToken($this->server->serverProvider->credentials['token']) + ->post($this->apiUrl.'/instances', [ + 'label' => $this->server->name, + 'region' => $this->server->provider_data['region'], + 'plan' => $this->server->provider_data['plan'], + 'os_id' => config('serverproviders.vultr.images')[$this->server->os], + 'enable_ipv6' => false, + 'sshkey_id' => [$createSshKey->json()['ssh_key']['id']], + ]); + if ($create->status() != 202) { + $msg = __('Failed to create server on Vultr'); + Log::error('Failed to create server on Vultr', $create->json()); + throw new ServerProviderError($msg); + } + $providerData = $this->server->provider_data; + $providerData['instance_id'] = $create->json()['instance']['id']; + $this->server->provider_data = $providerData; + $this->server->save(); + } + + public function isRunning(): bool + { + $status = Http::withToken($this->server->serverProvider->credentials['token']) + ->get($this->apiUrl.'/instances/'.$this->server->provider_data['instance_id']); + + if (! $status->ok()) { + return false; + } + + if (! $this->server->ip) { + $this->server->ip = $status->json()['instance']['main_ip']; + $this->server->save(); + } + + return $status->json()['instance']['status'] == 'active'; + } + + /** + * @throws Exception + */ + public function delete(): void + { + if (isset($this->server->provider_data['instance_id'])) { + $delete = Http::withToken($this->server->serverProvider->credentials['token']) + ->delete($this->apiUrl.'/instances/'.$this->server->provider_data['instance_id']); + + /** @todo notify */ + // if (! $delete->ok()) { + // $this->server->team->notify(new FailedToDeleteServerFromProvider($this->server)); + // } + } + } +} diff --git a/app/ServerTypes/AbstractType.php b/app/ServerTypes/AbstractType.php new file mode 100755 index 0000000..02e6b38 --- /dev/null +++ b/app/ServerTypes/AbstractType.php @@ -0,0 +1,32 @@ +server = $server; + } + + protected function progress(int $percentage, string $step = null): Closure + { + return function () use ($percentage, $step) { + $this->server->progress = $percentage; + $this->server->progress_step = $step; + $this->server->save(); + event(new Broadcast('server-installation-progress', [ + 'server' => $this->server, + 'step' => $step, + 'percentage' => $percentage, + ])); + }; + } +} diff --git a/app/ServerTypes/Regular.php b/app/ServerTypes/Regular.php new file mode 100755 index 0000000..6d5e9d5 --- /dev/null +++ b/app/ServerTypes/Regular.php @@ -0,0 +1,184 @@ + [ + 'required', + 'in:'.implode(',', config('core.webservers')), + ], + 'php' => [ + 'required', + 'in:'.implode(',', config('core.php_versions')), + ], + 'database' => [ + 'required', + 'in:'.implode(',', config('core.databases')), + ], + ]; + } + + public function data(array $input): array + { + return []; + } + + public function createServices(array $input): void + { + $this->server->services()->forceDelete(); + + $this->addWebserver($input['webserver']); + $this->addDatabase($input['database']); + $this->addPHP($input['php']); + $this->addSupervisor(); + $this->addRedis(); + $this->addUfw(); + } + + public function install(): void + { + $jobs = [ + new Initialize($this->server, $this->server->ssh_user, $this->server->provider === 'custom'), + $this->progress(15, 'Installing Updates'), + new Upgrade($this->server), + $this->progress(25, 'Installing Requirements'), + new InstallRequirements($this->server), + $this->progress(35, 'Installing Node.js'), + new InstallNodejs($this->server), + $this->progress(45, 'Installing Certbot'), + new InstallCertbot($this->server), + ]; + + $services = $this->server->services; + $currentProgress = 45; + $progressPerService = (100 - $currentProgress) / count($services); + foreach ($services as $service) { + $currentProgress += $progressPerService; + $jobs[] = $this->progress($currentProgress, 'Installing '.$service->name); + $jobs[] = $service->installer(); + if ($service->type == 'php') { + $jobs[] = $this->progress($currentProgress, 'Installing Composer'); + $jobs[] = new InstallComposer($this->server); + } + } + + $jobs[] = function () { + $this->server->update([ + 'status' => 'ready', + 'progress' => 100, + ]); + event( + new Broadcast('install-server-finished', [ + 'server' => $this->server, + ]) + ); + /** @todo notify */ + }; + + Bus::chain($jobs) + ->catch(function (Throwable $e) { + $this->server->update([ + 'status' => 'installation_failed', + ]); + event( + new Broadcast('install-server-failed', [ + 'server' => $this->server, + ]) + ); + /** @todo notify */ + Log::error('server-installation-error', [ + 'error' => (string) $e, + ]); + throw $e; + }) + ->onConnection('ssh-long') + ->dispatch(); + } + + protected function addWebserver(string $service): void + { + if ($service != 'none') { + $this->server->services()->create([ + 'type' => 'webserver', + 'name' => $service, + 'version' => 'latest', + ]); + } + } + + protected function addDatabase(string $service): void + { + if ($service != 'none') { + $this->server->services()->create([ + 'type' => 'database', + 'name' => config('core.databases_name.'.$service), + 'version' => config('core.databases_version.'.$service), + ]); + } + } + + protected function addPHP(string $version): void + { + if ($version != 'none') { + $this->server->services()->create([ + 'type' => 'php', + 'type_data' => [ + 'extensions' => [], + ], + 'name' => 'php', + 'version' => $version, + ]); + } + } + + /** + * add supervisor + */ + protected function addSupervisor(): void + { + $this->server->services()->create([ + 'type' => 'process_manager', + 'name' => 'supervisor', + 'version' => 'latest', + ]); + } + + /** + * add supervisor + */ + protected function addRedis(): void + { + $this->server->services()->create([ + 'type' => 'memory_database', + 'name' => 'redis', + 'version' => 'latest', + ]); + } + + /** + * add supervisor + */ + protected function addUfw(): void + { + $this->server->services()->create([ + 'type' => 'firewall', + 'name' => 'ufw', + 'version' => 'latest', + ]); + } +} diff --git a/app/ServiceHandlers/Database/AbstractDatabase.php b/app/ServiceHandlers/Database/AbstractDatabase.php new file mode 100755 index 0000000..8234f7c --- /dev/null +++ b/app/ServiceHandlers/Database/AbstractDatabase.php @@ -0,0 +1,16 @@ +service = $service; + } +} diff --git a/app/ServiceHandlers/Database/Mysql.php b/app/ServiceHandlers/Database/Mysql.php new file mode 100755 index 0000000..b7bbe8b --- /dev/null +++ b/app/ServiceHandlers/Database/Mysql.php @@ -0,0 +1,138 @@ +service->server->ssh()->exec( + new CreateCommand('mysql', $name), + 'create-database' + ); + } + + /** + * @throws Throwable + */ + public function delete(string $name): void + { + $this->service->server->ssh()->exec( + new DeleteCommand('mysql', $name), + 'delete-database' + ); + } + + /** + * @throws Throwable + */ + public function createUser(string $username, string $password, string $host): void + { + $this->service->server->ssh()->exec( + new CreateUserCommand('mysql', $username, $password, $host), + 'create-user' + ); + } + + /** + * @throws Throwable + */ + public function deleteUser(string $username, string $host): void + { + $this->service->server->ssh()->exec( + new DeleteUserCommand('mysql', $username, $host), + 'delete-user' + ); + } + + /** + * @throws Throwable + */ + public function link(string $username, string $host, array $databases): void + { + $ssh = $this->service->server->ssh(); + foreach ($databases as $database) { + $ssh->exec( + new LinkCommand('mysql', $username, $host, $database), + 'link-user-to-databases' + ); + } + } + + /** + * @throws Throwable + */ + public function unlink(string $username, string $host): void + { + $this->service->server->ssh()->exec( + new UnlinkCommand('mysql', $username, $host), + 'unlink-user-from-database' + ); + } + + /** + * @throws Throwable + */ + public function runBackup(BackupFile $backupFile): void + { + // backup + $this->service->server->ssh()->exec( + new BackupDatabaseCommand( + 'mysql', + $backupFile->backup->database->name, + $backupFile->name + ), + 'backup-database' + ); + + // upload to cloud + $upload = $backupFile->backup->storage->provider()->upload( + $backupFile->backup->server, + $backupFile->path, + $backupFile->storage_path, + ); + + // cleanup + $this->service->server->ssh()->exec('rm '.$backupFile->name.'.zip'); + + $backupFile->size = $upload['size']; + $backupFile->save(); + } + + /** + * @throws Throwable + */ + public function restoreBackup(BackupFile $backupFile, string $database): void + { + // download + $backupFile->backup->storage->provider()->download( + $backupFile->backup->server, + $backupFile->storage_path, + $backupFile->name.'.zip', + ); + + // restore + $this->service->server->ssh()->exec( + new RestoreDatabaseCommand( + 'mysql', + $database, + $backupFile->name + ), + 'restore-database' + ); + } +} diff --git a/app/ServiceHandlers/Firewall/AbstractFirewall.php b/app/ServiceHandlers/Firewall/AbstractFirewall.php new file mode 100755 index 0000000..a10673a --- /dev/null +++ b/app/ServiceHandlers/Firewall/AbstractFirewall.php @@ -0,0 +1,16 @@ +service = $service; + } +} diff --git a/app/ServiceHandlers/Firewall/Ufw.php b/app/ServiceHandlers/Firewall/Ufw.php new file mode 100755 index 0000000..30dea50 --- /dev/null +++ b/app/ServiceHandlers/Firewall/Ufw.php @@ -0,0 +1,32 @@ +service->server->ssh()->exec( + new AddRuleCommand('ufw', $type, $protocol, $port, $source, $mask), + 'add-firewall-rule' + ); + } + + /** + * @throws Throwable + */ + public function removeRule(string $type, string $protocol, int $port, string $source, string $mask): void + { + $this->service->server->ssh()->exec( + new RemoveRuleCommand('ufw', $type, $protocol, $port, $source, $mask), + 'remove-firewall-rule' + ); + } +} diff --git a/app/ServiceHandlers/PHP.php b/app/ServiceHandlers/PHP.php new file mode 100644 index 0000000..471debd --- /dev/null +++ b/app/ServiceHandlers/PHP.php @@ -0,0 +1,36 @@ +service = $service; + } + + public function setDefaultCli(): void + { + $this->service->update(['status' => ServiceStatus::RESTARTING]); + + dispatch(new SetDefaultCli($this->service))->onConnection('ssh'); + } + + public function installExtension($name): void + { + dispatch(new InstallPHPExtension($this->service, $name))->onConnection('ssh-long'); + } + + public function updateSettings(array $settings): void + { + dispatch(new UpdatePHPSettings($this->service, $settings))->onConnection('ssh-long'); + } +} diff --git a/app/ServiceHandlers/ProcessManager/AbstractProcessManager.php b/app/ServiceHandlers/ProcessManager/AbstractProcessManager.php new file mode 100644 index 0000000..d72c24c --- /dev/null +++ b/app/ServiceHandlers/ProcessManager/AbstractProcessManager.php @@ -0,0 +1,16 @@ +service = $service; + } +} diff --git a/app/ServiceHandlers/ProcessManager/Supervisor.php b/app/ServiceHandlers/ProcessManager/Supervisor.php new file mode 100644 index 0000000..3501085 --- /dev/null +++ b/app/ServiceHandlers/ProcessManager/Supervisor.php @@ -0,0 +1,124 @@ +service->server->ssh($user)->exec( + new CreateWorkerCommand( + $id, + $this->generateConfigFile( + $id, + $command, + $user, + $autoStart, + $autoRestart, + $numprocs, + $logFile + ) + ), + 'create-worker', + $siteId + ); + } + + /** + * @throws Throwable + */ + public function delete(int $id, int $siteId = null): void + { + $this->service->server->ssh()->exec( + new DeleteWorkerCommand($id), + 'delete-worker', + $siteId + ); + } + + /** + * @throws Throwable + */ + public function restart(int $id, int $siteId = null): void + { + $this->service->server->ssh()->exec( + new RestartWorkerCommand($id), + 'restart-worker', + $siteId + ); + } + + /** + * @throws Throwable + */ + public function stop(int $id, int $siteId = null): void + { + $this->service->server->ssh()->exec( + new StopWorkerCommand($id), + 'stop-worker', + $siteId + ); + } + + /** + * @throws Throwable + */ + public function start(int $id, int $siteId = null): void + { + $this->service->server->ssh()->exec( + new StartWorkerCommand($id), + 'start-worker', + $siteId + ); + } + + /** + * @throws Throwable + */ + public function getLogs(string $logPath): string + { + return $this->service->server->ssh()->exec( + "tail -100 $logPath" + ); + } + + private function generateConfigFile( + int $id, + string $command, + string $user, + bool $autoStart, + bool $autoRestart, + int $numprocs, + string $logFile + ): string { + $config = File::get(base_path('system/command-templates/supervisor/worker.conf')); + $config = Str::replace('__name__', (string) $id, $config); + $config = Str::replace('__command__', $command, $config); + $config = Str::replace('__user__', $user, $config); + $config = Str::replace('__auto_start__', var_export($autoStart, true), $config); + $config = Str::replace('__auto_restart__', var_export($autoRestart, true), $config); + $config = Str::replace('__numprocs__', (string) $numprocs, $config); + + return Str::replace('__log_file__', $logFile, $config); + } +} diff --git a/app/ServiceHandlers/Webserver/AbstractWebserver.php b/app/ServiceHandlers/Webserver/AbstractWebserver.php new file mode 100755 index 0000000..b194ff1 --- /dev/null +++ b/app/ServiceHandlers/Webserver/AbstractWebserver.php @@ -0,0 +1,16 @@ +service = $service; + } +} diff --git a/app/ServiceHandlers/Webserver/Nginx.php b/app/ServiceHandlers/Webserver/Nginx.php new file mode 100755 index 0000000..0a0ce22 --- /dev/null +++ b/app/ServiceHandlers/Webserver/Nginx.php @@ -0,0 +1,194 @@ +service->server->ssh()->exec( + new CreateNginxVHostCommand( + $site->domain, + $site->path, + $this->generateVhost($site) + ), + 'create-vhost', + $site->id + ); + } + + /** + * @throws Throwable + */ + public function updateVHost(Site $site, bool $noSSL = false): void + { + $this->service->server->ssh()->exec( + new UpdateNginxVHostCommand( + $site->domain, + $site->path, + $this->generateVhost($site, $noSSL) + ), + 'update-vhost', + $site->id + ); + } + + /** + * @throws Throwable + */ + public function deleteSite(Site $site): void + { + $this->service->server->ssh()->exec( + new DeleteNginxSiteCommand( + $site->domain, + $site->path + ), + 'delete-site', + $site->id + ); + $this->service->restart(); + } + + /** + * @throws Throwable + */ + public function changePHPVersion(Site $site, $version): void + { + $this->service->server->ssh()->exec( + new ChangeNginxPHPVersionCommand($site->domain, $site->php_version, $version), + 'change-php-version', + $site->id + ); + } + + /** + * @throws Throwable + */ + public function setupSSL(Ssl $ssl): void + { + $command = new CreateLetsencryptSSLCommand( + $ssl->site->server->creator->email, + $ssl->site->domain, + $ssl->site->web_directory_path + ); + if ($ssl->type == 'custom') { + $command = new CreateCustomSSLCommand( + $ssl->certs_directory_path, + $ssl->certificate, + $ssl->pk, + $ssl->certificate_path, + $ssl->pk_path, + ); + } + $result = $this->service->server->ssh()->exec( + $command, + 'create-ssl', + $ssl->site_id + ); + if (! $ssl->validateSetup($result)) { + throw new SSLCreationException(); + } + + $this->updateVHost($ssl->site); + } + + /** + * @throws Throwable + */ + public function removeSSL(Ssl $ssl): void + { + $this->service->server->ssh()->exec( + new RemoveSSLCommand($ssl->certs_directory_path), + 'remove-ssl', + $ssl->site_id + ); + + $this->updateVHost($ssl->site, true); + } + + /** + * @throws Throwable + */ + public function updateRedirects(Site $site, array $redirects): void + { + $redirectsPlain = ''; + foreach ($redirects as $redirect) { + $rd = File::get(base_path('system/command-templates/nginx/redirect.conf')); + $rd = Str::replace('__from__', $redirect->from, $rd); + $rd = Str::replace('__mode__', $redirect->mode, $rd); + $rd = Str::replace('__to__', $redirect->to, $rd); + $redirectsPlain .= $rd."\n"; + } + $result = $this->service->server->ssh()->exec( + new UpdateNginxRedirectsCommand( + $site->domain, + $redirectsPlain, + ), + 'update-redirects', + $site->id + ); + if (Str::contains($result, 'journalctl -xe')) { + throw new ErrorUpdatingRedirects(); + } + } + + protected function generateVhost(Site $site, bool $noSSL = false): string + { + $ssl = $site->activeSsl; + if ($noSSL) { + $ssl = null; + } + $vhost = File::get(base_path('system/command-templates/nginx/vhost.conf')); + if ($ssl) { + $vhost = File::get(base_path('system/command-templates/nginx/vhost-ssl.conf')); + } + if ($site->type()->language() === 'php') { + $vhost = File::get(base_path('system/command-templates/nginx/php-vhost.conf')); + if ($ssl) { + $vhost = File::get(base_path('system/command-templates/nginx/php-vhost-ssl.conf')); + } + } + if ($site->port) { + $vhost = File::get(base_path('system/command-templates/nginx/reverse-vhost.conf')); + if ($ssl) { + $vhost = File::get(base_path('system/command-templates/nginx/reverse-vhost-ssl.conf')); + } + $vhost = Str::replace('__port__', (string) $site->port, $vhost); + } + + $vhost = Str::replace('__domain__', $site->domain, $vhost); + $vhost = Str::replace('__aliases__', $site->aliases_string, $vhost); + $vhost = Str::replace('__path__', $site->path, $vhost); + $vhost = Str::replace('__web_directory__', $site->web_directory, $vhost); + + if ($ssl) { + $vhost = Str::replace('__certificate__', $ssl->certificate_path, $vhost); + $vhost = Str::replace('__private_key__', $ssl->pk_path, $vhost); + } + + if ($site->php_version) { + $vhost = Str::replace('__php_version__', $site->php_version, $vhost); + } + + return $vhost; + } +} diff --git a/app/SiteTypes/AbstractSiteType.php b/app/SiteTypes/AbstractSiteType.php new file mode 100755 index 0000000..22a29a8 --- /dev/null +++ b/app/SiteTypes/AbstractSiteType.php @@ -0,0 +1,38 @@ +site = $site; + } + + public function delete(): void + { + dispatch(new DeleteSite($this->site))->onConnection('ssh'); + } + + protected function progress(int $percentage): Closure + { + return function () use ($percentage) { + $this->site->progress = $percentage; + $this->site->save(); + event( + new Broadcast('site-installation-progress', [ + 'site' => $this->site, + 'percentage' => $percentage, + ]) + ); + }; + } +} diff --git a/app/SiteTypes/Laravel.php b/app/SiteTypes/Laravel.php new file mode 100755 index 0000000..3891aad --- /dev/null +++ b/app/SiteTypes/Laravel.php @@ -0,0 +1,7 @@ + [ + 'required', + 'in:'.implode(',', $this->site->server->installedPHPVersions()), + ], + 'source_control' => [ + 'required', + Rule::exists('source_controls', 'provider'), + ], + 'repository' => [ + 'required', + ], + 'branch' => [ + 'required', + ], + ]; + } + + public function createFields(array $input): array + { + return [ + 'web_directory' => $input['web_directory'] ?? '', + 'source_control' => $input['source_control'] ?? '', + 'repository' => $input['repository'] ?? '', + 'branch' => $input['branch'] ?? '', + ]; + } + + public function data(array $input): array + { + return [ + 'composer' => (bool) $input['composer'], + ]; + } + + public function install(): void + { + $chain = [ + new CreateVHost($this->site), + $this->progress(30), + new CloneRepository($this->site), + $this->progress(65), + function () { + $this->site->php()?->restart(); + }, + ]; + + if ($this->site->type_data['composer']) { + $chain[] = new ComposerInstall($this->site); + } + + $chain[] = function () { + $this->site->update([ + 'status' => SiteStatus::READY, + 'progress' => 100, + ]); + event( + new Broadcast('install-site-finished', [ + 'site' => $this->site, + ]) + ); + /** @todo notify */ + }; + + Bus::chain($chain) + ->catch(function (Throwable $e) { + $this->site->update([ + 'status' => SiteStatus::INSTALLATION_FAILED, + ]); + event( + new Broadcast('install-site-failed', [ + 'site' => $this->site, + ]) + ); + /** @todo notify */ + Log::error('install-site-error', [ + 'error' => (string) $e, + ]); + throw $e; + }) + ->onConnection('ssh-long') + ->dispatch(); + } + + public function editValidationRules(array $input): array + { + return []; + } + + public function edit(): void + { + // + } +} diff --git a/app/SiteTypes/Wordpress.php b/app/SiteTypes/Wordpress.php new file mode 100755 index 0000000..a01e477 --- /dev/null +++ b/app/SiteTypes/Wordpress.php @@ -0,0 +1,172 @@ + 'required', + 'username' => 'required', + 'password' => 'required', + 'email' => 'required|email', + 'database' => 'required', + 'database_user' => 'required', + ]; + } + + public function createFields(array $input): array + { + return [ + 'web_directory' => $input['web_directory'] ?? '', + ]; + } + + public function data(array $input): array + { + $data = $this->site->type_data; + $data['url'] = $this->site->url; + if (isset($input['title']) && $input['title']) { + $data['title'] = $input['title']; + } + if (isset($input['username']) && $input['username']) { + $data['username'] = $input['username']; + } + if (isset($input['email']) && $input['email']) { + $data['email'] = $input['email']; + } + if (isset($input['password']) && $input['password']) { + $data['password'] = $input['password']; + } + if (isset($input['database']) && $input['database']) { + $data['database'] = $input['database']; + } + if (isset($input['database_user']) && $input['database_user']) { + $data['database_user'] = $input['database_user']; + } + if (isset($input['url']) && $input['url']) { + $data['url'] = $input['url']; + } + + return $data; + } + + public function install(): void + { + $chain = [ + new CreateVHost($this->site), + $this->progress(30), + new InstallWordpress($this->site), + $this->progress(65), + function () { + $this->site->php()?->restart(); + }, + ]; + + $chain[] = function () { + $this->site->update([ + 'status' => SiteStatus::READY, + 'progress' => 100, + ]); + event( + new Broadcast('install-site-finished', [ + 'site' => $this->site, + ]) + ); + /** @todo notify */ + }; + + Bus::chain($chain) + ->catch(function (Throwable $e) { + $this->site->update([ + 'status' => SiteStatus::INSTALLATION_FAILED, + ]); + event( + new Broadcast('install-site-failed', [ + 'site' => $this->site, + ]) + ); + /** @todo notify */ + Log::error('install-site-error', [ + 'error' => (string) $e, + ]); + throw $e; + }) + ->onConnection('ssh-long') + ->dispatch(); + } + + public function editValidationRules(array $input): array + { + return [ + 'title' => 'required', + 'url' => 'required', + // 'email' => 'required|email', + ]; + } + + public function edit(): void + { + $this->site->status = 'installing'; + $this->site->progress = 90; + $this->site->save(); + $chain = [ + function () { + $this->site->server->ssh()->exec( + new UpdateWordpressCommand( + $this->site->path, + $this->site->type_data['url'], + $this->site->type_data['username'] ?? '', + $this->site->type_data['password'] ?? '', + $this->site->type_data['email'] ?? '', + $this->site->type_data['title'] ?? '', + ), + 'update-wordpress', + $this->site->id + ); + $this->site->update([ + 'status' => SiteStatus::READY, + ]); + event( + new Broadcast('install-site-finished', [ + 'site' => $this->site, + ]) + ); + }, + ]; + + Bus::chain($chain) + ->catch(function (Throwable $e) { + $this->site->update([ + 'status' => SiteStatus::INSTALLATION_FAILED, + ]); + event( + new Broadcast('install-site-failed', [ + 'site' => $this->site, + ]) + ); + /** @todo notify */ + Log::error('install-site-error', [ + 'error' => (string) $e, + ]); + throw $e; + }) + ->onConnection('ssh') + ->dispatch(); + } +} diff --git a/app/SourceControlProviders/AbstractSourceControlProvider.php b/app/SourceControlProviders/AbstractSourceControlProvider.php new file mode 100755 index 0000000..86f1087 --- /dev/null +++ b/app/SourceControlProviders/AbstractSourceControlProvider.php @@ -0,0 +1,40 @@ +sourceControl = $sourceControl; + } + + /** + * @throws SourceControlIsNotConnected + * @throws RepositoryNotFound + * @throws RepositoryPermissionDenied + */ + protected function handleResponseErrors(Response $res, string $repo): void + { + if ($res->status() == 401) { + throw new SourceControlIsNotConnected($this->sourceControl); + } + + if ($res->status() == 404) { + throw new RepositoryNotFound($repo); + } + + if ($res->status() == 403) { + throw new RepositoryPermissionDenied($repo); + } + } +} diff --git a/app/SourceControlProviders/Bitbucket.php b/app/SourceControlProviders/Bitbucket.php new file mode 100755 index 0000000..fafac2b --- /dev/null +++ b/app/SourceControlProviders/Bitbucket.php @@ -0,0 +1,114 @@ +sourceControl->access_token) + ->get($this->apiUrl.'/repositories'); + + return $res->successful(); + } + + /** + * @throws Exception + */ + public function getRepo(string $repo = null): mixed + { + $res = Http::withToken($this->sourceControl->access_token) + ->get($this->apiUrl."/repositories/$repo"); + + $this->handleResponseErrors($res, $repo); + + return $res->json(); + } + + public function fullRepoUrl(string $repo): string + { + return "https://x-token-auth:{$this->sourceControl->access_token}@bitbucket.org/$repo.git"; + } + + /** + * @throws FailedToDeployGitHook + */ + public function deployHook(string $repo, array $events, string $secret): array + { + $response = Http::withToken($this->sourceControl->access_token)->post($this->apiUrl."/repositories/$repo/hooks", [ + 'description' => 'deploy', + 'url' => url('/git-hooks?secret='.$secret), + 'events' => [ + 'repo:'.implode(',', $events), + ], + 'active' => true, + ]); + + if ($response->status() != 201) { + throw new FailedToDeployGitHook($response->json()['error']['message']); + } + + return [ + 'hook_id' => json_decode($response->body())->uuid, + 'hook_response' => json_decode($response->body()), + ]; + } + + /** + * @throws FailedToDestroyGitHook + */ + public function destroyHook(string $repo, string $hookId): void + { + $hookId = urlencode($hookId); + $response = Http::withToken($this->sourceControl->access_token)->delete($this->apiUrl."/repositories/$repo/hooks/$hookId"); + + if ($response->status() != 204) { + throw new FailedToDestroyGitHook('Error'); + } + } + + /** + * @throws Exception + */ + public function getLastCommit(string $repo, string $branch): ?array + { + $res = Http::withToken($this->sourceControl->access_token) + ->get($this->apiUrl."/repositories/$repo/commits?include=".$branch); + + $this->handleResponseErrors($res, $repo); + + $commits = $res->json(); + + if (isset($commits['values']) && count($commits['values']) > 0) { + return [ + 'commit_id' => $commits['values'][0]['hash'], + 'commit_data' => [ + 'name' => $this->getCommitter($commits['values'][0]['author']['raw'])['name'] ?? null, + 'email' => $this->getCommitter($commits['values'][0]['author']['raw'])['email'] ?? null, + 'message' => str_replace("\n", '', $commits['values'][0]['message']), + 'url' => $commits['values'][0]['links']['html']['href'] ?? null, + ], + ]; + } + + return null; + } + + protected function getCommitter(string $raw): array + { + $committer = explode(' <', $raw); + + return [ + 'name' => $committer[0], + 'email' => Str::replace('>', '', $committer[1]), + ]; + } +} diff --git a/app/SourceControlProviders/Custom.php b/app/SourceControlProviders/Custom.php new file mode 100755 index 0000000..d7bb22d --- /dev/null +++ b/app/SourceControlProviders/Custom.php @@ -0,0 +1,36 @@ + 'application/vnd.github.v3+json', + 'Authorization' => 'Bearer '.$this->sourceControl->access_token, + ])->get($this->apiUrl.'/user/repos'); + + return $res->successful(); + } + + /** + * @throws Exception + */ + public function getRepo(string $repo = null): mixed + { + if ($repo) { + $url = $this->apiUrl.'/repos/'.$repo; + } else { + $url = $this->apiUrl.'/user/repos'; + } + $res = Http::withHeaders([ + 'Accept' => 'application/vnd.github.v3+json', + 'Authorization' => 'Bearer '.$this->sourceControl->access_token, + ])->get($url); + + $this->handleResponseErrors($res, $repo); + + return $res->json(); + } + + public function fullRepoUrl(string $repo): string + { + return "https://{$this->sourceControl->access_token}@github.com/$repo.git"; + } + + /** + * @throws FailedToDeployGitHook + */ + public function deployHook(string $repo, array $events, string $secret): array + { + $response = Http::withHeaders([ + 'Accept' => 'application/vnd.github.v3+json', + 'Authorization' => 'Bearer '.$this->sourceControl->access_token, + ])->post($this->apiUrl."/repos/$repo/hooks", [ + 'name' => 'web', + 'events' => $events, + 'config' => [ + 'url' => url('/git-hooks?secret='.$secret), + 'content_type' => 'json', + ], + 'active' => true, + ]); + + if ($response->status() != 201) { + throw new FailedToDeployGitHook(json_decode($response->body())->message); + } + + return [ + 'hook_id' => json_decode($response->body())->id, + 'hook_response' => json_decode($response->body()), + ]; + } + + /** + * @throws FailedToDestroyGitHook + */ + public function destroyHook(string $repo, string $hookId): void + { + $response = Http::withHeaders([ + 'Accept' => 'application/vnd.github.v3+json', + 'Authorization' => 'Bearer '.$this->sourceControl->access_token, + ])->delete($this->apiUrl."/repos/$repo/hooks/$hookId"); + + if ($response->status() != 204) { + throw new FailedToDestroyGitHook(json_decode($response->body())->message); + } + } + + /** + * @throws Exception + */ + public function getLastCommit(string $repo, string $branch): ?array + { + $url = $this->apiUrl.'/repos/'.$repo.'/commits/'.$branch; + $res = Http::withHeaders([ + 'Accept' => 'application/vnd.github.v3+json', + 'Authorization' => 'Bearer '.$this->sourceControl->access_token, + ])->get($url); + + $this->handleResponseErrors($res, $repo); + + $commit = $res->json(); + if (isset($commit['sha']) && isset($commit['commit'])) { + return [ + 'commit_id' => $commit['sha'], + 'commit_data' => [ + 'name' => $commit['commit']['committer']['name'] ?? null, + 'email' => $commit['commit']['committer']['email'] ?? null, + 'message' => $commit['commit']['message'] ?? null, + 'url' => $commit['html_url'] ?? null, + ], + ]; + } + + return null; + } +} diff --git a/app/SourceControlProviders/Gitlab.php b/app/SourceControlProviders/Gitlab.php new file mode 100755 index 0000000..2921b57 --- /dev/null +++ b/app/SourceControlProviders/Gitlab.php @@ -0,0 +1,117 @@ +sourceControl->access_token) + ->get($this->apiUrl.'/projects'); + + return $res->successful(); + } + + /** + * @throws Exception + */ + public function getRepo(string $repo = null): mixed + { + $repository = $repo ? urlencode($repo) : null; + $res = Http::withToken($this->sourceControl->access_token) + ->get($this->apiUrl.'/projects/'.$repository.'/repository/commits'); + + $this->handleResponseErrors($res, $repo); + + return $res->json(); + } + + public function fullRepoUrl(string $repo): string + { + return 'https://oauth2:'.$this->sourceControl->access_token.'@gitlab.com/'.$repo.'.git'; + } + + /** + * @throws FailedToDeployGitHook + */ + public function deployHook(string $repo, array $events, string $secret): array + { + $repository = urlencode($repo); + $response = Http::withToken($this->sourceControl->access_token)->post( + $this->apiUrl.'/projects/'.$repository.'/hooks', + [ + 'description' => 'deploy', + 'url' => url('/git-hooks?secret='.$secret), + 'push_events' => in_array('push', $events), + 'issues_events' => false, + 'job_events' => false, + 'merge_requests_events' => false, + 'note_events' => false, + 'pipeline_events' => false, + 'tag_push_events' => false, + 'wiki_page_events' => false, + 'deployment_events' => false, + 'confidential_note_events' => false, + 'confidential_issues_events' => false, + ] + ); + + if ($response->status() != 201) { + throw new FailedToDeployGitHook(json_decode($response->body())->message); + } + + return [ + 'hook_id' => json_decode($response->body())->id, + 'hook_response' => json_decode($response->body()), + ]; + } + + /** + * @throws FailedToDestroyGitHook + */ + public function destroyHook(string $repo, string $hookId): void + { + $repository = urlencode($repo); + $response = Http::withToken($this->sourceControl->access_token)->delete( + $this->apiUrl.'/projects/'.$repository.'/hooks/'.$hookId + ); + + if ($response->status() != 204) { + throw new FailedToDestroyGitHook(json_decode($response->body())->message); + } + } + + /** + * @throws Exception + */ + public function getLastCommit(string $repo, string $branch): ?array + { + $repository = urlencode($repo); + $res = Http::withToken($this->sourceControl->access_token) + ->get($this->apiUrl.'/projects/'.$repository.'/repository/commits?ref_name='.$branch); + + $this->handleResponseErrors($res, $repo); + + $commits = $res->json(); + if (count($commits) > 0) { + return [ + 'commit_id' => $commits[0]['id'], + 'commit_data' => [ + 'name' => $commits[0]['committer_name'] ?? null, + 'email' => $commits[0]['committer_email'] ?? null, + 'message' => $commits[0]['title'] ?? null, + 'url' => $commits[0]['web_url'] ?? null, + ], + ]; + } + + return null; + } +} diff --git a/app/StorageProviders/AbstractStorageProvider.php b/app/StorageProviders/AbstractStorageProvider.php new file mode 100644 index 0000000..ae275ae --- /dev/null +++ b/app/StorageProviders/AbstractStorageProvider.php @@ -0,0 +1,16 @@ +storageProvider = $storageProvider; + } +} diff --git a/app/StorageProviders/Dropbox.php b/app/StorageProviders/Dropbox.php new file mode 100644 index 0000000..f1c8c33 --- /dev/null +++ b/app/StorageProviders/Dropbox.php @@ -0,0 +1,72 @@ +put('storage_provider_id', $this->storageProvider->id); + + return Socialite::driver('dropbox')->redirect(); + } + + /** + * @throws Throwable + */ + public function upload(Server $server, string $src, string $dest): array + { + $upload = $server->ssh()->exec( + new UploadToDropboxCommand( + $src, + $dest, + $this->storageProvider->token + ), + 'upload-to-dropbox' + ); + + $data = json_decode($upload); + + return [ + 'size' => $data?->size, + ]; + } + + /** + * @throws Throwable + */ + public function download(Server $server, string $src, string $dest): void + { + $server->ssh()->exec( + new DownloadFromDropboxCommand( + $src, + $dest, + $this->storageProvider->token + ), + 'download-from-dropbox' + ); + } + + public function delete(array $paths): void + { + $data = []; + foreach ($paths as $path) { + $data[] = ['path' => $path]; + } + Http::withToken($this->storageProvider->token) + ->withHeaders([ + 'Content-Type:application/json', + ]) + ->post('https://api.dropboxapi.com/2/files/delete_batch', [ + 'entries' => $data, + ]); + } +} diff --git a/app/Support/SocialiteProviders/DropboxProvider.php b/app/Support/SocialiteProviders/DropboxProvider.php new file mode 100644 index 0000000..a0253d9 --- /dev/null +++ b/app/Support/SocialiteProviders/DropboxProvider.php @@ -0,0 +1,78 @@ +buildAuthUrlFromBase('https://www.dropbox.com/oauth2/authorize', $state); + } + + /** + * {@inheritdoc} + */ + protected function getTokenUrl(): string + { + return 'https://api.dropboxapi.com/oauth2/token'; + } + + /** + * {@inheritdoc} + */ + protected function getTokenFields($code): array + { + return array_merge(parent::getTokenFields($code), [ + 'grant_type' => 'authorization_code', + ]); + } + + /** + * {@inheritdoc} + * + * @throws GuzzleException + */ + protected function getUserByToken($token) + { + $response = $this->getHttpClient()->post('https://api.dropboxapi.com/2/users/get_current_account', [ + 'headers' => [ + 'Authorization' => 'Bearer '.$token, + ], + ]); + + return json_decode($response->getBody(), true); + } + + /** + * {@inheritdoc} + */ + protected function mapUserToObject(array $user): User + { + return (new User)->setRaw($user)->map([ + 'id' => $user['account_id'], + 'nickname' => null, + 'name' => $user['name']['display_name'], + 'email' => $user['email'], + 'avatar' => Arr::get($user, 'profile_photo_url'), + ]); + } +} diff --git a/app/Support/Testing/SSHFake.php b/app/Support/Testing/SSHFake.php new file mode 100644 index 0000000..b625ff7 --- /dev/null +++ b/app/Support/Testing/SSHFake.php @@ -0,0 +1,66 @@ +output = $output; + + return $this; + } + + public function assertExecuted(array|string $commands): void + { + if (! $this->commands) { + PHPUnit::fail('No commands are executed'); + } + if (! is_array($commands)) { + $commands = [$commands]; + } + $allExecuted = true; + foreach ($commands as $command) { + if (! in_array($command, $commands)) { + $allExecuted = false; + } + } + if (! $allExecuted) { + PHPUnit::fail('The expected commands are not executed'); + } + PHPUnit::assertTrue(true, $allExecuted); + } + + public function exec(string|array|SSHCommand $commands, string $log = '', int $siteId = null): string + { + if (! is_array($commands)) { + $commands = [$commands]; + } + + foreach ($commands as $command) { + if (is_string($command)) { + $this->commands[] = $command; + } else { + $this->commands[] = get_class($command); + } + } + + return 'fake output'; + } +} diff --git a/app/Support/helpers.php b/app/Support/helpers.php new file mode 100755 index 0000000..a586b4c --- /dev/null +++ b/app/Support/helpers.php @@ -0,0 +1,65 @@ + {$publicKeyPath}"); +} + +function generate_key_pair($path): void +{ + exec("ssh-keygen -t ed25519 -m PEM -N '' -f {$path}"); + chmod($path, 0400); +} + +function make_bash_script($commands): string +{ + $script = ''; + foreach (preg_split("/((\r?\n)|(\r\n?))/", $commands) as $line) { + $script .= 'if ! '.$line."; then\n echo 'VITO_SSH_ERROR' && exit 1 \nfi"."\n"; + } + + return $script; +} + +/** + * @throws Exception + */ +function date_with_timezone($date, $timezone): string +{ + $dt = new DateTime('now', new DateTimeZone($timezone)); + $dt->setTimestamp(strtotime($date)); + + return $dt->format('Y-m-d H:i:s'); +} diff --git a/app/Traits/HasCustomPaginationView.php b/app/Traits/HasCustomPaginationView.php new file mode 100644 index 0000000..0bf06e9 --- /dev/null +++ b/app/Traits/HasCustomPaginationView.php @@ -0,0 +1,15 @@ + 'refreshComponent', + 'refreshComponent' => '$refresh', + '$refresh', + ]; + } + + public function refreshComponent(array $data): void + { + $this->emit('refreshComponent'); + } +} diff --git a/app/ValidationRules/CronRule.php b/app/ValidationRules/CronRule.php new file mode 100755 index 0000000..3b79b22 --- /dev/null +++ b/app/ValidationRules/CronRule.php @@ -0,0 +1,19 @@ + 3) { + return false; + } + $algorithm = $key_parts[0]; + $key = $key_parts[1]; + if (! in_array($algorithm, ['ssh-rsa', 'ssh-dss'])) { + return false; + } + $key_base64_decoded = base64_decode($key, true); + if ($key_base64_decoded == false) { + return false; + } + $check = base64_decode(substr($key, 0, 16)); + $check = preg_replace("/[^\w\-]/", '', $check); + if ((string) $check !== (string) $algorithm) { + return false; + } + + return true; + } + + /** + * @return array|\Illuminate\Contracts\Translation\Translator|string|null + */ + public function message() + { + return __('Invalid key'); + } +} diff --git a/app/View/Components/AppLayout.php b/app/View/Components/AppLayout.php new file mode 100644 index 0000000..fe4dcf5 --- /dev/null +++ b/app/View/Components/AppLayout.php @@ -0,0 +1,14 @@ +make(Illuminate\Contracts\Console\Kernel::class); + +$status = $kernel->handle( + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput +); + +/* +|-------------------------------------------------------------------------- +| Shutdown The Application +|-------------------------------------------------------------------------- +| +| Once Artisan has finished running, we will fire off the shutdown events +| so that any final work may be done by the application before we shut +| down the process. This is the last thing to happen to the request. +| +*/ + +$kernel->terminate($input, $status); + +exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..037e17d --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,55 @@ +singleton( + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +/* +|-------------------------------------------------------------------------- +| Return The Application +|-------------------------------------------------------------------------- +| +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. +| +*/ + +return $app; diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..8edbce9 --- /dev/null +++ b/composer.json @@ -0,0 +1,76 @@ +{ + "name": "laravel/laravel", + "type": "project", + "description": "The Laravel Framework.", + "keywords": ["framework", "laravel"], + "license": "MIT", + "require": { + "php": "^8.1", + "aws/aws-sdk-php": "^3.158", + "bensampo/laravel-enum": "^6.3", + "blade-ui-kit/blade-heroicons": "^2.1", + "guzzlehttp/guzzle": "^7.2", + "laravel/framework": "^10.0", + "laravel/sanctum": "^3.2", + "laravel/socialite": "^5.2", + "laravel/tinker": "^2.8", + "livewire/livewire": "^2.12", + "pusher/pusher-php-server": "^7.2" + }, + "require-dev": { + "fakerphp/faker": "^1.9.1", + "laravel/pint": "^1.10", + "laravel/sail": "^1.18", + "laravel/telescope": "^4.14", + "mockery/mockery": "^1.4.4", + "nunomaduro/collision": "^7.0", + "phpunit/phpunit": "^10.0", + "spatie/laravel-ignition": "^2.0" + }, + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Factories\\": "database/factories/", + "Database\\Seeders\\": "database/seeders/" + }, + "files": [ + "app/Support/helpers.php" + ] + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, + "scripts": { + "post-autoload-dump": [ + "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", + "@php artisan package:discover --ansi" + ], + "post-update-cmd": [ + "@php artisan vendor:publish --tag=laravel-assets --ansi --force" + ], + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-create-project-cmd": [ + "@php artisan key:generate --ansi" + ] + }, + "extra": { + "laravel": { + "dont-discover": [] + } + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true, + "php-http/discovery": true + } + }, + "minimum-stability": "stable", + "prefer-stable": true +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..1d265ba --- /dev/null +++ b/composer.lock @@ -0,0 +1,8973 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "c1707f21542e1ae2b8839cd24e846e51", + "packages": [ + { + "name": "aws/aws-crt-php", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1" + }, + "time": "2023-03-24T20:22:19+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.263.11", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "4ac444fd1dfabe18714d05d2603e92468c00a28b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/4ac444fd1dfabe18714d05d2603e92468c00a28b", + "reference": "4ac444fd1dfabe18714d05d2603e92468c00a28b", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.0.4", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", + "guzzlehttp/promises": "^1.4.0", + "guzzlehttp/psr7": "^1.8.5 || ^2.3", + "mtdowling/jmespath.php": "^2.6", + "php": ">=5.5" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^1.10.22", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "paragonie/random_compat": ">= 2", + "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3 || ^4.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.263.11" + }, + "time": "2023-04-14T18:22:01+00:00" + }, + { + "name": "bensampo/laravel-enum", + "version": "v6.3.1", + "source": { + "type": "git", + "url": "https://github.com/BenSampo/laravel-enum.git", + "reference": "b7a69853b1c8f2dcc8c03270a7d5229cb575f594" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/BenSampo/laravel-enum/zipball/b7a69853b1c8f2dcc8c03270a7d5229cb575f594", + "reference": "b7a69853b1c8f2dcc8c03270a7d5229cb575f594", + "shasum": "" + }, + "require": { + "composer/class-map-generator": "^1", + "illuminate/contracts": "^9 || ^10", + "illuminate/support": "^9 || ^10", + "laminas/laminas-code": "^3.4 || ^4", + "nikic/php-parser": "^4.13", + "php": "^8" + }, + "require-dev": { + "doctrine/dbal": "^3.4", + "ergebnis/composer-normalize": "^2.28.3", + "mockery/mockery": "^1.5", + "nunomaduro/larastan": "^2.1.12", + "orchestra/testbench": "^7.6.1 || ^8", + "phpstan/phpstan": "^1.8.2", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1.1", + "phpunit/phpunit": "^9.5.21", + "squizlabs/php_codesniffer": "^3.7.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BenSampo\\Enum\\EnumServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "BenSampo\\Enum\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Sampson", + "homepage": "https://sampo.co.uk", + "role": "Developer" + } + ], + "description": "Simple, extensible and powerful enumeration implementation for Laravel.", + "homepage": "https://github.com/bensampo/laravel-enum", + "keywords": [ + "bensampo", + "enum", + "laravel", + "package", + "validation" + ], + "support": { + "issues": "https://github.com/BenSampo/laravel-enum/issues", + "source": "https://github.com/BenSampo/laravel-enum/tree/v6.3.1" + }, + "funding": [ + { + "url": "https://github.com/bensampo", + "type": "github" + } + ], + "time": "2023-02-13T14:09:29+00:00" + }, + { + "name": "blade-ui-kit/blade-heroicons", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/blade-ui-kit/blade-heroicons.git", + "reference": "f756c807b0d04afd2caf7079bac26492da9cc6d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/blade-ui-kit/blade-heroicons/zipball/f756c807b0d04afd2caf7079bac26492da9cc6d4", + "reference": "f756c807b0d04afd2caf7079bac26492da9cc6d4", + "shasum": "" + }, + "require": { + "blade-ui-kit/blade-icons": "^1.1", + "illuminate/support": "^9.0|^10.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Heroicons\\BladeHeroiconsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "BladeUI\\Heroicons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of Heroicons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-heroicons", + "keywords": [ + "Heroicons", + "blade", + "laravel" + ], + "support": { + "issues": "https://github.com/blade-ui-kit/blade-heroicons/issues", + "source": "https://github.com/blade-ui-kit/blade-heroicons/tree/2.1.0" + }, + "funding": [ + { + "url": "https://github.com/caneco", + "type": "github" + }, + { + "url": "https://github.com/driesvints", + "type": "github" + } + ], + "time": "2023-01-11T08:38:22+00:00" + }, + { + "name": "blade-ui-kit/blade-icons", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/blade-ui-kit/blade-icons.git", + "reference": "b2a80ff2a26641f64bfee48ad0d2a922ce781228" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/b2a80ff2a26641f64bfee48ad0d2a922ce781228", + "reference": "b2a80ff2a26641f64bfee48ad0d2a922ce781228", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0|^10.0", + "illuminate/filesystem": "^8.0|^9.0|^10.0", + "illuminate/support": "^8.0|^9.0|^10.0", + "illuminate/view": "^8.0|^9.0|^10.0", + "php": "^7.4|^8.0", + "symfony/console": "^5.3|^6.0", + "symfony/finder": "^5.3|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "orchestra/testbench": "^6.0|^7.0|^8.0", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/blade-icons-generate" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Icons\\BladeIconsServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "BladeUI\\Icons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of icons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-icons", + "keywords": [ + "blade", + "icons", + "laravel", + "svg" + ], + "support": { + "issues": "https://github.com/blade-ui-kit/blade-icons/issues", + "source": "https://github.com/blade-ui-kit/blade-icons" + }, + "funding": [ + { + "url": "https://github.com/caneco", + "type": "github" + }, + { + "url": "https://github.com/driesvints", + "type": "github" + } + ], + "time": "2023-02-15T16:30:12+00:00" + }, + { + "name": "brick/math", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.11.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-01-15T23:15:59+00:00" + }, + { + "name": "composer/class-map-generator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "shasum": "" + }, + "require": { + "composer/pcre": "^2 || ^3", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-06-19T11:31:27+00:00" + }, + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-11-17T09:50:14+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "f41715465d65213d644d3141a6a93081be5d3549" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", + "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + }, + "time": "2022-10-27T11:44:00+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.6" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2022-10-20T09:10:12+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "84a527db05647743d50373e0ec53a152f2cde568" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568", + "reference": "84a527db05647743d50373e0ec53a152f2cde568", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-15T16:57:16+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-09-10T18:51:20+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/3a85486b709bc384dae8eb78fb2eec649bdb64ff", + "reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^4.30" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2023-01-14T14:17:03+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-02-20T15:07:15+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-02-25T20:23:15+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.5.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf", + "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.4.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-03-09T13:19:02+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "b945d74a55a25a949158444f09ec0d3c120d69e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/b945d74a55a25a949158444f09ec0d3c120d69e2", + "reference": "b945d74a55a25a949158444f09ec0d3c120d69e2", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.19 || ^9.5.8", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2021-10-07T12:57:01+00:00" + }, + { + "name": "laminas/laminas-code", + "version": "4.10.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-code.git", + "reference": "ad8b36073f9ac792716478befadca0798cc15635" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/ad8b36073f9ac792716478befadca0798cc15635", + "reference": "ad8b36073f9ac792716478befadca0798cc15635", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0.0", + "ext-phar": "*", + "laminas/laminas-coding-standard": "^2.3.0", + "laminas/laminas-stdlib": "^3.6.1", + "phpunit/phpunit": "^10.0.9", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.7.1" + }, + "suggest": { + "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", + "laminas/laminas-stdlib": "Laminas\\Stdlib component" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Code\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", + "homepage": "https://laminas.dev", + "keywords": [ + "code", + "laminas", + "laminasframework" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-code/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-code/issues", + "rss": "https://github.com/laminas/laminas-code/releases.atom", + "source": "https://github.com/laminas/laminas-code" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2023-03-08T11:55:01+00:00" + }, + { + "name": "laravel/framework", + "version": "v10.7.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "ddbbb2b50388721fe63312bb4469cae13163fd36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/ddbbb2b50388721fe63312bb4469cae13163fd36", + "reference": "ddbbb2b50388721fe63312bb4469cae13163fd36", + "shasum": "" + }, + "require": { + "brick/math": "^0.9.3|^0.10.2|^0.11", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.3.2", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.2", + "guzzlehttp/uri-template": "^1.0", + "laravel/serializable-closure": "^1.3", + "league/commonmark": "^2.2.1", + "league/flysystem": "^3.8.0", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^2.62.1", + "nunomaduro/termwind": "^1.13", + "php": "^8.1", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^6.2", + "symfony/error-handler": "^6.2", + "symfony/finder": "^6.2", + "symfony/http-foundation": "^6.2", + "symfony/http-kernel": "^6.2", + "symfony/mailer": "^6.2", + "symfony/mime": "^6.2", + "symfony/process": "^6.2", + "symfony/routing": "^6.2", + "symfony/uid": "^6.2", + "symfony/var-dumper": "^6.2", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.235.5", + "doctrine/dbal": "^3.5.1", + "ext-gmp": "*", + "fakerphp/faker": "^1.21", + "guzzlehttp/guzzle": "^7.5", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-path-prefixing": "^3.3", + "league/flysystem-read-only": "^3.3", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^8.4", + "pda/pheanstalk": "^4.0", + "phpstan/phpdoc-parser": "^1.15", + "phpstan/phpstan": "^1.4.7", + "phpunit/phpunit": "^10.0.7", + "predis/predis": "^2.0.2", + "symfony/cache": "^6.2", + "symfony/http-client": "^6.2.4" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", + "brianium/paratest": "Required to run tests in parallel (^6.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.5).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", + "league/flysystem-read-only": "Required to use read-only disks (^3.3)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.5.1).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8|^10.0.7).", + "predis/predis": "Required to use the predis connector (^2.0.2).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^6.2).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.2).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.2).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.2).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-04-11T14:11:49+00:00" + }, + { + "name": "laravel/sanctum", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "d09d69bac55708fcd4a3b305d760e673d888baf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/d09d69bac55708fcd4a3b305d760e673d888baf9", + "reference": "d09d69bac55708fcd4a3b305d760e673d888baf9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^9.21|^10.0", + "illuminate/contracts": "^9.21|^10.0", + "illuminate/database": "^9.21|^10.0", + "illuminate/support": "^9.21|^10.0", + "php": "^8.0.2" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^7.0|^8.0", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2023-01-13T15:41:49+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", + "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2023-01-30T18:31:20+00:00" + }, + { + "name": "laravel/socialite", + "version": "v5.6.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/a14a177f2cc71d8add71e2b19e00800e83bdda09", + "reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0", + "league/oauth1-client": "^1.10.1", + "php": "^7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0", + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ], + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "homepage": "https://laravel.com", + "keywords": [ + "laravel", + "oauth" + ], + "support": { + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" + }, + "time": "2023-01-20T15:42:35+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.8.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/04a2d3bd0d650c0764f70bf49d1ee39393e4eb10", + "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.10.4|^0.11.1", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.8.1" + }, + "time": "2023-02-15T16:40:09+00:00" + }, + { + "name": "league/commonmark", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048", + "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2023-03-24T15:16:10+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/flysystem", + "version": "3.14.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "e2a279d7f47d9098e479e8b21f7fb8b8de230158" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e2a279d7f47d9098e479e8b21f7fb8b8de230158", + "reference": "e2a279d7f47d9098e479e8b21f7fb8b8de230158", + "shasum": "" + }, + "require": { + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5", + "async-aws/simple-s3": "^1.1", + "aws/aws-sdk-php": "^3.220.0", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^3.0.14", + "phpstan/phpstan": "^0.12.26", + "phpunit/phpunit": "^9.5.11", + "sabre/dav": "^4.3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.14.0" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2023-04-11T18:11:47+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-04-17T13:12:02+00:00" + }, + { + "name": "league/oauth1-client", + "version": "v1.10.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" + }, + "require-dev": { + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5||9.5" + }, + "suggest": { + "ext-simplexml": "For decoding XML-based responses." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1" + }, + "time": "2022-04-15T14:02:14+00:00" + }, + { + "name": "livewire/livewire", + "version": "v2.12.3", + "source": { + "type": "git", + "url": "https://github.com/livewire/livewire.git", + "reference": "019b1e69d8cd8c7e749eba7a38e4fa69ecbc8f74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/livewire/zipball/019b1e69d8cd8c7e749eba7a38e4fa69ecbc8f74", + "reference": "019b1e69d8cd8c7e749eba7a38e4fa69ecbc8f74", + "shasum": "" + }, + "require": { + "illuminate/database": "^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^7.0|^8.0|^9.0|^10.0", + "illuminate/validation": "^7.0|^8.0|^9.0|^10.0", + "league/mime-type-detection": "^1.9", + "php": "^7.2.5|^8.0", + "symfony/http-kernel": "^5.0|^6.0" + }, + "require-dev": { + "calebporzio/sushi": "^2.1", + "laravel/framework": "^7.0|^8.0|^9.0|^10.0", + "mockery/mockery": "^1.3.1", + "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0", + "orchestra/testbench-dusk": "^5.2|^6.0|^7.0|^8.0", + "phpunit/phpunit": "^8.4|^9.0", + "psy/psysh": "@stable" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Livewire\\LivewireServiceProvider" + ], + "aliases": { + "Livewire": "Livewire\\Livewire" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "A front-end framework for Laravel.", + "support": { + "issues": "https://github.com/livewire/livewire/issues", + "source": "https://github.com/livewire/livewire/tree/v2.12.3" + }, + "funding": [ + { + "url": "https://github.com/livewire", + "type": "github" + } + ], + "time": "2023-03-03T20:12:38+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.3.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "9b5daeaffce5b926cac47923798bba91059e60e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/9b5daeaffce5b926cac47923798bba91059e60e2", + "reference": "9b5daeaffce5b926cac47923798bba91059e60e2", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^9.5.26", + "predis/predis": "^1.1 || ^2", + "ruflin/elastica": "^7", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.3.1" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2023-02-06T13:46:10+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1" + }, + "time": "2021-06-14T00:11:39+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.66.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "496712849902241f04902033b0441b269effe001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/496712849902241f04902033b0441b269effe001", + "reference": "496712849902241f04902033b0441b269effe001", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.1.4", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2023-01-29T18:53:47+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.3" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.3" + }, + "time": "2022-10-13T01:24:26+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e", + "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e", + "shasum": "" + }, + "require": { + "php": ">=8.0 <8.3" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.0" + }, + "time": "2023-02-02T10:41:53+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290", + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4" + }, + "time": "2023-03-05T19:49:14+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v1.15.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.0", + "symfony/console": "^5.3.0|^6.0.0" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^1.0.", + "illuminate/console": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "laravel/pint": "^1.0.0", + "pestphp/pest": "^1.21.0", + "pestphp/pest-plugin-mock": "^1.0", + "phpstan/phpstan": "^1.4.6", + "phpstan/phpstan-strict-rules": "^1.1.0", + "symfony/var-dumper": "^5.2.7|^6.0.0", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v1.15.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2023-02-08T01:06:31+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "paragonie/sodium_compat", + "version": "v1.19.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/sodium_compat.git", + "reference": "cb15e403ecbe6a6cc515f855c310eb6b1872a933" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/cb15e403ecbe6a6cc515f855c310eb6b1872a933", + "reference": "cb15e403ecbe6a6cc515f855c310eb6b1872a933", + "shasum": "" + }, + "require": { + "paragonie/random_compat": ">=1", + "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9" + }, + "suggest": { + "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.", + "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security." + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com" + }, + { + "name": "Frank Denis", + "email": "jedisct1@pureftpd.org" + } + ], + "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists", + "keywords": [ + "Authentication", + "BLAKE2b", + "ChaCha20", + "ChaCha20-Poly1305", + "Chapoly", + "Curve25519", + "Ed25519", + "EdDSA", + "Edwards-curve Digital Signature Algorithm", + "Elliptic Curve Diffie-Hellman", + "Poly1305", + "Pure-PHP cryptography", + "RFC 7748", + "RFC 8032", + "Salpoly", + "Salsa20", + "X25519", + "XChaCha20-Poly1305", + "XSalsa20-Poly1305", + "Xchacha20", + "Xsalsa20", + "aead", + "cryptography", + "ecdh", + "elliptic curve", + "elliptic curve cryptography", + "encryption", + "libsodium", + "php", + "public-key cryptography", + "secret-key cryptography", + "side-channel resistant" + ], + "support": { + "issues": "https://github.com/paragonie/sodium_compat/issues", + "source": "https://github.com/paragonie/sodium_compat/tree/v1.19.0" + }, + "time": "2022-09-26T03:40:35+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-02-25T19:38:58+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/1.0.2" + }, + "time": "2023-04-10T20:12:12+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.11.15", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "5350ce0ec8ecf2c5b5cf554cd2496f97b444af85" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/5350ce0ec8ecf2c5b5cf554cd2496f97b444af85", + "reference": "5350ce0ec8ecf2c5b5cf554cd2496f97b444af85", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.11.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.15" + }, + "time": "2023-04-07T21:57:09+00:00" + }, + { + "name": "pusher/pusher-php-server", + "version": "7.2.2", + "source": { + "type": "git", + "url": "https://github.com/pusher/pusher-http-php.git", + "reference": "4ace4873873b06c25cecb2dd6d9fdcbf2f20b640" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pusher/pusher-http-php/zipball/4ace4873873b06c25cecb2dd6d9fdcbf2f20b640", + "reference": "4ace4873873b06c25cecb2dd6d9fdcbf2f20b640", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.2", + "paragonie/sodium_compat": "^1.6", + "php": "^7.3|^8.0", + "psr/log": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "overtrue/phplint": "^2.3", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Pusher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Library for interacting with the Pusher REST API", + "keywords": [ + "events", + "messaging", + "php-pusher-server", + "publish", + "push", + "pusher", + "real time", + "real-time", + "realtime", + "rest", + "trigger" + ], + "support": { + "issues": "https://github.com/pusher/pusher-http-php/issues", + "source": "https://github.com/pusher/pusher-http-php/tree/7.2.2" + }, + "time": "2022-12-20T19:52:36+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2022-12-31T21:50:55+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.7.4", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "60a4c63ab724854332900504274f6150ff26d286" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", + "reference": "60a4c63ab724854332900504274f6150ff26d286", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.4" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2023-04-15T23:01:58+00:00" + }, + { + "name": "symfony/console", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/3582d68a64a86ec25240aaa521ec8bc2342b369b", + "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.2.8" + }, + "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-03-29T21:42:15+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/aedf3cb0f5b929ec255d96bbb4909e9932c769e0", + "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v6.2.7" + }, + "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-02-14T08:44:56+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e", + "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-01T10:25:55+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.2.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "e95f1273b3953c3b5e5341172dae838bacee11ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/e95f1273b3953c3b5e5341172dae838bacee11ee", + "reference": "e95f1273b3953c3b5e5341172dae838bacee11ee", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.2.9" + }, + "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-04-11T16:03:19+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339", + "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8" + }, + "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-03-20T16:06:02+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ad3b6f1e4e2da5690fefe075cd53a238646d8dd", + "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-01T10:32:47+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb", + "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.2.7" + }, + "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-02-16T09:57:23+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "511a524affeefc191939348823ac75e9921c2112" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/511a524affeefc191939348823ac75e9921c2112", + "reference": "511a524affeefc191939348823ac75e9921c2112", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "conflict": { + "symfony/cache": "<6.2" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.2.8" + }, + "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-03-29T21:42:15+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.2.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "02246510cf7031726f7237138d61b796b95799b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/02246510cf7031726f7237138d61b796b95799b3", + "reference": "02246510cf7031726f7237138d61b796b95799b3", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/error-handler": "^6.1", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/http-foundation": "^5.4.21|^6.2.7", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.2", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<5.4", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^6.1", + "symfony/console": "^5.4|^6.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dependency-injection": "^6.2", + "symfony/dom-crawler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.2.9" + }, + "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-04-13T16:41:43+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/bfcfa015c67e19c6fdb7ca6fe70700af1e740a17", + "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/mime": "^6.2", + "symfony/service-contracts": "^1.1|^2|^3" + }, + "conflict": { + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/messenger": "^6.2", + "symfony/twig-bridge": "^6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.2.8" + }, + "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-03-14T15:00:05+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "62e341f80699badb0ad70b31149c8df89a2d778e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/62e341f80699badb0ad70b31149c8df89a2d778e", + "reference": "62e341f80699badb0ad70b31149c8df89a2d778e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.2" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/serializer": "^6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.2.7" + }, + "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-02-24T10:42:00+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "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 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/f3cf1a645c2734236ed1e2e671e273eeb3586166", + "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "75ed64103df4f6615e15a7fe38b8111099f47416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/75ed64103df4f6615e15a7fe38b8111099f47416", + "reference": "75ed64103df4f6615e15a7fe38b8111099f47416", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.2.8" + }, + "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-03-09T16:20:02+00:00" + }, + { + "name": "symfony/routing", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "69062e2823f03b82265d73a966999660f0e1e404" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/69062e2823f03b82265d73a966999660f0e1e404", + "reference": "69062e2823f03b82265d73a966999660f0e1e404", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<6.2", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12|^2", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.2", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v6.2.8" + }, + "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-03-14T15:00:05+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "a8c9cedf55f314f3a186041d19537303766df09a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a", + "reference": "a8c9cedf55f314f3a186041d19537303766df09a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-01T10:32:47+00:00" + }, + { + "name": "symfony/string", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef", + "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.2.8" + }, + "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-03-20T16:06:02+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/817535dbb1721df8b3a8f2489dc7e50bcd6209b5", + "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.3|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "nikic/php-parser": "To use PhpAstExtractor", + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.2.8" + }, + "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-03-31T09:14:44+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dfec258b9dd17a6b24420d464c43bffe347441c8", + "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-01T10:32:47+00:00" + }, + { + "name": "symfony/uid", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "d30c72a63897cfa043e1de4d4dd2ffa9ecefcdc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/d30c72a63897cfa043e1de4d4dd2ffa9ecefcdc0", + "reference": "d30c72a63897cfa043e1de4d4dd2ffa9ecefcdc0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v6.2.7" + }, + "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-02-14T08:44:56+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "d37ab6787be2db993747b6218fcc96e8e3bb4bd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d37ab6787be2db993747b6218fcc96e8e3bb4bd0", + "reference": "d37ab6787be2db993747b6218fcc96e8e3bb4bd0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "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.2.8" + }, + "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-03-29T21:42:15+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.6", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c", + "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6" + }, + "time": "2023-01-03T09:29:04+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.5.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.5-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2022-10-16T01:01:54+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b56450eed252f6801410d810c8e1727224ae0743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-03-08T17:03:00+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "fakerphp/faker", + "version": "v1.21.0", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "92efad6a967f0b79c499705c69b662f738cc9e4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/92efad6a967f0b79c499705c69b662f738cc9e4d", + "reference": "92efad6a967f0b79c499705c69b662f738cc9e4d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "v1.21-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.21.0" + }, + "time": "2022-12-13T13:54:32+00:00" + }, + { + "name": "filp/whoops", + "version": "2.15.2", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/aac9304c5ed61bf7b1b7a6064bf9806ab842ce73", + "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.15.2" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2023-04-12T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "c7a01fa9bdd79819e7a2f1ba63ac1b02e6692dbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/c7a01fa9bdd79819e7a2f1ba63ac1b02e6692dbc", + "reference": "c7a01fa9bdd79819e7a2f1ba63ac1b02e6692dbc", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.16.0", + "illuminate/view": "^10.5.1", + "laravel-zero/framework": "^10.0.2", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.5.1", + "nunomaduro/termwind": "^1.15.1", + "pestphp/pest": "^2.4.0" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2023-04-25T14:52:30+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.21.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "5e59b4a57181020477e2b18943b27493638e3f89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/5e59b4a57181020477e2b18943b27493638e3f89", + "reference": "5e59b4a57181020477e2b18943b27493638e3f89", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0|^10.0", + "illuminate/contracts": "^8.0|^9.0|^10.0", + "illuminate/support": "^8.0|^9.0|^10.0", + "php": "^7.3|^8.0", + "symfony/yaml": "^6.0" + }, + "require-dev": { + "orchestra/testbench": "^6.0|^7.0|^8.0", + "phpstan/phpstan": "^1.10" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2023-03-30T12:28:55+00:00" + }, + { + "name": "laravel/telescope", + "version": "v4.14.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "88ca4cbeefea563b605cf3fd9c10ff5a623864b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/88ca4cbeefea563b605cf3fd9c10ff5a623864b1", + "reference": "88ca4cbeefea563b605cf3fd9c10ff5a623864b1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.37|^9.0|^10.0", + "php": "^8.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "ext-gd": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "laravel/octane": "^1.4", + "orchestra/testbench": "^6.0|^7.0|^8.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/", + "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "support": { + "issues": "https://github.com/laravel/telescope/issues", + "source": "https://github.com/laravel/telescope/tree/v4.14.1" + }, + "time": "2023-03-17T18:13:19+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/e92dcc83d5a51851baf5f5591d32cb2b16e3684e", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.5.1" + }, + "time": "2022-09-07T15:32:08+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v7.5.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "bbbc6fb9c1ee88f8aa38e47abd15c465f946f85e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/bbbc6fb9c1ee88f8aa38e47abd15c465f946f85e", + "reference": "bbbc6fb9c1ee88f8aa38e47abd15c465f946f85e", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.15.2", + "nunomaduro/termwind": "^1.15.1", + "php": "^8.1.0", + "symfony/console": "^6.2.8" + }, + "conflict": { + "phpunit/phpunit": "<10.1.0" + }, + "require-dev": { + "brianium/paratest": "^7.1.3", + "laravel/framework": "^10.7.1", + "laravel/pint": "^1.8.0", + "laravel/sail": "^1.21.4", + "laravel/sanctum": "^3.2.1", + "laravel/tinker": "^2.8.1", + "nunomaduro/larastan": "^2.5.1", + "orchestra/testbench-core": "^8.4.2", + "pestphp/pest": "^2.5.0", + "phpunit/phpunit": "^10.1.0", + "sebastian/environment": "^6.0.1", + "spatie/laravel-ignition": "^2.1.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2023-04-14T10:39:16+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "fc4f5ee614fa82d50ecf9014b51af0a9561f3df8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/fc4f5ee614fa82d50ecf9014b51af0a9561f3df8", + "reference": "fc4f5ee614fa82d50ecf9014b51af0a9561f3df8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-13T07:08:27+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "fd9329ab3368f59fe1fe808a189c51086bd4b6bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/fd9329ab3368f59fe1fe808a189c51086bd4b6bd", + "reference": "fd9329ab3368f59fe1fe808a189c51086bd4b6bd", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-10T16:53:14+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "9f3d3709577a527025f55bcf0f7ab8052c8bb37d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/9f3d3709577a527025f55bcf0f7ab8052c8bb37d", + "reference": "9f3d3709577a527025f55bcf0f7ab8052c8bb37d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:46+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "5a477aea03e61329132935689ae2d73f418f5e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5a477aea03e61329132935689ae2d73f418f5e25", + "reference": "5a477aea03e61329132935689ae2d73f418f5e25", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.0", + "sebastian/global-state": "^6.0", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.1.0" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-04-14T05:15:09+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/72f01e6586e0caf6af81297897bd112eb7e9627c", + "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:07:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:47+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "aae9a0a43bff37bd5d8d0311426c87bf36153f02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/aae9a0a43bff37bd5d8d0311426c87bf36153f02", + "reference": "aae9a0a43bff37bd5d8d0311426c87bf36153f02", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-03-23T05:12:41+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-11T05:39:26+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0", + "reference": "f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:49+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "aab257c712de87b90194febd52e4d184551c2d44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/aab257c712de87b90194febd52e4d184551c2d44", + "reference": "aab257c712de87b90194febd52e4d184551c2d44", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:07:38+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/17c4d940ecafb3d15d2cf916f4108f664e28b130", + "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:02+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "ec4dd16476b802dbdc6b4467f84032837e316b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/ec4dd16476b802dbdc6b4467f84032837e316b8c", + "reference": "ec4dd16476b802dbdc6b4467f84032837e316b8c", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "spatie/phpunit-snapshot-assertions": "^4.2", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/backtrace/tree/1.4.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2023-03-04T08:57:24+00:00" + }, + { + "name": "spatie/flare-client-php", + "version": "1.3.6", + "source": { + "type": "git", + "url": "https://github.com/spatie/flare-client-php.git", + "reference": "530ac81255af79f114344286e4275f8869c671e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/530ac81255af79f114344286e4275f8869c671e2", + "reference": "530ac81255af79f114344286e4275f8869c671e2", + "shasum": "" + }, + "require": { + "illuminate/pipeline": "^8.0|^9.0|^10.0", + "php": "^8.0", + "spatie/backtrace": "^1.2", + "symfony/http-foundation": "^5.0|^6.0", + "symfony/mime": "^5.2|^6.0", + "symfony/process": "^5.2|^6.0", + "symfony/var-dumper": "^5.2|^6.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.3.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/phpunit-snapshot-assertions": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\FlareClient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Send PHP errors to Flare", + "homepage": "https://github.com/spatie/flare-client-php", + "keywords": [ + "exception", + "flare", + "reporting", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/flare-client-php/issues", + "source": "https://github.com/spatie/flare-client-php/tree/1.3.6" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-04-12T07:57:12+00:00" + }, + { + "name": "spatie/ignition", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/ignition.git", + "reference": "4db9c9626e4d7745efbe0b512157326190b41b65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ignition/zipball/4db9c9626e4d7745efbe0b512157326190b41b65", + "reference": "4db9c9626e4d7745efbe0b512157326190b41b65", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.0", + "spatie/backtrace": "^1.4", + "spatie/flare-client-php": "^1.1", + "symfony/console": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "illuminate/cache": "^9.52", + "mockery/mockery": "^1.4", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "psr/simple-cache-implementation": "*", + "symfony/cache": "^6.2", + "symfony/process": "^5.4|^6.0", + "vlucas/phpdotenv": "^5.5" + }, + "suggest": { + "openai-php/client": "Require get solutions from OpenAI", + "simple-cache-implementation": "To cache solutions from OpenAI" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\Ignition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for PHP applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/ignition/issues", + "source": "https://github.com/spatie/ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-04-12T09:07:50+00:00" + }, + { + "name": "spatie/laravel-ignition", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ignition.git", + "reference": "3718dfb91bc5aff340af26507a61f0f9605f81e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/3718dfb91bc5aff340af26507a61f0f9605f81e8", + "reference": "3718dfb91bc5aff340af26507a61f0f9605f81e8", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "illuminate/support": "^10.0", + "php": "^8.1", + "spatie/flare-client-php": "^1.3.5", + "spatie/ignition": "^1.5.0", + "symfony/console": "^6.2.3", + "symfony/var-dumper": "^6.2.3" + }, + "require-dev": { + "livewire/livewire": "^2.11", + "mockery/mockery": "^1.5.1", + "openai-php/client": "^0.3.4", + "orchestra/testbench": "^8.0", + "pestphp/pest": "^1.22.3", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan-deprecation-rules": "^1.1.1", + "phpstan/phpstan-phpunit": "^1.3.3", + "vlucas/phpdotenv": "^5.5" + }, + "suggest": { + "openai-php/client": "Require get solutions from OpenAI", + "psr/simple-cache-implementation": "Needed to cache solutions from OpenAI" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelIgnition\\IgnitionServiceProvider" + ], + "aliases": { + "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\LaravelIgnition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for Laravel applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/laravel-ignition/issues", + "source": "https://github.com/spatie/laravel-ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-04-12T09:26:00+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e8e6a1d59e050525f27a1f530aa9703423cb7f57", + "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.2.7" + }, + "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-02-16T09:57:23+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.1" + }, + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..7d9462e --- /dev/null +++ b/config/app.php @@ -0,0 +1,216 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | your application so that it is used when running Artisan tasks. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + 'asset_url' => env('ASSET_URL'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. We have gone + | ahead and set this to a sensible default for you out of the box. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by the translation service provider. You are free to set this value + | to any of the locales which will be supported by the application. + | + */ + + 'locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Application Fallback Locale + |-------------------------------------------------------------------------- + | + | The fallback locale determines the locale to use when the current one + | is not available. You may change the value to correspond to any of + | the language folders that are provided through your application. + | + */ + + 'fallback_locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + + 'faker_locale' => 'en_US', + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is used by the Illuminate encrypter service and should be set + | to a random, 32 character string, otherwise these encrypted strings + | will not be safe. Please do this before deploying an application! + | + */ + + 'key' => env('APP_KEY'), + + 'cipher' => 'AES-256-CBC', + + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => 'file', + // 'store' => 'redis', + ], + + /* + |-------------------------------------------------------------------------- + | Autoloaded Service Providers + |-------------------------------------------------------------------------- + | + | The service providers listed here will be automatically loaded on the + | request to your application. Feel free to add your own services to + | this array to grant expanded functionality to your applications. + | + */ + + 'providers' => [ + + /* + * Laravel Framework Service Providers... + */ + Illuminate\Auth\AuthServiceProvider::class, + Illuminate\Broadcasting\BroadcastServiceProvider::class, + Illuminate\Bus\BusServiceProvider::class, + Illuminate\Cache\CacheServiceProvider::class, + Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, + Illuminate\Cookie\CookieServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + Illuminate\Encryption\EncryptionServiceProvider::class, + Illuminate\Filesystem\FilesystemServiceProvider::class, + Illuminate\Foundation\Providers\FoundationServiceProvider::class, + Illuminate\Hashing\HashServiceProvider::class, + Illuminate\Mail\MailServiceProvider::class, + Illuminate\Notifications\NotificationServiceProvider::class, + Illuminate\Pagination\PaginationServiceProvider::class, + Illuminate\Pipeline\PipelineServiceProvider::class, + Illuminate\Queue\QueueServiceProvider::class, + Illuminate\Redis\RedisServiceProvider::class, + Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, + Illuminate\Translation\TranslationServiceProvider::class, + Illuminate\Validation\ValidationServiceProvider::class, + Illuminate\View\ViewServiceProvider::class, + + /* + * Package Service Providers... + */ + + /* + * Application Service Providers... + */ + App\Providers\AppServiceProvider::class, + App\Providers\AuthServiceProvider::class, + App\Providers\BroadcastServiceProvider::class, + App\Providers\EventServiceProvider::class, + App\Providers\RouteServiceProvider::class, + App\Providers\TelescopeServiceProvider::class, + + ], + + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | This array of class aliases will be registered when this application + | is started. However, feel free to register as many as you wish as + | the aliases are "lazy" loaded so they don't hinder performance. + | + */ + + 'aliases' => Facade::defaultAliases()->merge([ + // 'ExampleClass' => App\Example\ExampleClass::class, + ])->toArray(), + +]; diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..9548c15 --- /dev/null +++ b/config/auth.php @@ -0,0 +1,115 @@ + [ + 'guard' => 'web', + 'passwords' => 'users', + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | here which uses session storage and the Eloquent user provider. + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | If you have multiple user tables or models you may configure multiple + | sources which represent each model / table. These sources may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => App\Models\User::class, + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | You may specify multiple password reset configurations if you have more + | than one user table or model in the application and you want to have + | separate password reset settings based on the specific user types. + | + | The expiry time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => 'password_reset_tokens', + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | times out and the user is prompted to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => 10800, + +]; diff --git a/config/blade-heroicons.php b/config/blade-heroicons.php new file mode 100644 index 0000000..e517a97 --- /dev/null +++ b/config/blade-heroicons.php @@ -0,0 +1,57 @@ + 'heroicon', + + /* + |----------------------------------------------------------------- + | Fallback Icon + |----------------------------------------------------------------- + | + | This config option allows you to define a fallback + | icon when an icon in this set cannot be found. + | + */ + + 'fallback' => '', + + /* + |----------------------------------------------------------------- + | Default Set Classes + |----------------------------------------------------------------- + | + | This config option allows you to define some classes which + | will be applied by default to all icons within this set. + | + */ + + 'class' => '', + + /* + |----------------------------------------------------------------- + | Default Set Attributes + |----------------------------------------------------------------- + | + | This config option allows you to define some attributes which + | will be applied by default to all icons within this set. + | + */ + + 'attributes' => [ + // 'width' => 50, + // 'height' => 50, + ], + +]; diff --git a/config/broadcasting.php b/config/broadcasting.php new file mode 100644 index 0000000..9e4d4aa --- /dev/null +++ b/config/broadcasting.php @@ -0,0 +1,70 @@ + env('BROADCAST_DRIVER', 'null'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_APP_KEY'), + 'secret' => env('PUSHER_APP_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), + 'options' => [ + 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'port' => env('PUSHER_PORT', 443), + 'scheme' => env('PUSHER_SCHEME', 'https'), + 'encrypted' => true, + 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', + ], + 'client_options' => [ + // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html + ], + ], + + 'ably' => [ + 'driver' => 'ably', + 'key' => env('ABLY_KEY'), + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + 'null' => [ + 'driver' => 'null', + ], + + ], + +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..33bb295 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,110 @@ + env('CACHE_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "apc", "array", "database", "file", + | "memcached", "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc', + ], + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + 'lock_connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'cache', + 'lock_connection' => 'default', + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, or DynamoDB cache + | stores there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + +]; diff --git a/config/core.php b/config/core.php new file mode 100755 index 0000000..a3fa386 --- /dev/null +++ b/config/core.php @@ -0,0 +1,361 @@ + env('SSH_USER', 'vito'), + 'ssh_public_key' => env('SSH_PUBLIC_KEY'), + 'ssh_public_key_name' => env('SSH_PUBLIC_KEY_NAME'), + 'ssh_private_key_name' => env('SSH_PRIVATE_KEY_NAME'), + 'logs_disk' => env('SERVER_LOGS_DISK', 'server-logs-local'), + 'key_pairs_disk' => env('KEY_PAIRS_DISK', 'key-pairs-local'), + + /* + * General + */ + 'operating_systems' => ['ubuntu_18', 'ubuntu_20', 'ubuntu_22'], + 'webservers' => ['nginx'], + 'php_versions' => [ + 'none', + // '5.6', + '7.0', + '7.1', + '7.2', + '7.3', + '7.4', + '8.0', + '8.1', + '8.2', + ], + 'databases' => ['none', 'mysql57', 'mysql80', 'mariadb'], + 'databases_name' => [ + 'mysql57' => 'mysql', + 'mysql80' => 'mysql', + 'mariadb' => 'mariadb', + ], + 'databases_version' => [ + 'mysql57' => '5.7', + 'mysql80' => '8.0', + 'mariadb' => '10.3', + ], + + /* + * Server + */ + 'server_types' => ['regular'], + 'server_types_class' => [ + 'regular' => Regular::class, + ], + 'server_providers' => ['custom', 'aws', 'linode', 'digitalocean', 'vultr', 'hetzner'], + 'server_providers_class' => [ + 'custom' => \App\ServerProviders\Custom::class, + 'aws' => AWS::class, + 'linode' => Linode::class, + 'digitalocean' => DigitalOcean::class, + 'vultr' => Vultr::class, + 'hetzner' => Hetzner::class, + ], + 'server_providers_default_user' => [ + 'custom' => [ + 'ubuntu_18' => 'root', + 'ubuntu_20' => 'root', + 'ubuntu_22' => 'root', + ], + 'aws' => [ + 'ubuntu_18' => 'ubuntu', + 'ubuntu_20' => 'ubuntu', + 'ubuntu_22' => 'ubuntu', + ], + 'linode' => [ + 'ubuntu_18' => 'root', + 'ubuntu_20' => 'root', + 'ubuntu_22' => 'root', + ], + 'digitalocean' => [ + 'ubuntu_18' => 'root', + 'ubuntu_20' => 'root', + 'ubuntu_22' => 'root', + ], + 'vultr' => [ + 'ubuntu_18' => 'root', + 'ubuntu_20' => 'root', + 'ubuntu_22' => 'root', + ], + 'hetzner' => [ + 'ubuntu_18' => 'root', + 'ubuntu_20' => 'root', + 'ubuntu_22' => 'root', + ], + ], + + /* + * Service + */ + 'service_installers' => [ + 'nginx' => InstallNginx::class, + 'mysql' => InstallMysql::class, + 'mariadb' => InstallMariadb::class, + 'php' => InstallPHP::class, + 'redis' => InstallRedis::class, + 'supervisor' => InstallSupervisor::class, + 'ufw' => InstallUfw::class, + 'phpmyadmin' => InstallPHPMyAdmin::class, + ], + 'service_uninstallers' => [ + 'phpmyadmin' => UninstallPHPMyAdmin::class, + 'php' => UninstallPHP::class, + ], + 'service_handlers' => [ + 'nginx' => Nginx::class, + 'mysql' => Mysql::class, + 'mariadb' => Mysql::class, + 'php' => PHP::class, + 'ufw' => Ufw::class, + 'supervisor' => Supervisor::class, + ], + 'service_units' => [ + 'nginx' => [ + 'ubuntu_18' => [ + 'latest' => 'nginx', + ], + 'ubuntu_20' => [ + 'latest' => 'nginx', + ], + 'ubuntu_22' => [ + 'latest' => 'nginx', + ], + ], + 'mysql' => [ + 'ubuntu_18' => [ + '5.7' => 'mysql', + '8.0' => 'mysql', + ], + 'ubuntu_20' => [ + '5.7' => 'mysql', + '8.0' => 'mysql', + ], + 'ubuntu_22' => [ + '5.7' => 'mysql', + '8.0' => 'mysql', + ], + ], + 'mariadb' => [ + 'ubuntu_18' => [ + '10.3' => 'mariadb', + ], + 'ubuntu_20' => [ + '10.3' => 'mariadb', + ], + 'ubuntu_22' => [ + '10.3' => 'mariadb', + ], + ], + 'php' => [ + 'ubuntu_18' => [ + '5.6' => 'php5.6-fpm', + '7.0' => 'php7.0-fpm', + '7.1' => 'php7.1-fpm', + '7.2' => 'php7.2-fpm', + '7.3' => 'php7.3-fpm', + '7.4' => 'php7.4-fpm', + '8.0' => 'php8.0-fpm', + '8.1' => 'php8.1-fpm', + '8.2' => 'php8.2-fpm', + ], + 'ubuntu_20' => [ + '5.6' => 'php5.6-fpm', + '7.0' => 'php7.0-fpm', + '7.1' => 'php7.1-fpm', + '7.2' => 'php7.2-fpm', + '7.3' => 'php7.3-fpm', + '7.4' => 'php7.4-fpm', + '8.0' => 'php8.0-fpm', + '8.1' => 'php8.1-fpm', + '8.2' => 'php8.2-fpm', + ], + 'ubuntu_22' => [ + '5.6' => 'php5.6-fpm', + '7.0' => 'php7.0-fpm', + '7.1' => 'php7.1-fpm', + '7.2' => 'php7.2-fpm', + '7.3' => 'php7.3-fpm', + '7.4' => 'php7.4-fpm', + '8.0' => 'php8.0-fpm', + '8.1' => 'php8.1-fpm', + '8.2' => 'php8.2-fpm', + ], + ], + 'redis' => [ + 'ubuntu_18' => [ + 'latest' => 'redis', + ], + 'ubuntu_20' => [ + 'latest' => 'redis', + ], + 'ubuntu_22' => [ + 'latest' => 'redis', + ], + ], + 'supervisor' => [ + 'ubuntu_18' => [ + 'latest' => 'supervisor', + ], + 'ubuntu_20' => [ + 'latest' => 'supervisor', + ], + 'ubuntu_22' => [ + 'latest' => 'supervisor', + ], + ], + 'ufw' => [ + 'ubuntu_18' => [ + 'latest' => 'ufw', + ], + 'ubuntu_20' => [ + 'latest' => 'ufw', + ], + 'ubuntu_22' => [ + 'latest' => 'ufw', + ], + ], + ], + + /* + * Site + */ + 'site_types' => [ + \App\Enums\SiteType::LARAVEL, + \App\Enums\SiteType::PHP, + \App\Enums\SiteType::WORDPRESS, + ], + 'site_types_class' => [ + \App\Enums\SiteType::LARAVEL => Laravel::class, + \App\Enums\SiteType::PHP => PHPSite::class, + \App\Enums\SiteType::WORDPRESS => Wordpress::class, + ], + + /* + * Source Control + */ + 'source_control_providers' => [ + 'github', + 'gitlab', + 'bitbucket', + 'custom', + ], + 'source_control_providers_class' => [ + 'github' => Github::class, + 'gitlab' => Gitlab::class, + 'bitbucket' => Bitbucket::class, + 'custom' => Custom::class, + ], + + /* + * available php extensions + */ + 'php_extensions' => [ + 'imagick', + // 'geoip', + 'exif', + 'gmagick', + 'ssh2', + 'gmp', + 'intl', + ], + + /* + * php settings + */ + 'php_settings' => [ + 'upload_max_filesize' => '2', + 'memory_limit' => '128', + 'max_execution_time' => '30', + 'post_max_size' => '2', + ], + 'php_settings_unit' => [ + 'upload_max_filesize' => 'M', + 'memory_limit' => 'M', + 'max_execution_time' => 'S', + 'post_max_size' => 'M', + ], + + /* + * firewall + */ + 'firewall_protocols_port' => [ + 'ssh' => 22, + 'http' => 80, + 'https' => 443, + 'mysql' => 3306, + 'ftp' => 21, + 'phpmyadmin' => 54331, + 'tcp' => '', + 'udp' => '', + ], + + /* + * Disable these IPs for servers + */ + 'restricted_ip_addresses' => array_merge( + ['127.0.0.1', 'localhost', '0.0.0.0'], + explode(',', env('RESTRICTED_IP_ADDRESSES', '')) + ), + + /* + * Notification channels + */ + 'notification_channels_providers' => [ + \App\Enums\NotificationChannel::SLACK, + \App\Enums\NotificationChannel::DISCORD, + \App\Enums\NotificationChannel::EMAIL, + ], + 'notification_channels_providers_class' => [ + \App\Enums\NotificationChannel::SLACK => Slack::class, + \App\Enums\NotificationChannel::DISCORD => Discord::class, + \App\Enums\NotificationChannel::EMAIL => Email::class, + ], + + /* + * storage providers + */ + 'storage_providers' => [ + 'dropbox', + ], + 'storage_providers_class' => [ + 'dropbox' => Dropbox::class, + ], +]; diff --git a/config/cors.php b/config/cors.php new file mode 100644 index 0000000..8a39e6d --- /dev/null +++ b/config/cors.php @@ -0,0 +1,34 @@ + ['api/*', 'sanctum/csrf-cookie'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => [], + + 'max_age' => 0, + + 'supports_credentials' => false, + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..137ad18 --- /dev/null +++ b/config/database.php @@ -0,0 +1,151 @@ + env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DATABASE_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..edb159c --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,85 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been set up for each driver as an example of the required values. + | + | Supported Drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + 'throw' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + ], + + 'key-pairs-local' => [ + 'driver' => 'local', + 'root' => storage_path('app/key-pairs'), + ], + + 'server-logs-local' => [ + 'driver' => 'local', + 'root' => storage_path('app/server-logs'), + ], + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/config/hashing.php b/config/hashing.php new file mode 100644 index 0000000..bcd3be4 --- /dev/null +++ b/config/hashing.php @@ -0,0 +1,52 @@ + 'bcrypt', + + /* + |-------------------------------------------------------------------------- + | Bcrypt Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Bcrypt algorithm. This will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'bcrypt' => [ + 'rounds' => env('BCRYPT_ROUNDS', 10), + ], + + /* + |-------------------------------------------------------------------------- + | Argon Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Argon algorithm. These will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'argon' => [ + 'memory' => 65536, + 'threads' => 1, + 'time' => 4, + ], + +]; diff --git a/config/logging.php b/config/logging.php new file mode 100644 index 0000000..c44d276 --- /dev/null +++ b/config/logging.php @@ -0,0 +1,131 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => false, + ], + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", + | "custom", "stack" + | + */ + + 'channels' => [ + 'stack' => [ + 'driver' => 'stack', + 'channels' => ['single'], + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => 14, + 'replace_placeholders' => true, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => 'Laravel Log', + 'emoji' => ':boom:', + 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => LOG_USER, + 'replace_placeholders' => true, + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + ], + +]; diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..542d98c --- /dev/null +++ b/config/mail.php @@ -0,0 +1,124 @@ + env('MAIL_MAILER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers to be used while + | sending an e-mail. You will specify which one you are using for your + | mailers below. You are free to add additional mailers as required. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "log", "array", "failover" + | + */ + + 'mailers' => [ + 'smtp' => [ + 'transport' => 'smtp', + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + 'port' => env('MAIL_PORT', 587), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN'), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'mailgun' => [ + 'transport' => 'mailgun', + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'postmark' => [ + 'transport' => 'postmark', + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + + /* + |-------------------------------------------------------------------------- + | Markdown Mail Settings + |-------------------------------------------------------------------------- + | + | If you are using Markdown based email rendering, you may configure your + | theme and component paths here, allowing you to customize the design + | of the emails. Or, you may simply stick with the Laravel defaults! + | + */ + + 'markdown' => [ + 'theme' => 'default', + + 'paths' => [ + resource_path('views/vendor/mail'), + ], + ], + +]; diff --git a/config/queue.php b/config/queue.php new file mode 100755 index 0000000..541e164 --- /dev/null +++ b/config/queue.php @@ -0,0 +1,89 @@ + env('QUEUE_CONNECTION', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => 600, + 'block_for' => null, + 'after_commit' => false, + ], + + 'default' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'timeout' => 90, + 'retry_after' => 600, + ], + + 'ssh' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'ssh', + 'timeout' => 240, + 'retry_after' => 600, + ], + + 'ssh-long' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'ssh-long', + 'timeout' => 600, + 'retry_after' => 600, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/sanctum.php b/config/sanctum.php new file mode 100644 index 0000000..529cfdc --- /dev/null +++ b/config/sanctum.php @@ -0,0 +1,67 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort() + ))), + + /* + |-------------------------------------------------------------------------- + | Sanctum Guards + |-------------------------------------------------------------------------- + | + | This array contains the authentication guards that will be checked when + | Sanctum is trying to authenticate a request. If none of these guards + | are able to authenticate the request, Sanctum will use the bearer + | token that's present on an incoming request for authentication. + | + */ + + 'guard' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. If this value is null, personal access tokens do + | not expire. This won't tweak the lifetime of first-party sessions. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, + 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, + ], + +]; diff --git a/config/serverproviders.php b/config/serverproviders.php new file mode 100644 index 0000000..13050a0 --- /dev/null +++ b/config/serverproviders.php @@ -0,0 +1,821 @@ + [ + 'plans' => [ + [ + 'title' => '[t2 nano] 512MB RAM - CPU 1 core(s)', + 'value' => 't2.nano', + ], + [ + 'title' => '[t2 micro] 1024MB RAM - CPU 1 core(s)', + 'value' => 't2.micro', + ], + [ + 'title' => '[t2 small] 2048MB RAM - CPU 1 core(s)', + 'value' => 't2.small', + ], + [ + 'title' => '[t2 medium] 4096MB RAM - CPU 2 core(s)', + 'value' => 't2.medium', + ], + [ + 'title' => '[t2 large] 8192MB RAM - CPU 2 core(s)', + 'value' => 't2.large', + ], + [ + 'title' => '[t2 xlarge] 16384MB RAM - CPU 4 core(s)', + 'value' => 't2.xlarge', + ], + [ + 'title' => '[t2 2xlarge] 32768MB RAM - CPU 8 core(s)', + 'value' => 't2.2xlarge', + ], + [ + 'title' => '[t3a nano] 512MB RAM - CPU 2 core(s)', + 'value' => 't3a.nano', + ], + [ + 'title' => '[t3a micro] 1024MB RAM - CPU 2 core(s)', + 'value' => 't3a.micro', + ], + [ + 'title' => '[t3a small] 2048MB RAM - CPU 2 core(s)', + 'value' => 't3a.small', + ], + [ + 'title' => '[t3a medium] 4096MB RAM - CPU 2 core(s)', + 'value' => 't3a.medium', + ], + [ + 'title' => '[t3a large] 8192MB RAM - CPU 2 core(s)', + 'value' => 't3a.large', + ], + [ + 'title' => '[t3a xlarge] 16384MB RAM - CPU 4 core(s)', + 'value' => 't3a.xlarge', + ], + ], + 'regions' => [ + [ + 'title' => 'US East (N. Virginia) (us-east-1)', + 'value' => 'us-east-1', + ], + [ + 'title' => 'US East (Ohio) (us-east-2)', + 'value' => 'us-east-2', + ], + [ + 'title' => 'US West (N. California) (us-west-1)', + 'value' => 'us-west-1', + ], + [ + 'title' => 'US West (Oregon) (us-west-2)', + 'value' => 'us-west-2', + ], + [ + 'title' => 'Asia Pacific (Hong Kong) (ap-east-1)', + 'value' => 'ap-east-1', + ], + [ + 'title' => 'Asia Pacific (Mumbai) (ap-south-1)', + 'value' => 'ap-south-1', + ], + [ + 'title' => 'Asia Pacific (Singapore) (ap-southeast-1', + 'value' => 'ap-southeast-1', + ], + [ + 'title' => 'Asia Pacific (Seoul) (ap-northeast-2)', + 'value' => 'ap-northeast-2', + ], + [ + 'title' => 'Asia Pacific (Tokyo) (ap-northeast-1)', + 'value' => 'ap-northeast-1', + ], + [ + 'title' => 'Asia Pacific (Sydney) (ap-southeast-2)', + 'value' => 'ap-southeast-2', + ], + [ + 'title' => 'Canada (Central) (ca-central-1)', + 'value' => 'ca-central-1', + ], + [ + 'title' => 'Europe (Frankfurt) (eu-central-1)', + 'value' => 'eu-central-1', + ], + [ + 'title' => 'Europe (Ireland) (eu-west-1)', + 'value' => 'eu-west-1', + ], + [ + 'title' => 'Europe (London) (eu-west-2)', + 'value' => 'eu-west-2', + ], + [ + 'title' => 'Europe (Paris) (eu-west-3)', + 'value' => 'eu-west-3', + ], + [ + 'title' => 'Europe (Milan) (eu-south-1)', + 'value' => 'eu-south-1', + ], + [ + 'title' => 'Europe (Stockholm) (eu-north-1)', + 'value' => 'eu-north-1', + ], + [ + 'title' => 'Middle East (Bahrain) (me-south-1)', + 'value' => 'me-south-1', + ], + [ + 'title' => 'South America (São Paulo) (sa-east-1)', + 'value' => 'sa-east-1', + ], + [ + 'title' => 'Africa (Cape Town) (af-south-1)', + 'value' => 'af-south-1', + ], + ], + 'images' => [ + 'us-east-1' => [ + 'ubuntu_18' => 'ami-0279c3b3186e54acd', + 'ubuntu_20' => 'ami-083654bd07b5da81d', + ], + 'us-east-2' => [ + 'ubuntu_18' => 'ami-020db2c14939a8efb', + 'ubuntu_20' => 'ami-0629230e074c580f2', + ], + 'us-west-1' => [ + 'ubuntu_18' => 'ami-083f68207d3376798', + 'ubuntu_20' => 'ami-053ac55bdcfe96e85', + ], + 'us-west-2' => [ + 'ubuntu_18' => 'ami-09889d8d54f9e0a0e', + 'ubuntu_20' => 'ami-036d46416a34a611c', + ], + 'ap-east-1' => [ + 'ubuntu_18' => 'ami-032c0a4bd39a5772c', + 'ubuntu_20' => 'ami-0a9c1cc3697104990', + ], + 'ap-south-1' => [ + 'ubuntu_18' => 'ami-00782a7608c7fc226', + 'ubuntu_20' => 'ami-0567e0d2b4b2169ae', + ], + 'ap-northeast-1' => [ + 'ubuntu_18' => 'ami-085e9421f80dbe728', + 'ubuntu_20' => 'ami-036d0684fc96830ca', + ], + 'ap-northeast-2' => [ + 'ubuntu_18' => 'ami-0252a84eb1d66c2a0', + 'ubuntu_20' => 'ami-0f8b8babb98cc66d0', + ], + 'ap-southeast-1' => [ + 'ubuntu_18' => 'ami-0907c2c44ea451f84', + 'ubuntu_20' => 'ami-0fed77069cd5a6d6c', + ], + 'ap-southeast-2' => [ + 'ubuntu_18' => 'ami-00abf0511a7f4cee5', + 'ubuntu_20' => 'ami-0bf8b986de7e3c7ce', + ], + 'ca-central-1' => [ + 'ubuntu_18' => 'ami-0e471deaa43652c4a', + 'ubuntu_20' => 'ami-0bb84e7329f4fa1f7', + ], + 'eu-central-1' => [ + 'ubuntu_18' => 'ami-00d5e377dd7fad751', + 'ubuntu_20' => 'ami-0a49b025fffbbdac6', + ], + 'eu-west-1' => [ + 'ubuntu_18' => 'ami-095b735dce49535b5', + 'ubuntu_20' => 'ami-08edbb0e85d6a0a07', + ], + 'eu-west-2' => [ + 'ubuntu_18' => 'ami-008485ca60c91a0f3', + 'ubuntu_20' => 'ami-0fdf70ed5c34c5f52', + ], + 'eu-west-3' => [ + 'ubuntu_18' => 'ami-0df7d9cc2767d16cd', + 'ubuntu_20' => 'ami-06d79c60d7454e2af', + ], + 'eu-south-1' => [ + 'ubuntu_18' => 'ami-09f165dd6bd167be5', + 'ubuntu_20' => 'ami-0f8ce9c417115413d', + ], + 'eu-north-1' => [ + 'ubuntu_18' => 'ami-038904f9024f34a0c', + 'ubuntu_20' => 'ami-0bd9c26722573e69b', + ], + 'me-south-1' => [ + 'ubuntu_18' => 'ami-0ef669c57b73af73b', + 'ubuntu_20' => 'ami-0b4946d7420c44be4', + ], + 'sa-east-1' => [ + 'ubuntu_18' => 'ami-0ed2b3edeb28afa59', + 'ubuntu_20' => 'ami-0e66f5495b4efdd0f', + ], + 'af-south-1' => [ + 'ubuntu_18' => 'ami-0191bb2cf509687ee', + 'ubuntu_20' => 'ami-0ff86122fd4ad7208', + ], + ], + ], + 'linode' => [ + 'plans' => [ + [ + 'title' => 'Nanode 1GB', + 'value' => 'g6-nanode-1', + ], + [ + 'title' => 'Linode 2GB', + 'value' => 'g6-standard-1', + ], + [ + 'title' => 'Linode 4GB', + 'value' => 'g6-standard-2', + ], + [ + 'title' => 'Linode 8GB', + 'value' => 'g6-standard-4', + ], + [ + 'title' => 'Linode 16GB', + 'value' => 'g6-standard-6', + ], + [ + 'title' => 'Linode 32GB', + 'value' => 'g6-standard-8', + ], + [ + 'title' => 'Linode 64GB', + 'value' => 'g6-standard-16', + ], + [ + 'title' => 'Linode 96GB', + 'value' => 'g6-standard-20', + ], + [ + 'title' => 'Linode 128GB', + 'value' => 'g6-standard-24', + ], + [ + 'title' => 'Linode 192GB', + 'value' => 'g6-standard-32', + ], + [ + 'title' => 'Linode 24GB', + 'value' => 'g7-highmem-1', + ], + [ + 'title' => 'Linode 48GB', + 'value' => 'g7-highmem-2', + ], + [ + 'title' => 'Linode 90GB', + 'value' => 'g7-highmem-4', + ], + [ + 'title' => 'Linode 150GB', + 'value' => 'g7-highmem-8', + ], + [ + 'title' => 'Linode 300GB', + 'value' => 'g7-highmem-16', + ], + [ + 'title' => 'Dedicated 4GB', + 'value' => 'g6-dedicated-2', + ], + [ + 'title' => 'Dedicated 8GB', + 'value' => 'g6-dedicated-4', + ], + [ + 'title' => 'Dedicated 16GB', + 'value' => 'g6-dedicated-8', + ], + [ + 'title' => 'Dedicated 32GB', + 'value' => 'g6-dedicated-16', + ], + [ + 'title' => 'Dedicated 64GB', + 'value' => 'g6-dedicated-32', + ], + [ + 'title' => 'Dedicated 96GB', + 'value' => 'g6-dedicated-48', + ], + [ + 'title' => 'Dedicated 128GB', + 'value' => 'g6-dedicated-50', + ], + [ + 'title' => 'Dedicated 256GB', + 'value' => 'g6-dedicated-56', + ], + [ + 'title' => 'Dedicated 512GB', + 'value' => 'g6-dedicated-64', + ], + [ + 'title' => 'Dedicated 32GB + RTX6000 GPU x1', + 'value' => 'g1-gpu-rtx6000-1', + ], + [ + 'title' => 'Dedicated 64GB + RTX6000 GPU x2', + 'value' => 'g1-gpu-rtx6000-2', + ], + [ + 'title' => 'Dedicated 96GB + RTX6000 GPU x3', + 'value' => 'g1-gpu-rtx6000-3', + ], + [ + 'title' => 'Dedicated 128GB + RTX6000 GPU x4', + 'value' => 'g1-gpu-rtx6000-4', + ], + ], + 'regions' => [ + [ + 'title' => 'ap-west - India', + 'value' => 'ap-west', + ], + [ + 'title' => 'ca-central - Canada', + 'value' => 'ca-central', + ], + [ + 'title' => 'ap-southeast - Australia', + 'value' => 'ap-southeast', + ], + [ + 'title' => 'us-central - United States', + 'value' => 'us-central', + ], + [ + 'title' => 'us-west - United States', + 'value' => 'us-west', + ], + [ + 'title' => 'us-southeast - United States', + 'value' => 'us-southeast', + ], + [ + 'title' => 'us-east - United States', + 'value' => 'us-east', + ], + [ + 'title' => 'eu-west - United Kingdom', + 'value' => 'eu-west', + ], + [ + 'title' => 'ap-south - Singapore', + 'value' => 'ap-south', + ], + [ + 'title' => 'eu-central - Germany', + 'value' => 'eu-central', + ], + [ + 'title' => 'ap-northeast - Japan', + 'value' => 'ap-northeast', + ], + ], + 'images' => [ + 'ubuntu_18' => 'linode/ubuntu18.04', + 'ubuntu_20' => 'linode/ubuntu20.04', + ], + ], + 'digitalocean' => [ + 'plans' => [ + [ + 'title' => '1024MB RAM - CPU 1 core(s) - Disk: 25GB (s-1vcpu-1gb)', + 'value' => 's-1vcpu-1gb', + ], + [ + 'title' => '1024MB RAM - CPU 1 core(s) - Disk: 25GB (s-1vcpu-1gb-amd)', + 'value' => 's-1vcpu-1gb-amd', + ], + [ + 'title' => '1024MB RAM - CPU 1 core(s) - Disk: 25GB (s-1vcpu-1gb-intel)', + 'value' => 's-1vcpu-1gb-intel', + ], + [ + 'title' => '2048MB RAM - CPU 1 core(s) - Disk: 50GB (s-1vcpu-2gb)', + 'value' => 's-1vcpu-2gb', + ], + [ + 'title' => '2048MB RAM - CPU 1 core(s) - Disk: 50GB (s-1vcpu-2gb-amd)', + 'value' => 's-1vcpu-2gb-amd', + ], + [ + 'title' => '2048MB RAM - CPU 1 core(s) - Disk: 50GB (s-1vcpu-2gb-intel)', + 'value' => 's-1vcpu-2gb-intel', + ], + [ + 'title' => '2048MB RAM - CPU 2 core(s) - Disk: 60GB (s-2vcpu-2gb)', + 'value' => 's-2vcpu-2gb', + ], + [ + 'title' => '2048MB RAM - CPU 2 core(s) - Disk: 60GB (s-2vcpu-2gb-amd)', + 'value' => 's-2vcpu-2gb-amd', + ], + [ + 'title' => '2048MB RAM - CPU 2 core(s) - Disk: 60GB (s-2vcpu-2gb-intel)', + 'value' => 's-2vcpu-2gb-intel', + ], + [ + 'title' => '4096MB RAM - CPU 2 core(s) - Disk: 80GB (s-2vcpu-4gb)', + 'value' => 's-2vcpu-4gb', + ], + [ + 'title' => '4096MB RAM - CPU 2 core(s) - Disk: 80GB (s-2vcpu-4gb-amd)', + 'value' => 's-2vcpu-4gb-amd', + ], + [ + 'title' => '4096MB RAM - CPU 2 core(s) - Disk: 80GB (s-2vcpu-4gb-intel)', + 'value' => 's-2vcpu-4gb-intel', + ], + [ + 'title' => '8192MB RAM - CPU 4 core(s) - Disk: 160GB (s-4vcpu-8gb)', + 'value' => 's-4vcpu-8gb', + ], + [ + 'title' => '8192MB RAM - CPU 4 core(s) - Disk: 160GB (s-4vcpu-8gb-amd)', + 'value' => 's-4vcpu-8gb-amd', + ], + [ + 'title' => '8192MB RAM - CPU 4 core(s) - Disk: 160GB (s-4vcpu-8gb-intel)', + 'value' => 's-4vcpu-8gb-intel', + ], + [ + 'title' => '16384MB RAM - CPU 8 core(s) - Disk: 320GB (s-8vcpu-16gb)', + 'value' => 's-8vcpu-16gb', + ], + [ + 'title' => '4096MB RAM - CPU 2 core(s) - Disk: 25GB (c-2)', + 'value' => 'c-2', + ], + [ + 'title' => '4096MB RAM - CPU 2 core(s) - Disk: 50GB (c2-2vcpu-4gb)', + 'value' => 'c2-2vcpu-4gb', + ], + [ + 'title' => '8192MB RAM - CPU 2 core(s) - Disk: 25GB (g-2vcpu-8gb)', + 'value' => 'g-2vcpu-8gb', + ], + [ + 'title' => '8192MB RAM - CPU 2 core(s) - Disk: 50GB (gd-2vcpu-8gb)', + 'value' => 'gd-2vcpu-8gb', + ], + ], + 'regions' => [ + [ + 'title' => 'New York 1', + 'value' => 'nyc1', + ], + [ + 'title' => 'Amsterdam 2', + 'value' => 'ams2', + ], + [ + 'title' => 'Singapore 1', + 'value' => 'sgp1', + ], + [ + 'title' => 'London 1', + 'value' => 'lon1', + ], + [ + 'title' => 'New York 3', + 'value' => 'nyc3', + ], + [ + 'title' => 'Amsterdam 3', + 'value' => 'ams3', + ], + [ + 'title' => 'Frankfurt 1', + 'value' => 'fra1', + ], + [ + 'title' => 'Toronto 1', + 'value' => 'tor1', + ], + [ + 'title' => 'Bangalore 1', + 'value' => 'blr1', + ], + [ + 'title' => 'San Francisco 3', + 'value' => 'sfo3', + ], + ], + 'images' => [ + 'ubuntu_18' => '93524084', + 'ubuntu_20' => '93525508', + ], + ], + 'vultr' => [ + 'plans' => [ + [ + 'title' => '1 CPU - 1024MB Ram - 25GB Disk', + 'value' => 'vc2-1c-1gb', + ], + [ + 'title' => '1 CPU - 2048MB Ram - 55GB Disk', + 'value' => 'vc2-1c-2gb', + ], + [ + 'title' => '2 CPU - 4096MB Ram - 80GB Disk', + 'value' => 'vc2-2c-4gb', + ], + [ + 'title' => '4 CPU - 8192MB Ram - 160GB Disk', + 'value' => 'vc2-4c-8gb', + ], + [ + 'title' => '6 CPU - 16384MB Ram - 320GB Disk', + 'value' => 'vc2-6c-16gb', + ], + [ + 'title' => '8 CPU - 32768MB Ram - 640GB Disk', + 'value' => 'vc2-8c-32gb', + ], + [ + 'title' => '16 CPU - 65536MB Ram - 1280GB Disk', + 'value' => 'vc2-16c-64gb', + ], + [ + 'title' => '24 CPU - 98304MB Ram - 1600GB Disk', + 'value' => 'vc2-24c-96gb', + ], + [ + 'title' => '2 CPU - 8192MB Ram - 110GB Disk', + 'value' => 'vdc-2vcpu-8gb', + ], + [ + 'title' => '4 CPU - 16384MB Ram - 110GB Disk', + 'value' => 'vdc-4vcpu-16gb', + ], + [ + 'title' => '6 CPU - 24576MB Ram - 110GB Disk', + 'value' => 'vdc-6vcpu-24gb', + ], + [ + 'title' => '8 CPU - 32768MB Ram - 110GB Disk', + 'value' => 'vdc-8vcpu-32gb', + ], + [ + 'title' => '1 CPU - 1024MB Ram - 32GB Disk', + 'value' => 'vhf-1c-1gb', + ], + [ + 'title' => '1 CPU - 2048MB Ram - 64GB Disk', + 'value' => 'vhf-1c-2gb', + ], + [ + 'title' => '2 CPU - 2048MB Ram - 80GB Disk', + 'value' => 'vhf-2c-2gb', + ], + [ + 'title' => '2 CPU - 4096MB Ram - 128GB Disk', + 'value' => 'vhf-2c-4gb', + ], + [ + 'title' => '3 CPU - 8192MB Ram - 256GB Disk', + 'value' => 'vhf-3c-8gb', + ], + [ + 'title' => '4 CPU - 16384MB Ram - 384GB Disk', + 'value' => 'vhf-4c-16gb', + ], + [ + 'title' => '6 CPU - 24576MB Ram - 448GB Disk', + 'value' => 'vhf-6c-24gb', + ], + [ + 'title' => '8 CPU - 32768MB Ram - 512GB Disk', + 'value' => 'vhf-8c-32gb', + ], + [ + 'title' => '12 CPU - 49152MB Ram - 768GB Disk', + 'value' => 'vhf-12c-48gb', + ], + ], + 'regions' => [ + [ + 'title' => 'Europe - Amsterdam', + 'value' => 'ams', + ], + [ + 'title' => 'North America - Atlanta', + 'value' => 'atl', + ], + [ + 'title' => 'Europe - Paris', + 'value' => 'cdg', + ], + [ + 'title' => 'North America - Dallas', + 'value' => 'dfw', + ], + [ + 'title' => 'North America - New Jersey', + 'value' => 'ewr', + ], + [ + 'title' => 'Europe - Frankfurt', + 'value' => 'fra', + ], + [ + 'title' => 'Asia - Seoul', + 'value' => 'icn', + ], + [ + 'title' => 'North America - Los Angeles', + 'value' => 'lax', + ], + [ + 'title' => 'Europe - London', + 'value' => 'lhr', + ], + [ + 'title' => 'North America - Mexico City', + 'value' => 'mex', + ], + [ + 'title' => 'North America - Miami', + 'value' => 'mia', + ], + [ + 'title' => 'Asia - Tokyo', + 'value' => 'nrt', + ], + [ + 'title' => 'North America - Chicago', + 'value' => 'ord', + ], + [ + 'title' => 'North America - Seattle', + 'value' => 'sea', + ], + [ + 'title' => 'Asia - Singapore', + 'value' => 'sgp', + ], + [ + 'title' => 'North America - Silicon Valley', + 'value' => 'sjc', + ], + [ + 'title' => 'Europe - Stockholm', + 'value' => 'sto', + ], + [ + 'title' => 'Australia - Sydney', + 'value' => 'syd', + ], + [ + 'title' => 'North America - Toronto', + 'value' => 'yto', + ], + ], + 'images' => [ + 'ubuntu_18' => '270', + 'ubuntu_20' => '387', + ], + ], + 'hetzner' => [ + 'plans' => [ + [ + 'title' => 'CX11 - 1 Cores - 2 Memory - 20 Disk', + 'value' => 'cx11', + ], + [ + 'title' => 'CX21 - 2 Cores - 4 Memory - 40 Disk', + 'value' => 'cx21', + ], + [ + 'title' => 'CX31 - 2 Cores - 8 Memory - 80 Disk', + 'value' => 'cx31', + ], + [ + 'title' => 'CX41 - 4 Cores - 16 Memory - 160 Disk', + 'value' => 'cx41', + ], + [ + 'title' => 'CX51 - 8 Cores - 32 Memory - 240 Disk', + 'value' => 'cx51', + ], + [ + 'title' => 'CCX11 Dedicated CPU - 2 Cores - 8 Memory - 80 Disk', + 'value' => 'ccx11', + ], + [ + 'title' => 'CCX21 Dedicated CPU - 4 Cores - 16 Memory - 160 Disk', + 'value' => 'ccx21', + ], + [ + 'title' => 'CCX31 Dedicated CPU - 8 Cores - 32 Memory - 240 Disk', + 'value' => 'ccx31', + ], + [ + 'title' => 'CCX41 Dedicated CPU - 16 Cores - 64 Memory - 360 Disk', + 'value' => 'ccx41', + ], + [ + 'title' => 'CCX51 Dedicated CPU - 32 Cores - 128 Memory - 600 Disk', + 'value' => 'ccx51', + ], + [ + 'title' => 'CPX 11 - 2 Cores - 2 Memory - 40 Disk', + 'value' => 'cpx11', + ], + [ + 'title' => 'CPX 21 - 3 Cores - 4 Memory - 80 Disk', + 'value' => 'cpx21', + ], + [ + 'title' => 'CPX 31 - 4 Cores - 8 Memory - 160 Disk', + 'value' => 'cpx31', + ], + [ + 'title' => 'CPX 41 - 8 Cores - 16 Memory - 240 Disk', + 'value' => 'cpx41', + ], + [ + 'title' => 'CPX 51 - 16 Cores - 32 Memory - 360 Disk', + 'value' => 'cpx51', + ], + [ + 'title' => 'CCX12 Dedicated CPU - 2 Cores - 8 Memory - 80 Disk', + 'value' => 'ccx12', + ], + [ + 'title' => 'CCX22 Dedicated CPU - 4 Cores - 16 Memory - 160 Disk', + 'value' => 'ccx22', + ], + [ + 'title' => 'CCX32 Dedicated CPU - 8 Cores - 32 Memory - 240 Disk', + 'value' => 'ccx32', + ], + [ + 'title' => 'CCX42 Dedicated CPU - 16 Cores - 64 Memory - 360 Disk', + 'value' => 'ccx42', + ], + [ + 'title' => 'CCX52 Dedicated CPU - 32 Cores - 128 Memory - 600 Disk', + 'value' => 'ccx52', + ], + [ + 'title' => 'CCX62 Dedicated CPU - 48 Cores - 192 Memory - 960 Disk', + 'value' => 'ccx62', + ], + [ + 'title' => 'CAX11 - 2 Cores - 4 Memory - 40 Disk', + 'value' => 'cax11', + ], + [ + 'title' => 'CAX21 - 4 Cores - 8 Memory - 80 Disk', + 'value' => 'cax21', + ], + [ + 'title' => 'CAX31 - 8 Cores - 16 Memory - 160 Disk', + 'value' => 'cax31', + ], + [ + 'title' => 'CAX41 - 16 Cores - 32 Memory - 320 Disk', + 'value' => 'cax41', + ], + ], + 'regions' => [ + [ + 'title' => 'DE - Falkenstein', + 'value' => 'fsn1', + ], + [ + 'title' => 'DE - Nuremberg', + 'value' => 'nbg1', + ], + [ + 'title' => 'FI - Helsinki', + 'value' => 'hel1', + ], + [ + 'title' => 'US - Ashburn, VA', + 'value' => 'ash', + ], + [ + 'title' => 'US - Hillsboro, OR', + 'value' => 'hil', + ], + ], + 'images' => [ + 'ubuntu_18' => 'ubuntu-18.04', + 'ubuntu_20' => 'ubuntu-20.04', + 'ubuntu_22' => 'ubuntu-22.04', + ], + ], +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..0ace530 --- /dev/null +++ b/config/services.php @@ -0,0 +1,34 @@ + [ + 'domain' => env('MAILGUN_DOMAIN'), + 'secret' => env('MAILGUN_SECRET'), + 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), + 'scheme' => 'https', + ], + + 'postmark' => [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..8fed97c --- /dev/null +++ b/config/session.php @@ -0,0 +1,201 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | While using one of the framework's cache driven session backends you may + | list a cache store that should be used for these sessions. This value + | must match with one of the application's configured cache "stores". + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" since this is a secure default value. + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => 'lax', + +]; diff --git a/config/telescope.php b/config/telescope.php new file mode 100644 index 0000000..9a09fda --- /dev/null +++ b/config/telescope.php @@ -0,0 +1,187 @@ + env('TELESCOPE_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | Telescope Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Telescope will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => env('TELESCOPE_PATH', 'telescope'), + + /* + |-------------------------------------------------------------------------- + | Telescope Storage Driver + |-------------------------------------------------------------------------- + | + | This configuration options determines the storage driver that will + | be used to store Telescope's data. In addition, you may set any + | custom options as needed by the particular driver you choose. + | + */ + + 'driver' => env('TELESCOPE_DRIVER', 'database'), + + 'storage' => [ + 'database' => [ + 'connection' => env('DB_CONNECTION', 'mysql'), + 'chunk' => 1000, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Master Switch + |-------------------------------------------------------------------------- + | + | This option may be used to disable all Telescope watchers regardless + | of their individual configuration, which simply provides a single + | and convenient way to enable or disable Telescope data storage. + | + */ + + 'enabled' => env('TELESCOPE_ENABLED', true), + + /* + |-------------------------------------------------------------------------- + | Telescope Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will be assigned to every Telescope route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + Authorize::class, + ], + + /* + |-------------------------------------------------------------------------- + | Allowed / Ignored Paths & Commands + |-------------------------------------------------------------------------- + | + | The following array lists the URI paths and Artisan commands that will + | not be watched by Telescope. In addition to this list, some Laravel + | commands, like migrations and queue commands, are always ignored. + | + */ + + 'only_paths' => [ + // 'api/*' + ], + + 'ignore_paths' => [ + 'nova-api*', + ], + + 'ignore_commands' => [ + // + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Watchers + |-------------------------------------------------------------------------- + | + | The following array lists the "watchers" that will be registered with + | Telescope. The watchers gather the application's profile data when + | a request or task is executed. Feel free to customize this list. + | + */ + + 'watchers' => [ + Watchers\BatchWatcher::class => env('TELESCOPE_BATCH_WATCHER', true), + + Watchers\CacheWatcher::class => [ + 'enabled' => env('TELESCOPE_CACHE_WATCHER', true), + 'hidden' => [], + ], + + Watchers\ClientRequestWatcher::class => env('TELESCOPE_CLIENT_REQUEST_WATCHER', true), + + Watchers\CommandWatcher::class => [ + 'enabled' => env('TELESCOPE_COMMAND_WATCHER', true), + 'ignore' => [], + ], + + Watchers\DumpWatcher::class => [ + 'enabled' => env('TELESCOPE_DUMP_WATCHER', true), + 'always' => env('TELESCOPE_DUMP_WATCHER_ALWAYS', false), + ], + + Watchers\EventWatcher::class => [ + 'enabled' => env('TELESCOPE_EVENT_WATCHER', true), + 'ignore' => [], + ], + + Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true), + + Watchers\GateWatcher::class => [ + 'enabled' => env('TELESCOPE_GATE_WATCHER', true), + 'ignore_abilities' => [], + 'ignore_packages' => true, + 'ignore_paths' => [], + ], + + Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true), + + Watchers\LogWatcher::class => [ + 'enabled' => env('TELESCOPE_LOG_WATCHER', true), + 'level' => 'error', + ], + + Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true), + + Watchers\ModelWatcher::class => [ + 'enabled' => env('TELESCOPE_MODEL_WATCHER', true), + 'events' => ['eloquent.*'], + 'hydrations' => true, + ], + + Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true), + + Watchers\QueryWatcher::class => [ + 'enabled' => env('TELESCOPE_QUERY_WATCHER', true), + 'ignore_packages' => true, + 'ignore_paths' => [], + 'slow' => 100, + ], + + Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true), + + Watchers\RequestWatcher::class => [ + 'enabled' => env('TELESCOPE_REQUEST_WATCHER', true), + 'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64), + 'ignore_http_methods' => [], + 'ignore_status_codes' => [], + ], + + Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true), + Watchers\ViewWatcher::class => env('TELESCOPE_VIEW_WATCHER', true), + ], +]; diff --git a/config/view.php b/config/view.php new file mode 100644 index 0000000..22b8a18 --- /dev/null +++ b/config/view.php @@ -0,0 +1,36 @@ + [ + resource_path('views'), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => env( + 'VIEW_COMPILED_PATH', + realpath(storage_path('framework/views')) + ), + +]; diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..9b19b93 --- /dev/null +++ b/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/database/factories/BackupFactory.php b/database/factories/BackupFactory.php new file mode 100644 index 0000000..14ed950 --- /dev/null +++ b/database/factories/BackupFactory.php @@ -0,0 +1,15 @@ + 'ls -la', + 'user' => 'root', + 'frequency' => '* * * * *', + 'hidden' => false, + 'status' => CronjobStatus::READY, + ]; + } +} diff --git a/database/factories/DatabaseFactory.php b/database/factories/DatabaseFactory.php new file mode 100755 index 0000000..9c335f0 --- /dev/null +++ b/database/factories/DatabaseFactory.php @@ -0,0 +1,20 @@ + $this->faker->userName, + 'status' => DatabaseStatus::READY, + ]; + } +} diff --git a/database/factories/DatabaseUserFactory.php b/database/factories/DatabaseUserFactory.php new file mode 100755 index 0000000..d6ca9cd --- /dev/null +++ b/database/factories/DatabaseUserFactory.php @@ -0,0 +1,21 @@ + $this->faker->userName, + 'password' => 'password', + 'databases' => [], + 'host' => '%', + ]; + } +} diff --git a/database/factories/DeploymentFactory.php b/database/factories/DeploymentFactory.php new file mode 100755 index 0000000..927ddb1 --- /dev/null +++ b/database/factories/DeploymentFactory.php @@ -0,0 +1,18 @@ + $this->faker->name(), + 'content' => $this->faker->word(), + 'created_at' => Carbon::now(), + 'updated_at' => Carbon::now(), + 'site_id' => Site::factory(), + ]; + } +} diff --git a/database/factories/FirewallRuleFactory.php b/database/factories/FirewallRuleFactory.php new file mode 100644 index 0000000..13e8aa0 --- /dev/null +++ b/database/factories/FirewallRuleFactory.php @@ -0,0 +1,23 @@ + 'allow', + 'protocol' => 'tcp', + 'port' => $this->faker->numberBetween(1, 65535), + 'source' => $this->faker->ipv4(), + 'mask' => 24, + 'note' => 'test', + ]; + } +} diff --git a/database/factories/NotificationChannelFactory.php b/database/factories/NotificationChannelFactory.php new file mode 100644 index 0000000..39e3a87 --- /dev/null +++ b/database/factories/NotificationChannelFactory.php @@ -0,0 +1,20 @@ + $this->faker->text(10), + 'provider' => 'email', + 'data' => [ + 'email' => $this->faker->email, + ], + 'connected' => 1, + ]; + } +} diff --git a/database/factories/QueueFactory.php b/database/factories/QueueFactory.php new file mode 100644 index 0000000..acfd3ae --- /dev/null +++ b/database/factories/QueueFactory.php @@ -0,0 +1,26 @@ + 'php artisan queue:work', + 'user' => 'vito', + 'auto_start' => 1, + 'auto_restart' => 1, + 'numprocs' => 1, + 'redirect_stderr' => 1, + 'stdout_logfile' => 'file.log', + 'status' => QueueStatus::CREATING, + ]; + } +} diff --git a/database/factories/RedirectFactory.php b/database/factories/RedirectFactory.php new file mode 100644 index 0000000..b2ab1cf --- /dev/null +++ b/database/factories/RedirectFactory.php @@ -0,0 +1,25 @@ + $this->faker->randomNumber(), + 'mode' => $this->faker->randomNumber(), + 'from' => $this->faker->word(), + 'to' => $this->faker->word(), + 'status' => $this->faker->word(), + 'created_at' => Carbon::now(), + 'updated_at' => Carbon::now(), + ]; + } +} diff --git a/database/factories/ScriptExecutionFactory.php b/database/factories/ScriptExecutionFactory.php new file mode 100644 index 0000000..7140f1a --- /dev/null +++ b/database/factories/ScriptExecutionFactory.php @@ -0,0 +1,26 @@ + $this->faker->word(), + 'finished_at' => Carbon::now(), + 'created_at' => Carbon::now(), + 'updated_at' => Carbon::now(), + 'script_id' => Script::factory(), + 'server_id' => Server::factory(), + ]; + } +} diff --git a/database/factories/ScriptFactory.php b/database/factories/ScriptFactory.php new file mode 100644 index 0000000..983669a --- /dev/null +++ b/database/factories/ScriptFactory.php @@ -0,0 +1,15 @@ +create(); + + return [ + 'user_id' => $user->id, + 'name' => $this->faker->name(), + 'ssh_user' => 'vito', + 'ip' => $this->faker->ipv4(), + 'local_ip' => $this->faker->ipv4(), + 'port' => 22, + 'os' => OperatingSystem::UBUNTU22, + 'type' => ServerType::REGULAR, + 'provider' => ServerProvider::CUSTOM, + 'authentication' => [ + 'user' => 'vito', + 'pass' => 'password', + ], + 'public_key' => 'test', + 'status' => ServerStatus::READY, + 'progress' => 100, + ]; + } +} diff --git a/database/factories/ServerLogFactory.php b/database/factories/ServerLogFactory.php new file mode 100644 index 0000000..7ada3d1 --- /dev/null +++ b/database/factories/ServerLogFactory.php @@ -0,0 +1,21 @@ + 'test-log', + 'name' => 'test.log', + 'disk' => 'server-logs-local', + ]; + } +} diff --git a/database/factories/ServerProviderFactory.php b/database/factories/ServerProviderFactory.php new file mode 100644 index 0000000..9eb3c21 --- /dev/null +++ b/database/factories/ServerProviderFactory.php @@ -0,0 +1,23 @@ + $this->faker->word(), + 'provider' => $this->faker->randomElement(\App\Enums\ServerProvider::getValues()), + 'credentials' => [], + 'connected' => 1, + 'user_id' => User::factory(), + ]; + } +} diff --git a/database/factories/ServiceFactory.php b/database/factories/ServiceFactory.php new file mode 100644 index 0000000..b7d41f0 --- /dev/null +++ b/database/factories/ServiceFactory.php @@ -0,0 +1,19 @@ + SiteType::LARAVEL, + 'domain' => 'test.com', + 'web_directory' => '/', + 'path' => '/home', + 'status' => 'ready', + 'progress' => '100', + 'php_version' => '8.2', + 'branch' => 'main' + ]; + } +} diff --git a/database/factories/SourceControlFactory.php b/database/factories/SourceControlFactory.php new file mode 100644 index 0000000..e0d3fb2 --- /dev/null +++ b/database/factories/SourceControlFactory.php @@ -0,0 +1,20 @@ + $this->faker->randomElement(\App\Enums\SourceControl::getValues()), + 'access_token' => Str::random(10), + ]; + } +} diff --git a/database/factories/SshKeyFactory.php b/database/factories/SshKeyFactory.php new file mode 100644 index 0000000..153a22c --- /dev/null +++ b/database/factories/SshKeyFactory.php @@ -0,0 +1,20 @@ + $this->faker->name(), + 'public_key' => 'public-key-content', + ]; + } +} diff --git a/database/factories/SslFactory.php b/database/factories/SslFactory.php new file mode 100644 index 0000000..3e73347 --- /dev/null +++ b/database/factories/SslFactory.php @@ -0,0 +1,26 @@ + $this->faker->word(), + 'certificate' => $this->faker->word(), + 'pk' => $this->faker->word(), + 'ca' => $this->faker->word(), + 'expires_at' => Carbon::now()->addDay(), + 'status' => SslStatus::CREATED, + 'domains' => 'example.com', + ]; + } +} diff --git a/database/factories/StorageProviderFactory.php b/database/factories/StorageProviderFactory.php new file mode 100644 index 0000000..6db29d1 --- /dev/null +++ b/database/factories/StorageProviderFactory.php @@ -0,0 +1,15 @@ + $this->faker->name(), + 'email' => $this->faker->unique()->safeEmail(), + 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'remember_token' => Str::random(10), + 'timezone' => 'UTC', + ]; + } +} diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php new file mode 100755 index 0000000..c97e64f --- /dev/null +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->string('password'); + $table->rememberToken(); + $table->string('profile_photo_path', 2048)->nullable(); + $table->text('two_factor_secret')->nullable(); + $table->text('two_factor_recovery_codes')->nullable(); + $table->string('timezone')->default('UTC'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('users'); + } +} diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php new file mode 100755 index 0000000..e4e4106 --- /dev/null +++ b/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -0,0 +1,22 @@ +string('email')->index(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } + + public function down(): void + { + Schema::dropIfExists('password_reset_tokens'); + } +} diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php new file mode 100644 index 0000000..85264d8 --- /dev/null +++ b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php @@ -0,0 +1,26 @@ +id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + public function down(): void + { + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100644 index 0000000..b30c323 --- /dev/null +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,27 @@ +id(); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/migrations/2021_06_23_192743_create_sessions_table.php b/database/migrations/2021_06_23_192743_create_sessions_table.php new file mode 100755 index 0000000..2d0c288 --- /dev/null +++ b/database/migrations/2021_06_23_192743_create_sessions_table.php @@ -0,0 +1,25 @@ +string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->text('payload'); + $table->integer('last_activity')->index(); + }); + } + + public function down(): void + { + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/migrations/2021_06_23_211827_create_servers_table.php b/database/migrations/2021_06_23_211827_create_servers_table.php new file mode 100755 index 0000000..3425381 --- /dev/null +++ b/database/migrations/2021_06_23_211827_create_servers_table.php @@ -0,0 +1,38 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->string('name')->index(); + $table->string('ssh_user')->nullable(); + $table->ipAddress('ip')->index()->nullable(); + $table->ipAddress('local_ip')->nullable(); + $table->unsignedInteger('provider_id')->nullable(); + $table->integer('port')->default(22); + $table->string('os'); + $table->string('type'); + $table->json('type_data')->nullable(); + $table->string('provider'); + $table->json('provider_data')->nullable(); + $table->longText('authentication')->nullable(); + $table->longText('public_key')->nullable(); + $table->string('status')->default('installing'); + $table->tinyInteger('progress')->default(0); + $table->string('progress_step')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('servers'); + } +}; diff --git a/database/migrations/2021_06_23_214143_create_services_table.php b/database/migrations/2021_06_23_214143_create_services_table.php new file mode 100755 index 0000000..360db98 --- /dev/null +++ b/database/migrations/2021_06_23_214143_create_services_table.php @@ -0,0 +1,30 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->string('type'); + $table->json('type_data')->nullable(); + $table->string('name'); + $table->string('version'); + $table->enum('status', ServiceStatus::getValues())->default(ServiceStatus::INSTALLING); + $table->boolean('is_default')->default(1); + $table->string('unit')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('services'); + } +}; diff --git a/database/migrations/2021_06_25_102220_create_jobs_table.php b/database/migrations/2021_06_25_102220_create_jobs_table.php new file mode 100755 index 0000000..cb4e878 --- /dev/null +++ b/database/migrations/2021_06_25_102220_create_jobs_table.php @@ -0,0 +1,26 @@ +bigIncrements('id'); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + } + + public function down(): void + { + Schema::dropIfExists('jobs'); + } +}; diff --git a/database/migrations/2021_06_25_124831_create_server_logs_table.php b/database/migrations/2021_06_25_124831_create_server_logs_table.php new file mode 100755 index 0000000..e84db4e --- /dev/null +++ b/database/migrations/2021_06_25_124831_create_server_logs_table.php @@ -0,0 +1,26 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->unsignedBigInteger('site_id')->nullable(); + $table->string('type'); + $table->string('name'); + $table->string('disk'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('server_logs'); + } +}; diff --git a/database/migrations/2021_06_26_211903_create_sites_table.php b/database/migrations/2021_06_26_211903_create_sites_table.php new file mode 100755 index 0000000..5944aa3 --- /dev/null +++ b/database/migrations/2021_06_26_211903_create_sites_table.php @@ -0,0 +1,35 @@ +id(); + $table->unsignedBigInteger('server_id')->index(); + $table->string('type'); + $table->json('type_data')->nullable(); + $table->string('domain')->index(); + $table->json('aliases')->nullable(); + $table->string('web_directory')->nullable(); + $table->string('path'); + $table->string('php_version')->nullable(); + $table->string('source_control')->nullable(); + $table->string('repository')->nullable(); + $table->string('branch')->nullable(); + $table->integer('port')->nullable(); + $table->string('status')->default('installing'); + $table->tinyInteger('progress')->default(0); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('sites'); + } +}; diff --git a/database/migrations/2021_06_28_085814_create_source_controls_table.php b/database/migrations/2021_06_28_085814_create_source_controls_table.php new file mode 100755 index 0000000..23a9b69 --- /dev/null +++ b/database/migrations/2021_06_28_085814_create_source_controls_table.php @@ -0,0 +1,23 @@ +id(); + $table->string('provider'); + $table->longText('access_token'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('source_controls'); + } +}; diff --git a/database/migrations/2021_07_02_065815_create_deployments_table.php b/database/migrations/2021_07_02_065815_create_deployments_table.php new file mode 100755 index 0000000..1e11391 --- /dev/null +++ b/database/migrations/2021_07_02_065815_create_deployments_table.php @@ -0,0 +1,28 @@ +id(); + $table->unsignedBigInteger('site_id'); + $table->unsignedBigInteger('deployment_script_id'); + $table->unsignedInteger('log_id')->nullable(); + $table->json('commit_data')->nullable(); + $table->string('commit_id')->nullable(); + $table->enum('status', DeploymentStatus::getValues()); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('deployments'); + } +}; diff --git a/database/migrations/2021_07_03_133319_create_databases_table.php b/database/migrations/2021_07_03_133319_create_databases_table.php new file mode 100755 index 0000000..62f5a0d --- /dev/null +++ b/database/migrations/2021_07_03_133319_create_databases_table.php @@ -0,0 +1,25 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->string('name'); + $table->enum('status', DatabaseStatus::getValues())->default(DatabaseStatus::CREATING); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('databases'); + } +}; diff --git a/database/migrations/2021_07_03_133327_create_database_users_table.php b/database/migrations/2021_07_03_133327_create_database_users_table.php new file mode 100755 index 0000000..c829f74 --- /dev/null +++ b/database/migrations/2021_07_03_133327_create_database_users_table.php @@ -0,0 +1,28 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->string('username'); + $table->longText('password')->nullable(); + $table->json('databases')->nullable(); + $table->string('host')->default('localhost'); + $table->enum('status', DatabaseUserStatus::getValues())->default(DatabaseUserStatus::CREATING); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('database_users'); + } +}; diff --git a/database/migrations/2021_07_15_090830_create_firewall_rules_table.php b/database/migrations/2021_07_15_090830_create_firewall_rules_table.php new file mode 100755 index 0000000..ac13e58 --- /dev/null +++ b/database/migrations/2021_07_15_090830_create_firewall_rules_table.php @@ -0,0 +1,29 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->string('type'); + $table->string('protocol'); + $table->integer('port'); + $table->ipAddress('source')->default('0.0.0.0'); + $table->tinyInteger('mask')->default(0); + $table->text('note')->nullable(); + $table->string('status')->default('creating'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('firewall_rules'); + } +}; diff --git a/database/migrations/2021_07_30_204454_create_cron_jobs_table.php b/database/migrations/2021_07_30_204454_create_cron_jobs_table.php new file mode 100755 index 0000000..106093b --- /dev/null +++ b/database/migrations/2021_07_30_204454_create_cron_jobs_table.php @@ -0,0 +1,28 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->text('command'); + $table->string('user'); + $table->string('frequency'); + $table->boolean('hidden')->default(0); + $table->enum('status', CronjobStatus::getValues()); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('cron_jobs'); + } +}; diff --git a/database/migrations/2021_08_13_213657_create_deployment_scripts_table.php b/database/migrations/2021_08_13_213657_create_deployment_scripts_table.php new file mode 100644 index 0000000..cbc401f --- /dev/null +++ b/database/migrations/2021_08_13_213657_create_deployment_scripts_table.php @@ -0,0 +1,24 @@ +id(); + $table->unsignedBigInteger('site_id'); + $table->string('name')->nullable(); + $table->longText('content')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('deployment_scripts'); + } +}; diff --git a/database/migrations/2021_08_14_165326_create_ssls_table.php b/database/migrations/2021_08_14_165326_create_ssls_table.php new file mode 100644 index 0000000..020e297 --- /dev/null +++ b/database/migrations/2021_08_14_165326_create_ssls_table.php @@ -0,0 +1,30 @@ +id(); + $table->unsignedBigInteger('site_id'); + $table->string('type')->default('letsencrypt'); + $table->string('domains')->nullable(); + $table->longText('certificate')->nullable(); + $table->longText('pk')->nullable(); + $table->longText('ca')->nullable(); + $table->timestamp('expires_at'); + $table->enum('status', SslStatus::getValues()); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('ssls'); + } +}; diff --git a/database/migrations/2021_08_26_055643_create_redirects_table.php b/database/migrations/2021_08_26_055643_create_redirects_table.php new file mode 100644 index 0000000..3924166 --- /dev/null +++ b/database/migrations/2021_08_26_055643_create_redirects_table.php @@ -0,0 +1,26 @@ +id(); + $table->unsignedBigInteger('site_id'); + $table->integer('mode'); + $table->text('from'); + $table->text('to'); + $table->string('status')->default('creating'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('redirects'); + } +}; diff --git a/database/migrations/2021_08_27_064512_create_queues_table.php b/database/migrations/2021_08_27_064512_create_queues_table.php new file mode 100644 index 0000000..9937464 --- /dev/null +++ b/database/migrations/2021_08_27_064512_create_queues_table.php @@ -0,0 +1,32 @@ +id(); + $table->unsignedInteger('server_id')->nullable(); + $table->unsignedBigInteger('site_id'); + $table->text('command'); + $table->string('user'); + $table->boolean('auto_start')->default(1); + $table->boolean('auto_restart')->default(1); + $table->tinyInteger('numprocs')->default(8); + $table->boolean('redirect_stderr')->default(1); + $table->string('stdout_logfile')->nullable(); + $table->enum('status', QueueStatus::getValues()); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('queues'); + } +}; diff --git a/database/migrations/2021_08_29_210204_create_ssh_keys_table.php b/database/migrations/2021_08_29_210204_create_ssh_keys_table.php new file mode 100644 index 0000000..0d16882 --- /dev/null +++ b/database/migrations/2021_08_29_210204_create_ssh_keys_table.php @@ -0,0 +1,24 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->string('name'); + $table->longText('public_key'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('ssh_keys'); + } +}; diff --git a/database/migrations/2021_08_30_174511_create_server_ssh_keys_table.php b/database/migrations/2021_08_30_174511_create_server_ssh_keys_table.php new file mode 100644 index 0000000..6c91a28 --- /dev/null +++ b/database/migrations/2021_08_30_174511_create_server_ssh_keys_table.php @@ -0,0 +1,25 @@ +id(); + $table->unsignedBigInteger('server_id'); + $table->unsignedBigInteger('ssh_key_id'); + $table->enum('status', SshKeyStatus::getValues()); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('server_ssh_keys'); + } +}; diff --git a/database/migrations/2021_11_12_093030_create_git_hooks_table.php b/database/migrations/2021_11_12_093030_create_git_hooks_table.php new file mode 100644 index 0000000..d0f59c2 --- /dev/null +++ b/database/migrations/2021_11_12_093030_create_git_hooks_table.php @@ -0,0 +1,28 @@ +id(); + $table->unsignedBigInteger('site_id'); + $table->unsignedBigInteger('source_control_id'); + $table->string('secret')->unique()->index(); + $table->json('events'); + $table->json('actions'); + $table->string('hook_id')->nullable(); + $table->json('hook_response')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('git_hooks'); + } +}; diff --git a/database/migrations/2021_11_14_190808_create_server_providers_table.php b/database/migrations/2021_11_14_190808_create_server_providers_table.php new file mode 100644 index 0000000..a85cad8 --- /dev/null +++ b/database/migrations/2021_11_14_190808_create_server_providers_table.php @@ -0,0 +1,26 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->string('profile')->nullable(); + $table->string('provider'); + $table->longText('credentials'); + $table->boolean('connected')->default(1); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('server_providers'); + } +}; diff --git a/database/migrations/2021_12_09_062430_create_scripts_table.php b/database/migrations/2021_12_09_062430_create_scripts_table.php new file mode 100644 index 0000000..eb97ed6 --- /dev/null +++ b/database/migrations/2021_12_09_062430_create_scripts_table.php @@ -0,0 +1,24 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->string('name'); + $table->longText('content'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('scripts'); + } +}; diff --git a/database/migrations/2021_12_10_204458_create_script_executions_table.php b/database/migrations/2021_12_10_204458_create_script_executions_table.php new file mode 100644 index 0000000..7d1f78a --- /dev/null +++ b/database/migrations/2021_12_10_204458_create_script_executions_table.php @@ -0,0 +1,25 @@ +id(); + $table->unsignedBigInteger('script_id'); + $table->unsignedBigInteger('server_id'); + $table->string('user')->nullable(); + $table->timestamp('finished_at')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('script_executions'); + } +}; diff --git a/database/migrations/2021_12_24_151835_create_notification_channels_table.php b/database/migrations/2021_12_24_151835_create_notification_channels_table.php new file mode 100644 index 0000000..7b85db2 --- /dev/null +++ b/database/migrations/2021_12_24_151835_create_notification_channels_table.php @@ -0,0 +1,26 @@ +id(); + $table->string('provider'); + $table->string('label'); + $table->json('data')->nullable(); + $table->boolean('connected')->default(false); + $table->boolean('is_default')->default(false); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('notification_channels'); + } +}; diff --git a/database/migrations/2022_01_29_183900_create_storage_providers_table.php b/database/migrations/2022_01_29_183900_create_storage_providers_table.php new file mode 100644 index 0000000..b64e856 --- /dev/null +++ b/database/migrations/2022_01_29_183900_create_storage_providers_table.php @@ -0,0 +1,27 @@ +id(); + $table->string('provider'); + $table->string('label')->nullable(); + $table->string('token', 1000)->nullable(); + $table->string('refresh_token', 1000)->nullable(); + $table->boolean('connected')->default(1); + $table->timestamp('token_expires_at')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('storage_providers'); + } +} diff --git a/database/migrations/2022_02_11_085718_create_backups_table.php b/database/migrations/2022_02_11_085718_create_backups_table.php new file mode 100644 index 0000000..c84fa57 --- /dev/null +++ b/database/migrations/2022_02_11_085718_create_backups_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('type'); + $table->string('name'); + $table->unsignedBigInteger('server_id'); + $table->unsignedBigInteger('storage_id'); + $table->unsignedBigInteger('database_id')->nullable(); + $table->string('interval'); + $table->bigInteger('keep_backups'); + $table->string('status'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('backups'); + } +}; diff --git a/database/migrations/2022_02_11_085815_create_backup_files_table.php b/database/migrations/2022_02_11_085815_create_backup_files_table.php new file mode 100644 index 0000000..f08007d --- /dev/null +++ b/database/migrations/2022_02_11_085815_create_backup_files_table.php @@ -0,0 +1,26 @@ +id(); + $table->unsignedInteger('backup_id'); + $table->string('name'); + $table->bigInteger('size')->nullable(); + $table->string('status'); + $table->timestamp('restored_at')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('backup_files'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..b44b1c0 --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,20 @@ +create([ + 'name' => 'Test User', + 'email' => 'user@example.com', + ]); + } +} diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..0d35cdd --- /dev/null +++ b/deploy.sh @@ -0,0 +1,16 @@ +php artisan down + +git pull + +composer install --no-dev + +php artisan migrate --force + +php artisan config:clear +php artisan cache:clear + +php artisan config:cache + +sudo supervisorctl restart worker:* + +php artisan up diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..44bc2e2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,83 @@ +version: '3' +services: + app: + build: + context: ./docker/8.1 + dockerfile: Dockerfile + args: + WWWGROUP: '${WWWGROUP}' + image: vito/app + extra_hosts: + - 'host.docker.internal:host-gateway' + ports: + - '${APP_PORT:-80}:80' + - '${VITE_PORT:-5173}:${VITE_PORT:-5173}' + environment: + WWWUSER: '${WWWUSER}' + LARAVEL_SAIL: 1 + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + volumes: + - '.:/var/www/html' + networks: + - sail + depends_on: + - mysql + worker: + build: + context: ./docker/8.1 + dockerfile: Dockerfile + args: + WWWGROUP: '${WWWGROUP}' + image: vito/app + command: php artisan queue:listen --timeout=600 --queue=default,ssh,ssh-long + extra_hosts: + - 'host.docker.internal:host-gateway' + environment: + WWWUSER: '${WWWUSER}' + LARAVEL_SAIL: 1 + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + volumes: + - '.:/var/www/html' + networks: + - sail + restart: unless-stopped + depends_on: + - mysql + mysql: + image: 'mysql/mysql-server:8.0' + ports: + - '${FORWARD_DB_PORT:-3306}:3306' + environment: + MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' + MYSQL_ROOT_HOST: "%" + MYSQL_DATABASE: '${DB_DATABASE}' + MYSQL_USER: '${DB_USERNAME}' + MYSQL_PASSWORD: '${DB_PASSWORD}' + MYSQL_ALLOW_EMPTY_PASSWORD: 1 + volumes: + - 'sail-mysql:/var/lib/mysql' + - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh' + networks: + - sail + healthcheck: + test: [ "CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}" ] + retries: 3 + timeout: 5s + soketi: + image: 'quay.io/soketi/soketi:latest-16-alpine' + environment: + SOKETI_DEBUG: '1' + SOKETI_METRICS_SERVER_PORT: '9601' + ports: + - '${SOKETI_PORT:-6001}:6001' + - '${SOKETI_METRICS_SERVER_PORT:-9601}:9601' + networks: + - sail +networks: + sail: + driver: bridge +volumes: + sail-mysql: + driver: local diff --git a/docker/8.1/Dockerfile b/docker/8.1/Dockerfile new file mode 100644 index 0000000..4b77ed3 --- /dev/null +++ b/docker/8.1/Dockerfile @@ -0,0 +1,63 @@ +FROM ubuntu:22.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=16 +ARG POSTGRES_VERSION=14 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND noninteractive +ENV TZ=UTC + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \ + && mkdir -p ~/.gnupg \ + && chmod 600 ~/.gnupg \ + && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \ + && echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \ + && gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \ + && gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \ + && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.1-cli php8.1-dev \ + php8.1-pgsql php8.1-sqlite3 php8.1-gd \ + php8.1-curl \ + php8.1-imap php8.1-mysql php8.1-mbstring php8.1-ssh2 \ + php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \ + php8.1-intl php8.1-readline \ + php8.1-ldap \ + php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \ + php8.1-memcached php8.1-pcov php8.1-xdebug \ + && php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1 + +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 8000 + +ENTRYPOINT ["start-container"] diff --git a/docker/8.1/php.ini b/docker/8.1/php.ini new file mode 100644 index 0000000..66d04d5 --- /dev/null +++ b/docker/8.1/php.ini @@ -0,0 +1,4 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS diff --git a/docker/8.1/start-container b/docker/8.1/start-container new file mode 100644 index 0000000..b864399 --- /dev/null +++ b/docker/8.1/start-container @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + exec gosu $WWWUSER "$@" +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.1/supervisord.conf b/docker/8.1/supervisord.conf new file mode 100644 index 0000000..9d28479 --- /dev/null +++ b/docker/8.1/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80 +user=sail +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5928f0f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3108 @@ +{ + "name": "vito", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@ryangjchandler/alpine-clipboard": "^2.2.0", + "@tailwindcss/forms": "^0.5.2", + "alpinejs": "^3.4.2", + "autoprefixer": "^10.4.2", + "axios": "^1.1.2", + "laravel-echo": "^1.15.0", + "laravel-vite-plugin": "^0.7.2", + "postcss": "^8.4.6", + "pusher-js": "^4.3.1", + "tailwindcss": "^3.1.0", + "toastr": "^2.1.4", + "vite": "^4.0.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.16.tgz", + "integrity": "sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.16.tgz", + "integrity": "sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.16.tgz", + "integrity": "sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.16.tgz", + "integrity": "sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.16.tgz", + "integrity": "sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.16.tgz", + "integrity": "sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.16.tgz", + "integrity": "sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.16.tgz", + "integrity": "sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.16.tgz", + "integrity": "sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.16.tgz", + "integrity": "sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.16.tgz", + "integrity": "sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.16.tgz", + "integrity": "sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.16.tgz", + "integrity": "sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.16.tgz", + "integrity": "sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.16.tgz", + "integrity": "sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.16.tgz", + "integrity": "sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.16.tgz", + "integrity": "sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.16.tgz", + "integrity": "sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.16.tgz", + "integrity": "sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.16.tgz", + "integrity": "sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.16.tgz", + "integrity": "sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.16.tgz", + "integrity": "sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@ryangjchandler/alpine-clipboard": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ryangjchandler/alpine-clipboard/-/alpine-clipboard-2.2.0.tgz", + "integrity": "sha512-2kKHd2mA6K7RuYlC+1fikIUPVJeJLQlY2w9rNGrOgVfzXUZRotjTP+EjxouDizTEvqNRkVTJnmmNle32Uhb4zw==", + "dev": true + }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", + "dev": true, + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "dev": true, + "dependencies": { + "@vue/shared": "3.1.5" + } + }, + "node_modules/@vue/shared": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==", + "dev": true + }, + "node_modules/alpinejs": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.12.0.tgz", + "integrity": "sha512-YENcRBA9dlwR8PsZNFMTHbmdlTNwd1BkCeivPvOzzCKHas6AfwNRsDK9UEFmE5dXTMEZjnnpCTxV8vkdpWiOCw==", + "dev": true, + "dependencies": { + "@vue/reactivity": "~3.1.1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz", + "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001478", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz", + "integrity": "sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.361", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.361.tgz", + "integrity": "sha512-VocVwjPp05HUXzf3xmL0boRn5b0iyqC7amtDww84Jb1QJNPBc7F69gJyEeXRoriLBC4a5pSyckdllrXAg4mmRA==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.16.tgz", + "integrity": "sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.16", + "@esbuild/android-arm64": "0.17.16", + "@esbuild/android-x64": "0.17.16", + "@esbuild/darwin-arm64": "0.17.16", + "@esbuild/darwin-x64": "0.17.16", + "@esbuild/freebsd-arm64": "0.17.16", + "@esbuild/freebsd-x64": "0.17.16", + "@esbuild/linux-arm": "0.17.16", + "@esbuild/linux-arm64": "0.17.16", + "@esbuild/linux-ia32": "0.17.16", + "@esbuild/linux-loong64": "0.17.16", + "@esbuild/linux-mips64el": "0.17.16", + "@esbuild/linux-ppc64": "0.17.16", + "@esbuild/linux-riscv64": "0.17.16", + "@esbuild/linux-s390x": "0.17.16", + "@esbuild/linux-x64": "0.17.16", + "@esbuild/netbsd-x64": "0.17.16", + "@esbuild/openbsd-x64": "0.17.16", + "@esbuild/sunos-x64": "0.17.16", + "@esbuild/win32-arm64": "0.17.16", + "@esbuild/win32-ia32": "0.17.16", + "@esbuild/win32-x64": "0.17.16" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.9.4.tgz", + "integrity": "sha512-5i9HTcrJrCCcmztcjIHpt+eWwu89Ed66rNBf5LtTy69QHbP/mtvjOTGqiOR01QrSbfoT1EP0v4XXvydpJj0r9w==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jquery": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", + "integrity": "sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ==", + "dev": true + }, + "node_modules/laravel-echo": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.15.0.tgz", + "integrity": "sha512-q5YaEw2NFu9xra6sYUfh/FX2YotN5iY1nMeKz90J3W3Vpa+5WjK3/DYeEzkTfBZz8Oq1Dv9vWNE4IUvt7kxYIg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/laravel-vite-plugin": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-0.7.4.tgz", + "integrity": "sha512-NlIuXbeuI+4NZzRpWNpGHRVTwuFWessvD7QoD+o2MlyAi7qyUS4J8r4/yTlu1dl9lxcR7iKoYUmHQqZDcrw2KA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "vite-plugin-full-reload": "^1.0.5" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pusher-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-4.4.0.tgz", + "integrity": "sha512-oxSEG764hqeGAqW9Ryq5KdGQrbM/2sBy5L6Jsh62GyRbRO4z0qI9EjQ6IfQSDhR59b/tY0ANuXD8+ZOZY9AOyg==", + "dev": true, + "dependencies": { + "faye-websocket": "0.9.4", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0", + "xmlhttprequest": "^1.8.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "3.20.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz", + "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sucrase": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", + "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", + "dev": true, + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.17.2", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.0.9", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1", + "sucrase": "^3.29.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA==", + "dev": true, + "dependencies": { + "jquery": ">=1.12.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vite": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", + "dev": true, + "dependencies": { + "esbuild": "^0.17.5", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.18.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-full-reload": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.0.5.tgz", + "integrity": "sha512-kVZFDFWr0DxiHn6MuDVTQf7gnWIdETGlZh0hvTiMXzRN80vgF4PKbONSq8U1d0WtHsKaFODTQgJeakLacoPZEQ==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "vite": "^2 || ^3 || ^4" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + } + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.16.tgz", + "integrity": "sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.16.tgz", + "integrity": "sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.16.tgz", + "integrity": "sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.16.tgz", + "integrity": "sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.16.tgz", + "integrity": "sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.16.tgz", + "integrity": "sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.16.tgz", + "integrity": "sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.16.tgz", + "integrity": "sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.16.tgz", + "integrity": "sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.16.tgz", + "integrity": "sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.16.tgz", + "integrity": "sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.16.tgz", + "integrity": "sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.16.tgz", + "integrity": "sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.16.tgz", + "integrity": "sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.16.tgz", + "integrity": "sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.16.tgz", + "integrity": "sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.16.tgz", + "integrity": "sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.16.tgz", + "integrity": "sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.16.tgz", + "integrity": "sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.16.tgz", + "integrity": "sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.16.tgz", + "integrity": "sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.16.tgz", + "integrity": "sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==", + "dev": true, + "optional": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@ryangjchandler/alpine-clipboard": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ryangjchandler/alpine-clipboard/-/alpine-clipboard-2.2.0.tgz", + "integrity": "sha512-2kKHd2mA6K7RuYlC+1fikIUPVJeJLQlY2w9rNGrOgVfzXUZRotjTP+EjxouDizTEvqNRkVTJnmmNle32Uhb4zw==", + "dev": true + }, + "@tailwindcss/forms": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", + "dev": true, + "requires": { + "mini-svg-data-uri": "^1.2.3" + } + }, + "@vue/reactivity": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "dev": true, + "requires": { + "@vue/shared": "3.1.5" + } + }, + "@vue/shared": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==", + "dev": true + }, + "alpinejs": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.12.0.tgz", + "integrity": "sha512-YENcRBA9dlwR8PsZNFMTHbmdlTNwd1BkCeivPvOzzCKHas6AfwNRsDK9UEFmE5dXTMEZjnnpCTxV8vkdpWiOCw==", + "dev": true, + "requires": { + "@vue/reactivity": "~3.1.1" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "requires": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "axios": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz", + "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==", + "dev": true, + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001478", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz", + "integrity": "sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.361", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.361.tgz", + "integrity": "sha512-VocVwjPp05HUXzf3xmL0boRn5b0iyqC7amtDww84Jb1QJNPBc7F69gJyEeXRoriLBC4a5pSyckdllrXAg4mmRA==", + "dev": true + }, + "esbuild": { + "version": "0.17.16", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.16.tgz", + "integrity": "sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.17.16", + "@esbuild/android-arm64": "0.17.16", + "@esbuild/android-x64": "0.17.16", + "@esbuild/darwin-arm64": "0.17.16", + "@esbuild/darwin-x64": "0.17.16", + "@esbuild/freebsd-arm64": "0.17.16", + "@esbuild/freebsd-x64": "0.17.16", + "@esbuild/linux-arm": "0.17.16", + "@esbuild/linux-arm64": "0.17.16", + "@esbuild/linux-ia32": "0.17.16", + "@esbuild/linux-loong64": "0.17.16", + "@esbuild/linux-mips64el": "0.17.16", + "@esbuild/linux-ppc64": "0.17.16", + "@esbuild/linux-riscv64": "0.17.16", + "@esbuild/linux-s390x": "0.17.16", + "@esbuild/linux-x64": "0.17.16", + "@esbuild/netbsd-x64": "0.17.16", + "@esbuild/openbsd-x64": "0.17.16", + "@esbuild/sunos-x64": "0.17.16", + "@esbuild/win32-arm64": "0.17.16", + "@esbuild/win32-ia32": "0.17.16", + "@esbuild/win32-x64": "0.17.16" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.9.4.tgz", + "integrity": "sha512-5i9HTcrJrCCcmztcjIHpt+eWwu89Ed66rNBf5LtTy69QHbP/mtvjOTGqiOR01QrSbfoT1EP0v4XXvydpJj0r9w==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true + }, + "jquery": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", + "integrity": "sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ==", + "dev": true + }, + "laravel-echo": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.15.0.tgz", + "integrity": "sha512-q5YaEw2NFu9xra6sYUfh/FX2YotN5iY1nMeKz90J3W3Vpa+5WjK3/DYeEzkTfBZz8Oq1Dv9vWNE4IUvt7kxYIg==", + "dev": true + }, + "laravel-vite-plugin": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-0.7.4.tgz", + "integrity": "sha512-NlIuXbeuI+4NZzRpWNpGHRVTwuFWessvD7QoD+o2MlyAi7qyUS4J8r4/yTlu1dl9lxcR7iKoYUmHQqZDcrw2KA==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "vite-plugin-full-reload": "^1.0.5" + } + }, + "lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true + }, + "node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "pusher-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-4.4.0.tgz", + "integrity": "sha512-oxSEG764hqeGAqW9Ryq5KdGQrbM/2sBy5L6Jsh62GyRbRO4z0qI9EjQ6IfQSDhR59b/tY0ANuXD8+ZOZY9AOyg==", + "dev": true, + "requires": { + "faye-websocket": "0.9.4", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0", + "xmlhttprequest": "^1.8.0" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "requires": { + "pify": "^2.3.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rollup": { + "version": "3.20.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz", + "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "sucrase": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", + "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tailwindcss": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", + "dev": true, + "requires": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.17.2", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.0.9", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1", + "sucrase": "^3.29.0" + } + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA==", + "dev": true, + "requires": { + "jquery": ">=1.12.0" + } + }, + "ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "vite": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", + "dev": true, + "requires": { + "esbuild": "^0.17.5", + "fsevents": "~2.3.2", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.18.0" + } + }, + "vite-plugin-full-reload": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.0.5.tgz", + "integrity": "sha512-kVZFDFWr0DxiHn6MuDVTQf7gnWIdETGlZh0hvTiMXzRN80vgF4PKbONSq8U1d0WtHsKaFODTQgJeakLacoPZEQ==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8cd6b7e --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "private": true, + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "devDependencies": { + "@ryangjchandler/alpine-clipboard": "^2.2.0", + "@tailwindcss/forms": "^0.5.2", + "alpinejs": "^3.4.2", + "autoprefixer": "^10.4.2", + "axios": "^1.1.2", + "laravel-echo": "^1.15.0", + "laravel-vite-plugin": "^0.7.2", + "postcss": "^8.4.6", + "pusher-js": "^4.3.1", + "tailwindcss": "^3.1.0", + "toastr": "^2.1.4", + "vite": "^4.0.0" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..4408694 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,23 @@ + + + + + ./tests/Feature + + + + + + + + + + + + + + + ./app + + + diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..67cdf1a --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..3aec5e2 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100755 index 0000000..e69de29 diff --git a/public/favicon/android-icon-144x144.png b/public/favicon/android-icon-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..55a9e8eb59fa90a45177a5bc77a92baa73c520ad GIT binary patch literal 4676 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 literal 0 HcmV?d00001 diff --git a/public/favicon/android-icon-192x192.png b/public/favicon/android-icon-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..41bc00a50468a11113a5a68f6e5e6225ae942d4e GIT binary patch literal 5226 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 G_J06*>f&$! literal 0 HcmV?d00001 diff --git a/public/favicon/android-icon-36x36.png b/public/favicon/android-icon-36x36.png new file mode 100644 index 0000000000000000000000000000000000000000..4d0eb56c60f4897f8df5e0bc242c04986a5a7d02 GIT binary patch literal 1404 zcmb7@c~H|w6vr3kkgJ-aVm(^ypySlh90Ux%+9HtDM3Tr6APUsnhmr&Mp#$oOcob7D z+6pL09itXdP!TOutWu9w!4_1iXenOgmxK@#LI@-zp}%xGQ*@?(bY|badHX)^yKi@A z_a!n{2M5dz000EjsN`hShkI<=RCIpSCpm*UZ*eRm7J$amKquD+jl=lVWCj3*ivcLw z4S)k(D$)Uvj{{(U0|0acfKcVJD@iK>@G45AvnXpn)BLZ&q-f~z8bPM+(0-F@_iJ_{ zl1fMR>@a@4-^9<*r7@7(H*6CV6HezujoMOGZnoRq*RR@A)*$PXwNHB-TEr>g=ow@U zZ@uot^YI6rV`)s}^a;z!<3ldjL}i&-yg`TbkH35|z9C)P`_$3b>)^0;=gth59W;Hh z(>OlvR)0IhBx@9s0mFdv=bNKRR84b}wg1()n4@pHV6_an^5q7(c)&R5yxeGQY#6RN zX&D=J@7iX}WNEt}*mYWGwm>h;(skS!O<#)~RGI2dTaH%_*~i=)(zIEr+J{|Z>yoq; zhs-6#Mu)@Q_ow5|?a{>5nk(OrJnFV*Bx~zVS%%E6+)V=;dHVXA;X>FjJnXvEXsxdu zerUq@Za56Im_|FUs`sTNL<-zawyi-y6K{MiBR&T9{cy{z?^{?l`!WS9pXU0+)37uV;`lIWL7gp)(vv2NL z_%21Y@9r}U+3vH4lB7~4tm&ZcY(G$2yT3jDyN_5^e9Z6NQ}RbLqh>Gd>Z%>A^Iz4J zSz48S;YpdM<)n{tZ!4$!sqdvNOECQEqK1SZQ+=zS&iLg#FVhFWH@@NG2`)!)_-s&K z(46Dbe8>7{;#_}lhymqC{4Wy&TacCjwcUr4LkqZnF@&9SR>)J=OktPBZ3{M+mz?pV z8y;M1n5_<$UZ~1ArHTvbMP4$eZ~nw$o>c- zXhrMYSZIlRqw7`VV{-Hlg{ADzzcN>7&GR}9;;k?-6#Zmi5lmsj0xm3s__;#V0RoOd zScbzd!$-3S5fFX_gpXW`!$CM4v!agmMuAKrkctZayC9|=gMMWY=Gh@nA%eGXbA>-bpBz|r2<&uK_1pGoQ5LrO+pw_nGh~e3c=r9VU==m z%*8b3TRIFDN&$Qnkq{L@Bt%4}7ccPWOrNBaA}tgGTwL5?^{0bqDs56KHJJuP(rh7m zbgWDcXDh^55qGncuaM_q|Gjc7QN)WTaY;B~1PLeNMMa2K2%>O!yeNu~BauYJ=;dg| Va(fjka$)`9GwDyWIh1W-2m8- zC8-L4d?ZoB1b|cyfWJs~Ga(WH4>WBpBPM>8;(s617)8=rcwIb9i&dn=!^sqQTfX+k z2j=IU)~`+**C!|$YvE%DM>?Kb+a8*Ww`kcLRfE6T-EOzT;jTGrJW#4Ln_UCH*qG~7 zlxRgRS7XpS2Y*%|5)oii^>!(*z|D#yz~d*%ieovgTe<<+(NSLH|bPN%!Rc2qHF-;}J> z4mol;n)`Q6r^@wviifRM*PSL4eKjnVXnW+=G`e!s=-divOQgg3xkK%3mV;%whppy@ z%cB;HYu_H-z^^v_h*O-S;jz>jm19Gq@^ppa+pDiCj_XgA8?w^X8npvf*g2b2n^Tni zy|#wSuc}TOAc3a0$M&ezEMTjXDDb^IrrS-X;v((M#@9xpvq(JD@x)@Yx*oS#_U_WL z)~kMfVLN$3&u6Kt<~D8rIX`?&sFtZtKNr<2oALyDv(OJd_y_otg+x3wQ3{ML?II z_rhFi9Dnh8#f5RFYN{(q9-eP=p79Y3mA)o68q4VLE=7U~qPX>904Dj4846U$0+2-v zM5e@GV3e=Fk58gkD5C8VN{)_V#I<&v;BNMf@-CH+`=B7^L13h3I(O=mh8>5oPo-sx z%Vzp*joH5um5|V|MC*4Pr_PyE-aovjxsZg@6(&|XmIN2xTCh6+zK8D9`^-HcU{rXk z&)qFO5V(l=gBA5dymz3l6C8DI2l+9o2~1PYq!$XY$9YVxtp7&Q=sW24&Gn+E>1!|p zN46~-_Gm**n@+v~1!jTNmKCdS8RO7LP?P0(jk$B@jqeoxPP@nH^Z;p%d6GWU?HzG*F$Ez-*Zg?g3ChCZ zcaK#q-5OCZyzLJjW5RJ$-zu0s^?H4A_?eEkX0^PW>v_8@c1HKo0$C(#vW%9!%!;W> ztm#=Qo*s#+5=W-=NS3W)vauft{NMNTes5DkNb*YmzU~{-zMlr3utS>`^)ys&QuJlZ zeZBfYiBQz_xS;OrL2Aq5mOTqmQfz2bpATn56hD0H;h|eIs&rc?_ZLgMN1r(LnrU+m zeOIR-&>63-DY?t8un;9H5;Es!Wx~)=1yI6MuT}<81E(KsrA(l3)CZaJNL-a?zgxmr_t=+pb!L z#f1x+fOe6^Fq*PF$WxkJeERFYN6kNDI&}{By~Av@WodWE0z0aDt=}9$Dh#b`lMxcP zw`V>kHhwt!Q_l+NoM!jY)pF!b&4XgrL76OwP0Gk)BMuPpMB-vRVKE_sK@27lmXHXc zi|}|79#8$^0^=VE0%0bfQ}o{n%OCk5UnH0{RzWP}K!vP4HsC>!NKC@v_yQJ}jTk>8 z8!OD?HvK&F6v76Ku?$|mAe}^t7G~rN*trmiL_<(9Ak?^T;r_*t$5cq9I5wZlg8(6d z`0>V1k`TuK4V}N36n-Ye8$&v3XOBmaz&8*IU%-ZnL~QV9S2$5FclkHT)PLzv7zhOj zVIjn@;1FVPXv)r+V>(mc&`IP=*Z{v`#j&%?w8&QS8(T?qGT`uY*vQdwf?Oy^$i;D3 z1^f(Qt{C_CmE%G<=@H?qa6CIW9M4G)3+61z48s!$oUjahcsM5{0*ho|k^aDCvN}% literal 0 HcmV?d00001 diff --git a/public/favicon/android-icon-72x72.png b/public/favicon/android-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..5b922d6c01a662ff08dac8589efc73454d23cf38 GIT binary patch literal 2090 zcma)-2~d+s7RNsjIaF2<1;jzYaU5nx%)uQk6$z4n2_b}25OYGf5+I-)UJ)G~FLVR} z@j#K0O9jOPP~?(R9c5HR#Ze|-P7*>cl8`VTTU)j6RBhE(_3KyN@Av+%yQ{nU7y%z- zy})S!007ol44Mde%$!-ygL;ZbKsMye68&-h0MK}P;S6~`Ghnsp?TrKAQ21V19@Q>UPiL$ zR;{A9ThrODzECn5AHk2rfhT{GK5kX__GlU#6l|slkLKmD#N(g!v$L}X!|dZ$RVJ)P?NcT|KR-i@lM zX^rv7fr&jCV)>*&CN+>kz&p2;<6rcN3Br!YYMIQCoi1ilgdk5}e?xI-?}S=yyj7>T zR4z9fXD1{xnaQGAUBaD_{E;`>)(5JyCuDlP@%Uk>R%=u$4g2><$T5QV zqq;Z4+ISLwpjQ(W3RYIgk8-7XS>h?V;lvSXGDXX~F=LKOeqTWwvnf?F`5Rv9mq$#q(zL_8Bi z0G|&{N8-W09!<-A6)_k*b6oawp){W(o|-Z!6o$RKCA*>pqa(VfU7F@bW&cx66dt^M zK`xgYax=v#G@*b$Q+ZMT=6CJwdPRBhBqvQQl^RYRmFjfHFMsG6I|co{n%e7A2lFK= zrLiDeqL?y>#WT?a@Y%rhy*tW>_f$kI@AS{Ie2yfQE))u8-i>JQH7T!Ml3y;Dr%;9O z-|4i|#w4;l#n3w>UerwJv6XlV`8!ZV4>ZdnE>S#j?kn92a5}|08Q*1 zY;D8mdkFzx-byUmpA_9SF(M4u9<~&iv=0=jC)8R?bCfplWc#H@KV&Xsj)VnL5o%3zC77j)_%)ZS!*X_wC>xY%I&ZgC(Lbs1r{tZa;{(yrQ4{-xp zFu{&a_G4bFm+)M0B%g-JI`K;P?`rb89p~k#U-fMfjg5j!-dl7#3*Mi$=&oF}bXE8G zU4zBZ>O!k|HG7M8ns;_A^`+fN3NG?J;UgaMus`UM?2GNdQi?W}#Ri=?cfl#dDX{Wd zIGV^sP;0U)avwRG)r|j;!yR+#JjQHGdqpcc%pM?dt8w>(t%ef`@3$8hY+J;5R;^m} zGJ0##nf?plP()@^##n(tmcJFY^p4OLUu~bc5TAtc5S z_*Y^bJeP(|FzWVTE$^lB;$Ph>TW3ylPz+2QyyDpDyrH3FSx9hA`rCBga>R&T$cp$k zD3rvVAE8$ta<*CNi|JYwoK!pkWEmmvl z=4;pV|B7z6Pc675tg{>#WLdbiuj*5tOJ{DfHUKejBAg=+>Zgp0L3*O12wX)b$a(7q<2%(E|=eseu4 zygdA&R_I@q?^;~+joC?9^IG2P6pjt0)~A|KL91A2#!4Bj*e&ZITWX?48}@1vB6*UQn0ieuCkb|IiK{SD}BGKQ{6sq zgD!2uHd`}E=<@`&NmbPYS0Cl9|N4AeUTqY0eSQqTc4~3#WWnj!BV`Yu$MYR0Fq%Un zbLc2)CLMAB5{^W=!x8QXKN8Xdh44WkynckkQE)i^d=2Tp64F>SCL{NMCu|^Z z=b%so2+aZzzs|P8{>EVER8S}kotc=#0T6!3E%6x<5aaNb&cB%`CXJIchYZ)dT0+S3 zuMiwFjn2ts(}91j3dT-P+}sq2|C@1cR5&Vikepj5ojRRjJYx(6kW?wq%i}{@|It;Lwh7^Kk>9DPK>4S*+==i}DKa0U-4k04S#cnAZ$Z z7yu+e0boS{0J{u;F{%8qzcT<@Y!oucLj(AEQvbi=>p}H_Q&GF9{s@}C7d0}BQIyBK z-za?iNYr#!cs`rEFNhw5q#aM@+_@=ednkI?EG#bMkqNB#Z>4g%O08B)rK;y$V%!17 z9u%EFs~mVECE!@$A@u&&Qk6>G(JDgw(JIUMGO6m%4sob2&1WYyBYj3JQVE61EXqv6 zK^B9iV6zk?JPWy#Ixka&_|O_|3xon?8ksZ4S8`{RDG6*mhB-MQpZX?`31{vPrVqWB zHP#EtOJ)@c^^7m5_B8is0-MKGj(naE@}{-7in^bPl}h#Xa{kFQ&fJ_bmCT<0 zCO;I-+~ZI0>yb1!2m=tbtC#tCIXvpL{9rV5hNCzV&yGMdJ`TywWpaa&v`-&oFP@4| z9h-^8FuzU6|LT*51<+Am)cRUM&kISYA1weuZN4Wg%+(wto5fVj@|5XGoX;O+m^}1e)G@UpPOnx|qjHKf>Yjm2X~4A2bW`k<9vAf?GG{ zlnQm?A@<-qS^FbVY0>QX*ZI60E`zT4I4D!d)n&!AljHI`wSoh|^uf2%#}7pp&-1u5 z3XxDL5~;d6#ZRAzo9+qyc2TcgRdO}g-H06E8>mSs2an|!nf%?eJiI(kaS(A~hjssQ zjT;i_y$k+p-=jTu_AD>JyVl~rx0+r zpxCc7r77s3;8k6ws}0#KgXT^F|`Yhz9utjd}U@332!+rAZJ zh*TmiYfa!4Y+H2=tvK?^wy?N!AvaIF1oSx_T4yp3I#n{hUD6==lH4!rOyoHwJB&S42gj=Fzi}%YZZ8l{*<#WQm5bwa>6TU5fHJq$9~>i*#sb3W!m-xG0CL>;wt#@ zDXwLB<;vUMlwvoGN7d82VW%9yh;yVRagwk>xa8)mBO9CZJx@X_l~MU6o3H#1zwz)` zE)%_F&FIohh@Upu@`Ft_`Q4GHLzgVtyB`?qMC@~}OX6K;YW*>M(ZVS8Od9Bv7nHU& zAoPH8C8F^}rF1RSfx_Nsfo}!9euew8i_Rvn05Y|7m62{NQtJ=ff@vLt;w6JsZD!AU zVq09gaOzL2sQuj58^A}!6>o85nGT-^fSzcaK_}67)^UhCU zoY|VD>T(C)?#126^8;`Mi1wMVM3z_EEWVgh@AL!ijS_@EED#sf{ji@hblrmAcW1K! zg@aG0Y%tG%D_r5+i=)`NIsvEQAB5}UehJSykm&3^0?I`&(?)GaD8=PyZhyrhU+{S> zWilG0$~gODg7KWi-s+V&7}(cw8oBk@jf|z`u!^siX-4H*(>2?t3r8y5tF^)njY@23 zt0$nIf;eK6lCnaE^+ym-k#e9m;MiBG%( z(Y+Q@(ARVQ3+{K@R_w2xDaksH1}JXM-toYZ-Y=fY(d1jaqw`>_?VNrl^*4PCjmR2r zG2Q}+cqvI~UX5O@eBFb(aICTks|TQ2n?|$$aX7G`6S=)t8YKT~tEq_2 z09i6V{IeRt>~VilJCy9oMs3ihe7IKF)PMixBwe>IK8MzXWMtj&8g|*U(Gm%RyEK(G zz6V~ko>$W6-L%OR1zhm?*#74k ztww~&iYH&n_Jm@l6e8pH|z}isqsP0ar2#3MeWz})t%}qd$tu`UEitX zU5)+Xe!T_g9Q_oxdg~|H;sU}?6x|8PQJ~gyy_zN%q~tfWgC~X~sxi`3zL{Z)8MnJ( zlO#=UIC;r)Zl!v@PxC@;BzvIA(HJro7L|b2G{6RGW3vrvz0KMw$i^0Cy&Yz4{~Htv zgF<~v>Vp0&fDj*z$EE!5fE|4+H2(>(ZefPRcpNzylYj-WWHKocW@UvZU}CTu!$%#o zj8BN^7%;!8VNDj;px7irBn$?Rk4hq7iDVcIr9l&cb*;MH>Te8UK?Mf$!s26M$-vsl z#&!SUU=3sZozB0RP<%8wb^#fzU%y0yn0|-&;0aiA3JDATwJIwTF=j_|i0|KYe1bF- zuy(Msaj>2Y6zhdIwk@tp(WC!gph=&6hjC|6G4iiD1tyDO{%DL z5m1^U{S~ArN^c3EbW}t@zsooO%>Vx1%s=zZoxRW8ea@cUJ@@R+?oAtv`60f)_y7Pn zWNCr210!{>9M})O?~cWUgMo`|YGn!l6?ge}@Z8|{ae{@N6##^s1c1mJ0PqW}ikt_4 zKs5mP;sF52bN~?X&v7mxG*oS8Ysn2Qii zoxV8bl*0JD5GE*SDxAgW4I^i-Y;GCt#OxvXi~S}OmkV}kx0H8bMaNX`^`1Y4kk#r{q;GSHI2zKlj@PYLypOMlknyV$Ha4i zAFiF}%oemz;eK*`!c%`=Fvd%)ynP9>-@-m&>0q#1zTHkQpFaai{_=Du1y~V?|HgaW zBKyA#_?n0c0ps5;ifi1@KeSJOT+>yuJFqP)Xd91$VxfO$98ZSKQgc#2?V28NaaJkJ zq405bcyT$kXn)POX-DyKuvkiWZN^&zY(W8bMs7swlKaz%-3+mL%f?dshVXDz#v2v=rFg%m!iaJ!zZ zBi(NI4*Y<5lda+>cJcf^5(xR&=Xe$VFJH8Nf14|*5C4h239z6_O*?^lE7=M9bW`7# z7Tr+|+ix<$;faMM;n)W_C8^!Qj4!T_L{190HAjS&!@GX%_j$K+rxl7Ezhm!IfTXG< zqGo%T0xnNyBXF(_r#BYTb^J;=$BhIZ)!~*)D=r1aOZe#q*dk^6)su|UEl`h2WKRN0kxxDw+t9=@ws9lZbhcXXU)qULEsxqiV_Qf6C)knO^d zL3$73Psg`*FLNB8)aG?rQ+b!UPJJ-2gy`xz+S_q3CZ_<_)pN0~!77!zMdzU1StDjO ziDv3vhPh~Iq;$+0_34_)#tm?S%rR-E3!xvKz=+fPC4@}fk!})9jK?0Wy<*t%Gd&FJ zI|0e9mW?g6Z1S>ip9nVSYIN@?8r!!kR=CXCNsgGcemfv9JeEeQblMWo{~(x0auA(* zkK0wh5n1Ab8=i1A4)5BSy@|Fa5BI%^C48`wo*Xub-A-N~s5PvXW;*AV7Rs14KWc#- z*6x`2E4GwWtDhQ38%?~4#chYn_LUHr)H2>nd@vuxlNYbjZoQr6TOxa2{;U-A z7G|susjOQsNnzZZ?_-23NIf_dCnK)M#wd9@*#w#7t>uSxA+(vSw(qxRLPx}*#gEkj z;q4z@-~M(9lxeui34w`wLDd8fxfO!hz;LP@*1H(_))c9)i$Kn zlU$U$I3}M)brk+aFJL@;S66AWe5<2C&eXaHgM?jMkTez}Zf4z+<)s_3bjKjcjlm?z z*;=aJj3Y;mfCE$cD7WunqG$urqN$MX7hlMJEbH(}!2hTBjo4FE#W(>v$7EwPccj?` zp}N(t^{;UF4tE5o3mJ9)w?IZ=4_*h0Nj2)Sm(4;D;s)1 z(`t(5at_IIJmXArJ(ql@ZiGC0abGUQ%-xJkKW(Hmp(psL5g%X&(Ptg#8&&$_W)Py> zU2-h;tHhzwTUcDJF@um(mX7t>IFCNc&1B{co+%WMm7ZTZQ?)v{#c3j4TEj)IiW>LL zl#)CPKfprhT~dBD*YAdn<)Nm1&=h+(FkeYE|uQJ$7EaekZ+!^$PMyFC=Z< zN;qitsb(p*hGk}$CUoLuAbalI(V^a4b5vm}SLQ^4)0wUqM+Gh)vS%3_3ZZxP(NAKo z){QDM9wO>Sm5psjE?*Ggeerh^K6(WG?R$Nl`;0eXwtDAx7y*YcE`vYX@aW2Aek=ejjct|zK(y^p{?I#3sTF3vb5iHj-i-Ht)P{o#T zDE6_Z7-8Gr$6lu5cjzBA`VL46GT;K=zIO#>;b6V$vPpM(cOA~_ojCUNe(&PAtm`I5 zGb#=hB_VNBGLylxZu@!A6RzcR0t(@L;Zqgr-GZ-6nEK(Jn)Gm41mIgs0S&mYt@mqN zy}zcL>59i>Cg%E1`pLwz8pIFzbry&-Zs&aUWO9ojfsZW#GKWsxoA1B+3uOeQP!cM_ zL)VHe41BHAyH40AcHUGu<9PG2zxlS_Zzl4!X51=ly_7E$3Z1u zPNI^-2p?wJ+3R$kn%=*yXDpM->svj_YdKBbdYolq%G2Hq_qG+-Ctlho*4Xsbm!~-- z_5GmNY*SE;?`aZxih{$i!H`leq@hlGisW|>JkE!O9_rty`SxPBo6ux&QKahn7lZBj0L-O}| z7#hIsaFffKDmtazK?3zv7w9gq{z{L{ECE;v^=?GPx%q{`s|G9YIGg$BIzh$+&V`hm zr}2lQVBPw+2^CWI5L`?$%$7dXB?9dKRlm2Yw`D3e8eLlU%c3tMybbVhD^|9JQ#B0b z5;v+8C-DB76ZuPH5cucwPQ(@~l-GLnjmR~%=8zoXQ?>O$LnVqQ*f_v-Iy-{^-S6dj zL#CFXc|ZBdv(**&G;7)(m-0dqMyv;vl#@fNj=j9-znNIW55%P0wm>^cC{k^=5_DR` zeQs0BO=sf02p_7@2|X+Q`G#(QLcSL&sv%`C`#s~TLiVltP1B5kx$eiqCv`f-Ky@Y7 zBEWraD2vhv!9oj*7Uj<@jX6kvXXdrbq^FJ&UTBDg?pvOY!l@@`JP4Ti0o;;%7=xl zL@$V^8IE$4OUlU$MvQu@A=g9BhrqfM+u{aDoeer{#ZLSjKbNb>fS22;Jb$ASMfUYL zx4aW*cAZiB)N-c7-7e5tCzpdS@tahnEWU?wv!xgpmakTq_$2TP8@i5AJTa)+da;ilN`q0JscU>8#A&m7+2|Jx>+!t zWqOZ1jY<6~Ikv|F2mQW%Qzd%0mA8|$bm2J`l=`Qc7gFx$gpMMc#LAc{% zV=Gt>sA9gbFh%v=GlN?yzuaQ2%X+h={`;dRh%9%`w;sM1asHXE3rwB++$+OMfKnJ) zup|EztqO=l>eZNwma7JQDiz*vcXZPK^K(bjMEs|KE>DL~{}F%YiB;Gt^xp63ug*C+ zyq->loT$h{I~=h9j~aN?zIu~`gTrm+kK^H@nOS}pZSZm+M?*W(yzn$4l0YSb0Z>;{ zSBI$~U(uN@9=a$Uk`ODIr8a&CDz%*Ju$; zo&QG)XJ-kJD3^)g)Zsq9w99^EI0;Xu5d3@t;QuQ*T$ALfr;FEBBWmcXkvz3ENIG8H lY6t{Lo1mtvOVZR+1zV_s<6Cf<_Xm3bEYTQLshLOAzW{a`hW!8l literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon-120x120.png b/public/favicon/apple-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..14e7785d9725741f519703d9a9c43963cd5f51f1 GIT binary patch literal 3879 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 literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon-152x152.png b/public/favicon/apple-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc41f0da7986a0cec39c5148aeefb8c1d152c5c GIT binary patch literal 5010 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 literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon-57x57.png b/public/favicon/apple-icon-57x57.png new file mode 100644 index 0000000000000000000000000000000000000000..d14018d769563a6e618d8747a64eb5b554f769cc GIT binary patch literal 1816 zcmaKs3sBQn7Kg7Cm4_&(E4E$Ts?h0LB?&=te} zOArkR!J-93Yo!Gh1hiT)*lI-{Lahq&$diO5B;@_*pH64i?ac1XJ@?E#_dCCH@0~NZ zG!`G};r5;z0Kfx_K@%V!JZ~=VKy#On(+)Xj`gYuQ0KPAGw~`k^>klXx0uF$}4*@9t z0su110NwGMvK#vB&l(d6 zwD_~!Y2gFI>sRLIgQi-(Iu0W`ePZU>Q{(6>v#`gI&zvTwNMDSY91e%UV6P}s;n1Rz zB86II+eMVH8S>d#8;KxE!i#_IH7FHUMuv<+l8%pAbUIs6z9Mh0e5l{FD_#;CDf;$` zw&TX!HCIMMb)^~?E-E`VV=~$Y`;BQtiDKHik1Bielfh)NA1Y9Ebm86Beo1noW^Khl{Q?YwHD?=rGZlQ!0za z{$j-Z_>p09+(O$eCF~Tpx9POAwyRCrm`IUMYcred({gKWHgs$K@nWUXVBeoRO^TQF z_ZffuK_3$#;`3Bii~Sr=b)rPc=cxz#P2+DY&j(DE|5l~MNo17V7N{ZIxdePX0InEH zMuN&(Ttd25f`!5hGNK~U|5)hZc?Vj!vN0(f2wgF63qXxvH56RT#o{6six;f$_VS8f zxJ3pvSuqy9orvjGR>??%p`Jogs3)!d*54a9E{cqEk3h$M=aw82>wGTzZ>)!fs~)b< zICZPUU%Ad}W=&R$%E)ruca62_f;PmboTZB|$C>7uYz#Lep)sar@p%l6&~xme)p z-q6St4G!ma9zLJWIo{lP#P@NMPi;o{hRd~y*-t$~>r<+)?<~-@T$d5 z!1XA>hD{{cg@$un44b(pj#PB%%RuJDl(?ZiX5E$W<`CCo_us6--|WCt_0)X3$vx-& zs(w8luXMTO=Q=bh?5r!%5R}Uea?AzRxjTg0wa1F|!edh}drNJL*-p#rqgFQg?RE-T zEe`&qAvtNI&&{>8S z{k45{ZIVZzbX2=(MoC7bHBaEv!4h8RL+_MBves93^AZ$YhyBqL_v(`aMqH$34<^5; z-}9f|VT#kWGs&fetj6SQp8ev>C9iH5wKNpJfApO!o^wZEsPX=T$Z``Y_H6c*2;p6i zn1eBxmpnZ^;JH~XGhO^UdYk_tkc0|KfQUhY+JQ2!XRlG``o_tC}a60 zBW&W!BMZ-zFLD{i+^P0C%^U6;8t&8Z9cwoAem_7>toarc)tfQ1<$<^61@tYw93&^*l?=%FoF_q0lT!eh!t%MWJFL zlmif#9bK@$FxYt&6beIS(6hJz5$qqDmYV=E-f!vr$s{o{xmokb;I(xw5c2L@2#%3M z-*=-`MD1rUJ&{(;B^=BWvb$mc6AD&nTnU+cEP$2~97GO+Q;|V%T1Fs}wly;l jjzG`?De#~mT0pQLl;H=RPezimp$Y&Sfk$5t+jHc1h%j=a literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon-60x60.png b/public/favicon/apple-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..7f0f96b644dc0224504888b6760fd9d6537cf193 GIT binary patch literal 1891 zcmb7^dr;F?7RP_MVpXIC(GrnT%NECq&5IBqS}mAJQV5R_wD zbAGoXA}rW(z1w;K02~Q;ED7{`Y_|4qwut8^pM!37Y9KKX0It?JtWfO1^)?!wLTcaxP06O%xuA68&;byQnl9jTW`q+;dHPp+zl|uBaBx z*M8E*MhL5pD~!t)tJP{USsLpXPaad~brzk@Qc@s0duGvMu|9sZoE$5TixB>LTYn^5 zs?nJ1Ym^n`a_Pbfi!O*~}LYi@xsjn6Ee~4dB8;f#fNim|Sr^}bx zG))bQ6XW{t`6`RqIy+-ZNf0NJMb#%1X%xxKD`V|RWqFZYueY?ds3#}%F<`S_fX(Vo z*C^R(3$w3Hq%VXwuP?PVt2^4%U*^k{3UfMDGWW(bc1zdZs^)zur^bupBSn8aTrSR+ z)l?{SOO}6*=#~wZigHDGu;2&2YWkV+m#f;=bE=~`QWis^QJWQV^O3_~rxu~Wbf$JO zBSn%)mv}ut-UN<|6PFYg1x_9!!WaF*wDKy+LfJiggs^-U%-K;xg0bEo_s*{c7wb6q zxEug*aIu*k@LdxG48Fr95OMDa?Oa@)oull1CEy&k6R?3~{J6Y9ALA0}H10yiezzOi z-fma6hUc(jqr-a7cF5+?P1JRs=gVTLRky1XvAgUFW5}6P)8|C@c#9+jG`~Twbrl}( z8+f)X%V%fhD=y!1s@dXlpy~;ow(-;&+MB75KSM(UB6(4yMra7pc@{OmdA@cfiNXi6 zA2=sQ!tdW{@@FC&f(oA0cRUJB@DM%==oR)$o{_k>H=GO@O5WaZtfdR@v^wMJ*knt} znJM4CP4lw>bSf|T>{hRPqI=^W85OJgo122(KR_7u-1Pp=odU|>jrIF^UXN=Z`i6AS z;;MprD7~9$=`mP*d9jx<=JFbQ{?o^GBW}U|vV;&t?)HnTCYx{AwYqsHQY7(1b^}}e zdK))Ro<-Lk$T4(Y|9yHY{)XqI`@Pj{mSe@-bWiJ*%-~qJwkLU8+b$HR;?tXHuEsoN zDFl9Z=Qhc}M@e_PYZ6SO-8=02-g6(j)4zWd$(btiP&%Jj=kqA?;jb#kAvGe~U4L~7 z-UP4vrWk+X+#Z~R2-RM)+!#i}Y;~8p7aKLTAqQ`6xOMC#q*#K)X}r-zI~OWn?0VQG zP4|;u&e-(sXHQifgVjHlZ5ayG3>G-dnFmm$q(7jiOJ~u=XVo6VdG?ry}lp%^Wz~NPdruajx#Ek%s5%IoA7ZsLD_f%*Kujd*qF}mJr`Bkm((vCFI0H{ z4rnsVITZ2$WzgpN^7)}~yRSpp zPL`=L-;qf_2yY+3$~~QIX!%2Z*y>&_E&29`PH9>_YVS+P>y}*}CWrII$gy|-u3&;=?8U{! za#JW=I);`_2OWTfBaxrN5uYLg$VeXy!ViP+^@hVSaClfl2l>AWSnL!gqu_rR?3-`~ zUuAgE3i@R61x(S_YJzo!Wo@gYQ8WVq?i^xhyIMgJsil zS@bL}1``3IIRN6KwGZ|ehG0{{VDNNiY8n?n1Ry_8JRA)&u5ao5n~7njaMNtaqt1_P zKlPTk5F(RB=N542z@Mjrak5hPT{{@|7abxQqyPjOg+%+HkUqXKWgpmd-g`?Yig}a{ zz=MM7&+nCise^B&qDcgR!OWzCt;1MZ+)Q>Vj6um`(%4x!u>V{+48@=Z_*4AhbRT~> rgNpWH_@$uX2m}L7gZuk4PytY|0t%i_a!AYpcK`^uFzio3$z}fnxxSF6 literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon-72x72.png b/public/favicon/apple-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..5b922d6c01a662ff08dac8589efc73454d23cf38 GIT binary patch literal 2090 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 L;XLnqMCJV(Z%HqR literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon-precomposed.png b/public/favicon/apple-icon-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..b0cda2eddef64056a8737967d979b10bb5da63af GIT binary patch literal 5768 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 literal 0 HcmV?d00001 diff --git a/public/favicon/apple-icon.png b/public/favicon/apple-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b0cda2eddef64056a8737967d979b10bb5da63af GIT binary patch literal 5768 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 literal 0 HcmV?d00001 diff --git a/public/favicon/browserconfig.xml b/public/favicon/browserconfig.xml new file mode 100644 index 0000000..c554148 --- /dev/null +++ b/public/favicon/browserconfig.xml @@ -0,0 +1,2 @@ + +#ffffff \ No newline at end of file diff --git a/public/favicon/favicon-16x16.png b/public/favicon/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..8bec3802781f3ab58f54f171aaf015cdee4fb0ab GIT binary patch literal 994 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>7 zJk3jgwPMMqq^K7O5zm(``jngY(#QE}Q}x@QKmRS9`*GgPkKe!lt1EvK75Mzxm7n+S z{)!8G9uxBX_N`x+F8qk_f9C7_blSuZzkdDe?ReMK^6tlve-nG&Cq}+_{OI@DQ$Ip| zo`rZnJ9+&3gL}W?!=Hcq`meI+b!pz~FQ5M|n)@+3<>lKqe|ByEx_$GPS1qQz^hqCrJfHfxJpKRw|Iymnw}GBwDGBlm zj-0h{QPs7OA3#21lDE5ylfZS`FF+1wfk$L90|U1(2s1Lwnj--eWH0gbb!C6XC@d~0 z7|d$=5-2p))5S4F;&STw>wJd-IM^N}b6dPByt4QEwO!xq{!bVBsIu)8?-TBy%wDZb zOQ*0lZkoc|(DFWV)>( #hAk*us(QQ2Q+#XAI$puG?w%*Ix&#-%MwZ*AKwii$4>OW!Laqk`ff428F z2M^pY-v53-!?Y;w)U91zT0jS?mbgZgq$HN4S|t~y0x1R~10y3{14CUy%Mc@DD?@WD zLsM-711kdqzv(MOP&DM`r(~v8;?`h)N)VV}7!*J@6z8XvlqVLYGGvsL6ck(O>u2UB zrl$gNW^%S(eo^|K^Rjb+Y9&BwLo!NpldP;<@{>z*Q}ar!tO9^aix~`;|KF{Trp6Ow zij|c|YG!&y34@`fkwa`@C{T?!k~vT{;h8BV86YK>*C=uTl}I8f@y*OlEvYO>WdOTM zzaTH&ep8qqnmN89KvfKeW+p~v#wJF_rr}MpAanSU%n8n{N@Xx`a+{j|ig%;fyMVtquA>zkw{Sz07o7^E6o7^Eec8K;@2m>C!v jrkN!hSXiW)Sn2_F=mFjLGWtaU&;|xiS3j3^P63>n92TFa?d@v=X}oh-g|ED z5hf#Mj^|=e0KgntEF}r^0Z#Lnfz6bfqn(&@6_Dv<0B)4bwz1uuNp5Ts9f16m02F)& zfCUQ`XaSHz0O&ISfX@QpD=lwLTnhkhH#43^P1vORUxPta(Ko8-6jfS+dM`345$bnw zbbIAPX-suZ1!^|i^*YLsSXE1-sq>eKaLE7TMgri zD)iU(kH?D)8nso#*1hYq96w~(k)nC|++0;Yda`)r>Ep?Br;TrWEw5gfg&Dem4_0=% z_DT(kWa~!^Q(BEp%+vi)g-%S^t1CuR;?;S%g9%jCY@@;(dlhdaiIMEGj2Ia7K&S2A zU>qTb^fUxS6R{MIvpI$m7{bYhvBfNDY`P49*$bS81Lw;9u%J6aqf_10xCOrR=O?>G z=&%|VjY4LT9u_MFTiTgkGv8fX-ZQi!wES>g^>Tw-&|Im6+;L|WNm_lcubr$=uuz4j zF+q8LCA;=YT40=?^0fXTdg$)gU0$2WfyZa^ArUUQzo0kBiu=9A-*~j=$86?yt_JmL zlAGq-i@I{7`{|eNj}}%o4ZD+i56(5O>R|Y`zA5v0{`T9xbtfyT4gkM_MUbmkNzkK! z6E2_E;fuRE`zr#dWdkNqs%v|HYN--OEqk_?oWVbHIppGu!c$|bMEh~aHb(~EM?F(t z>cg}Zm# z<+{Yy(j+tG&Esyc&9%SYsZssB#{q)hm#p=kx9^BgY-aHZmnX_FBYJMB$D`&4)*?$h z-;=h#wRGp=fQX+8D`)v6dO%rq7t7LXw?52js&~9}d{zRpdb>i-V!a0|5NaBd$wqiE zHU*f6^JF7B7WX~7p(7@k9|=P;M_qb z;Ujz4xjZ055UC8t<3(b&fQOlgn-wa_72JNjxhV8pkFvfS9&fm-yQ6?gEBFfrj9vHG{8bTL|c}Sj= z2mU%0UYa9Ve>0Wwi4L8GQGgH`PK*o-Cx%6ADO}>z@t&rWEXwBrC_4JorFBDCDs@^a zC5Z<3qHG>^b-XwS$(9K4eD*gYt|Ui>|EJ~na6TuB#3n(!FcQS)M27L#WJW>+0zZ-q dkx2aTs8FmT6g!`8n^ubL0BBSO<$82R;h#w)V66ZE literal 0 HcmV?d00001 diff --git a/public/favicon/favicon-96x96.png b/public/favicon/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..f5df73a4e0881770ce80971209a45be5427a1aa0 GIT binary patch literal 2561 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 G@B9tNp^SF` literal 0 HcmV?d00001 diff --git a/public/favicon/manifest.json b/public/favicon/manifest.json new file mode 100644 index 0000000..013d4a6 --- /dev/null +++ b/public/favicon/manifest.json @@ -0,0 +1,41 @@ +{ + "name": "App", + "icons": [ + { + "src": "\/android-icon-36x36.png", + "sizes": "36x36", + "type": "image\/png", + "density": "0.75" + }, + { + "src": "\/android-icon-48x48.png", + "sizes": "48x48", + "type": "image\/png", + "density": "1.0" + }, + { + "src": "\/android-icon-72x72.png", + "sizes": "72x72", + "type": "image\/png", + "density": "1.5" + }, + { + "src": "\/android-icon-96x96.png", + "sizes": "96x96", + "type": "image\/png", + "density": "2.0" + }, + { + "src": "\/android-icon-144x144.png", + "sizes": "144x144", + "type": "image\/png", + "density": "3.0" + }, + { + "src": "\/android-icon-192x192.png", + "sizes": "192x192", + "type": "image\/png", + "density": "4.0" + } + ] +} \ No newline at end of file diff --git a/public/favicon/ms-icon-144x144.png b/public/favicon/ms-icon-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..55a9e8eb59fa90a45177a5bc77a92baa73c520ad GIT binary patch literal 4676 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 literal 0 HcmV?d00001 diff --git a/public/favicon/ms-icon-150x150.png b/public/favicon/ms-icon-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..77013978d00ddcdb4dd49610bf36ee8c169c706d GIT binary patch literal 4888 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::class); + +$response = $kernel->handle( + $request = Request::capture() +)->send(); + +$kernel->terminate($request, $response); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..eb05362 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/public/static/images/aws.svg b/public/static/images/aws.svg new file mode 100755 index 0000000..ebd82ab --- /dev/null +++ b/public/static/images/aws.svg @@ -0,0 +1,2 @@ + + diff --git a/public/static/images/bitbucket.svg b/public/static/images/bitbucket.svg new file mode 100644 index 0000000..7687c39 --- /dev/null +++ b/public/static/images/bitbucket.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/custom.svg b/public/static/images/custom.svg new file mode 100644 index 0000000..cf5ab3a --- /dev/null +++ b/public/static/images/custom.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/digital-ocean.svg b/public/static/images/digital-ocean.svg new file mode 100755 index 0000000..083b8d9 --- /dev/null +++ b/public/static/images/digital-ocean.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/static/images/digitalocean.svg b/public/static/images/digitalocean.svg new file mode 100644 index 0000000..083b8d9 --- /dev/null +++ b/public/static/images/digitalocean.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/static/images/discord.svg b/public/static/images/discord.svg new file mode 100644 index 0000000..079b54b --- /dev/null +++ b/public/static/images/discord.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/static/images/dropbox.svg b/public/static/images/dropbox.svg new file mode 100644 index 0000000..804fc6e --- /dev/null +++ b/public/static/images/dropbox.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/email.svg b/public/static/images/email.svg new file mode 100644 index 0000000..8d70dfb --- /dev/null +++ b/public/static/images/email.svg @@ -0,0 +1 @@ + diff --git a/public/static/images/error.svg b/public/static/images/error.svg new file mode 100755 index 0000000..e5a22ec --- /dev/null +++ b/public/static/images/error.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/github.svg b/public/static/images/github.svg new file mode 100644 index 0000000..0e859cf --- /dev/null +++ b/public/static/images/github.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/gitlab.svg b/public/static/images/gitlab.svg new file mode 100644 index 0000000..5039ab6 --- /dev/null +++ b/public/static/images/gitlab.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/google.svg b/public/static/images/google.svg new file mode 100644 index 0000000..c49f3a7 --- /dev/null +++ b/public/static/images/google.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/static/images/hetzner.svg b/public/static/images/hetzner.svg new file mode 100644 index 0000000..041093c --- /dev/null +++ b/public/static/images/hetzner.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/laravel.svg b/public/static/images/laravel.svg new file mode 100644 index 0000000..5b1a5e9 --- /dev/null +++ b/public/static/images/laravel.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/linode.svg b/public/static/images/linode.svg new file mode 100755 index 0000000..1bc4bbc --- /dev/null +++ b/public/static/images/linode.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/static/images/logo.png b/public/static/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4ca4efa646b155e5f8b79fc2c6fbe63d7916fcd4 GIT binary patch literal 19403 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 literal 0 HcmV?d00001 diff --git a/public/static/images/mariadb.svg b/public/static/images/mariadb.svg new file mode 100644 index 0000000..ef74d95 --- /dev/null +++ b/public/static/images/mariadb.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/public/static/images/monitoring.svg b/public/static/images/monitoring.svg new file mode 100644 index 0000000..88803ce --- /dev/null +++ b/public/static/images/monitoring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/mysql.svg b/public/static/images/mysql.svg new file mode 100644 index 0000000..34358d2 --- /dev/null +++ b/public/static/images/mysql.svg @@ -0,0 +1,9 @@ + + + MySQL + + + + + + diff --git a/public/static/images/nginx.svg b/public/static/images/nginx.svg new file mode 100644 index 0000000..38bc663 --- /dev/null +++ b/public/static/images/nginx.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/static/images/openvpn.svg b/public/static/images/openvpn.svg new file mode 100644 index 0000000..7203f28 --- /dev/null +++ b/public/static/images/openvpn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/php.svg b/public/static/images/php.svg new file mode 100644 index 0000000..bf57d7c --- /dev/null +++ b/public/static/images/php.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/redis.svg b/public/static/images/redis.svg new file mode 100644 index 0000000..675dc72 --- /dev/null +++ b/public/static/images/redis.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/server.svg b/public/static/images/server.svg new file mode 100755 index 0000000..cf5ab3a --- /dev/null +++ b/public/static/images/server.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/slack.svg b/public/static/images/slack.svg new file mode 100644 index 0000000..98dc80b --- /dev/null +++ b/public/static/images/slack.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/static/images/supervisor.svg b/public/static/images/supervisor.svg new file mode 100644 index 0000000..40866cd --- /dev/null +++ b/public/static/images/supervisor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/telegram.svg b/public/static/images/telegram.svg new file mode 100644 index 0000000..9950d60 --- /dev/null +++ b/public/static/images/telegram.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/static/images/ufw.svg b/public/static/images/ufw.svg new file mode 100644 index 0000000..0cf1d56 --- /dev/null +++ b/public/static/images/ufw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/vitomonitor.svg b/public/static/images/vitomonitor.svg new file mode 100644 index 0000000..88803ce --- /dev/null +++ b/public/static/images/vitomonitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/vultr.svg b/public/static/images/vultr.svg new file mode 100755 index 0000000..53ed449 --- /dev/null +++ b/public/static/images/vultr.svg @@ -0,0 +1 @@ +sygnet__on-white \ No newline at end of file diff --git a/public/static/images/wordpress.svg b/public/static/images/wordpress.svg new file mode 100644 index 0000000..ac653dc --- /dev/null +++ b/public/static/images/wordpress.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/www.svg b/public/static/images/www.svg new file mode 100755 index 0000000..3c5580b --- /dev/null +++ b/public/static/images/www.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/libs/ace/ace.js b/public/static/libs/ace/ace.js new file mode 100755 index 0000000..eccca70 --- /dev/null +++ b/public/static/libs/ace/ace.js @@ -0,0 +1,17 @@ +(function(){function o(n){var i=e;n&&(e[n]||(e[n]={}),i=e[n]);if(!i.define||!i.define.packaged)t.original=i.define,i.define=t,i.define.packaged=!0;if(!i.require||!i.require.packaged)r.original=i.require,i.require=r,i.require.packaged=!0}var ACE_NAMESPACE = "ace",e=function(){return this}();!e&&typeof window!="undefined"&&(e=window);if(!ACE_NAMESPACE&&typeof requirejs!="undefined")return;var t=function(e,n,r){if(typeof e!="string"){t.original?t.original.apply(this,arguments):(console.error("dropping module because define wasn't a string."),console.trace());return}arguments.length==2&&(r=n),t.modules[e]||(t.payloads[e]=r,t.modules[e]=null)};t.modules={},t.payloads={};var n=function(e,t,n){if(typeof t=="string"){var i=s(e,t);if(i!=undefined)return n&&n(),i}else if(Object.prototype.toString.call(t)==="[object Array]"){var o=[];for(var u=0,a=t.length;u1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;et.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n=0?parseFloat((s.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((s.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=s.match(/ Gecko\/\d+/),t.isOpera=typeof opera=="object"&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(s.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(s.split(" Chrome/")[1])||undefined,t.isEdge=parseFloat(s.split(" Edge/")[1])||undefined,t.isAIR=s.indexOf("AdobeAIR")>=0,t.isIPad=s.indexOf("iPad")>=0,t.isAndroid=s.indexOf("Android")>=0,t.isChromeOS=s.indexOf(" CrOS ")>=0,t.isIOS=/iPad|iPhone|iPod/.test(s)&&!window.MSStream,t.isIOS&&(t.isMac=!0),t.isMobile=t.isIPad||t.isAndroid}),ace.define("ace/lib/dom",["require","exports","module","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./useragent"),i="http://www.w3.org/1999/xhtml";t.buildDom=function o(e,t,n){if(typeof e=="string"&&e){var r=document.createTextNode(e);return t&&t.appendChild(r),r}if(!Array.isArray(e))return e;if(typeof e[0]!="string"||!e[0]){var i=[];for(var s=0;s=1.5:!0;if(typeof document!="undefined"){var s=document.createElement("div");t.HI_DPI&&s.style.transform!==undefined&&(t.HAS_CSS_TRANSFORMS=!0),!r.isEdge&&typeof s.style.animationName!="undefined"&&(t.HAS_CSS_ANIMATION=!0),s=null}t.HAS_CSS_TRANSFORMS?t.translate=function(e,t,n){e.style.transform="translate("+Math.round(t)+"px, "+Math.round(n)+"px)"}:t.translate=function(e,t,n){e.style.top=Math.round(n)+"px",e.style.left=Math.round(t)+"px"}}),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/keys",["require","exports","module","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./oop"),i=function(){var e={MODIFIER_KEYS:{16:"Shift",17:"Ctrl",18:"Alt",224:"Meta"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,"super":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:"Backspace",9:"Tab",13:"Return",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock"},PRINTABLE_KEYS:{32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e["return"],e.escape=e.esc,e.del=e["delete"],e[173]="-",function(){var t=["cmd","ctrl","alt","shift"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join("-")+"-"}(),e.KEY_MODS[0]="",e.KEY_MODS[-1]="input-",e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!="string"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function a(e,t,n){var a=u(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState("OS")||t.getModifierState("Win"))&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f="location"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1),a&8&&n>=91&&n<=93&&(n=-1);if(!a&&n===13){var f="location"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null)}var r=e("./keys"),i=e("./useragent"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent("on"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent("on"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s]("mousedown",e),r[s](l[o],e)}var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,"mousedown",c),i.isOldIE&&t.addListener(e,"dblclick",h)})};var u=!i.isMac||!i.isOpera||"KeyboardEvent"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var o=null;r(e,"keydown",function(e){o=e.keyCode}),r(e,"keypress",function(e){return a(n,e,o)})}else{var u=null;r(e,"keydown",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=a(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,"keypress",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,"keyup",function(e){s[e.keyCode]=null}),s||(f(),r(window,"focus",f))}};if(typeof window=="object"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+l++,i=function(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())};t.addListener(n,"message",i),n.postMessage(r,"*")}}t.$idleBlocked=!1,t.onIdle=function(e,n){return setTimeout(function r(){t.$idleBlocked?setTimeout(r,100):e()},n)},t.$idleBlockId=null,t.blockIdle=function(e){t.$idleBlockId&&clearTimeout(t.$idleBlockId),t.$idleBlocked=!0,t.$idleBlockId=setTimeout(function(){t.$idleBlocked=!1},e||100)},t.nextFrame=typeof window=="object"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.row0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n63,l=400,c=e("../lib/keys"),h=c.KEY_MODS,p=i.isIOS,d=p?/\s/:/\n/,v=function(e,t){function W(){x=!0,n.blur(),n.focus(),x=!1}function V(e){e.keyCode==27&&n.value.lengthC&&T[s]=="\n")o=c.end;else if(rC&&T.slice(0,s).split("\n").length>2)o=c.down;else if(s>C&&T[s-1]==" ")o=c.right,u=h.option;else if(s>C||s==C&&C!=N&&r==s)o=c.right;r!==s&&(u|=h.shift),o&&(t.onCommandKey(null,u,o),N=r,C=s,A(""))};document.addEventListener("selectionchange",s),t.on("destroy",function(){document.removeEventListener("selectionchange",s)})}var n=s.createElement("textarea");n.className="ace_text-input",n.setAttribute("wrap","off"),n.setAttribute("autocorrect","off"),n.setAttribute("autocapitalize","off"),n.setAttribute("spellcheck",!1),n.style.opacity="0",e.insertBefore(n,e.firstChild);var v=!1,m=!1,g=!1,y=!1,b="",w=!0,E=!1;i.isMobile||(n.style.fontSize="1px");var S=!1,x=!1,T="",N=0,C=0;try{var k=document.activeElement===n}catch(L){}r.addListener(n,"blur",function(e){if(x)return;t.onBlur(e),k=!1}),r.addListener(n,"focus",function(e){if(x)return;k=!0;if(i.isEdge)try{if(!document.hasFocus())return}catch(e){}t.onFocus(e),i.isEdge?setTimeout(A):A()}),this.$focusScroll=!1,this.focus=function(){if(b||f||this.$focusScroll=="browser")return n.focus({preventScroll:!0});var e=n.style.top;n.style.position="fixed",n.style.top="0px";try{var t=n.getBoundingClientRect().top!=0}catch(r){return}var i=[];if(t){var s=n.parentElement;while(s&&s.nodeType==1)i.push(s),s.setAttribute("ace_nocontext",!0),!s.parentElement&&s.getRootNode?s=s.getRootNode().host:s=s.parentElement}n.focus({preventScroll:!0}),t&&i.forEach(function(e){e.removeAttribute("ace_nocontext")}),setTimeout(function(){n.style.position="",n.style.top=="0px"&&(n.style.top=e)},0)},this.blur=function(){n.blur()},this.isFocused=function(){return k},t.on("beforeEndOperation",function(){if(t.curOp&&t.curOp.command.name=="insertstring")return;g&&(T=n.value="",z()),A()});var A=p?function(e){if(!k||v&&!e||y)return;e||(e="");var r="\n ab"+e+"cde fg\n";r!=n.value&&(n.value=T=r);var i=4,s=4+(e.length||(t.selection.isEmpty()?0:1));(N!=i||C!=s)&&n.setSelectionRange(i,s),N=i,C=s}:function(){if(g||y)return;if(!k&&!D)return;g=!0;var e=t.selection,r=e.getRange(),i=e.cursor.row,s=r.start.column,o=r.end.column,u=t.session.getLine(i);if(r.start.row!=i){var a=t.session.getLine(i-1);s=r.start.rowi+1?f.length:o,o+=u.length+1,u=u+"\n"+f}u.length>l&&(s=T.length&&e.value===T&&T&&e.selectionEnd!==C},M=function(e){if(g)return;v?v=!1:O(n)&&(t.selectAll(),A())},_=null;this.setInputHandler=function(e){_=e},this.getInputHandler=function(){return _};var D=!1,P=function(e,r){D&&(D=!1);if(m)return A(),e&&t.onPaste(e),m=!1,"";var i=n.selectionStart,s=n.selectionEnd,o=N,u=T.length-C,a=e,f=e.length-i,l=e.length-s,c=0;while(o>0&&T[c]==e[c])c++,o--;a=a.slice(c),c=1;while(u>0&&T.length-c>N-1&&T[T.length-c]==e[e.length-c])c++,u--;return f-=c-1,l-=c-1,a=a.slice(0,a.length-c+1),!r&&f==a.length&&!o&&!u&&!l?"":(y=!0,a&&!o&&!u&&!f&&!l||S?t.onTextInput(a):t.onTextInput(a,{extendLeft:o,extendRight:u,restoreStart:f,restoreEnd:l}),y=!1,T=e,N=i,C=s,a)},H=function(e){if(g)return U();var t=n.value,r=P(t,!0);(t.length>l+100||d.test(r))&&A()},B=function(e,t,n){var r=e.clipboardData||window.clipboardData;if(!r||u)return;var i=a||n?"Text":"text/plain";try{return t?r.setData(i,t)!==!1:r.getData(i)}catch(e){if(!n)return B(e,t,!0)}},j=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);B(e,s)?(p&&(A(s),v=s,setTimeout(function(){v=!1},10)),i?t.onCut():t.onCopy(),r.preventDefault(e)):(v=!0,n.value=s,n.select(),setTimeout(function(){v=!1,A(),i?t.onCut():t.onCopy()}))},F=function(e){j(e,!0)},I=function(e){j(e,!1)},q=function(e){var s=B(e);typeof s=="string"?(s&&t.onPaste(s,e),i.isIE&&setTimeout(A),r.preventDefault(e)):(n.value="",m=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,"select",M),r.addListener(n,"input",H),r.addListener(n,"cut",F),r.addListener(n,"copy",I),r.addListener(n,"paste",q),(!("oncut"in n)||!("oncopy"in n)||!("onpaste"in n))&&r.addListener(e,"keydown",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:I(e);break;case 86:q(e);break;case 88:F(e)}});var R=function(e){if(g||!t.onCompositionStart||t.$readOnly)return;g={};if(S)return;setTimeout(U,0),t.on("mousedown",W);var r=t.getSelectionRange();r.end.row=r.start.row,r.end.column=r.start.column,g.markerRange=r,g.selectionStart=N,t.onCompositionStart(g),g.useTextareaForIME?(n.value="",T="",N=0,C=0):(n.msGetInputContext&&(g.context=n.msGetInputContext()),n.getInputContext&&(g.context=n.getInputContext()))},U=function(){if(!g||!t.onCompositionUpdate||t.$readOnly)return;if(S)return W();if(g.useTextareaForIME)t.onCompositionUpdate(n.value);else{var e=n.value;P(e),g.markerRange&&(g.context&&(g.markerRange.start.column=g.selectionStart=g.context.compositionStartOffset),g.markerRange.end.column=g.markerRange.start.column+C-g.selectionStart)}},z=function(e){if(!t.onCompositionEnd||t.$readOnly)return;g=!1,t.onCompositionEnd(),t.off("mousedown",W),e&&H()},X=o.delayedCall(U,50).schedule.bind(null,null);r.addListener(n,"compositionstart",R),r.addListener(n,"compositionupdate",U),r.addListener(n,"keyup",V),r.addListener(n,"keydown",X),r.addListener(n,"compositionend",z),this.getElement=function(){return n},this.setCommandMode=function(e){S=e,n.readOnly=!1},this.setReadOnly=function(e){S||(n.readOnly=e)},this.setCopyWithEmptySelection=function(e){E=e},this.onContextMenu=function(e){D=!0,A(),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){b||(b=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+(i.isIE?"opacity:0.1;":"")+"text-indent: -"+(N+C)*t.renderer.characterWidth*.5+"px;";var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){s.translate(n,e.clientX-l-2,Math.min(e.clientY-f-2,c))};h(e);if(e.type!="mousedown")return;t.renderer.$isMousePressed=!0,clearTimeout($),i.isWin&&r.capture(t.container,h,J)},this.onContextMenuClose=J;var $,K=function(e){t.textInput.onContextMenu(e),J()};r.addListener(n,"mouseup",K),r.addListener(n,"mousedown",function(e){e.preventDefault(),J()}),r.addListener(t.renderer.scroller,"contextmenu",K),r.addListener(n,"contextmenu",K),p&&Q(e,t,n)};t.TextInput=v}),ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/useragent"],function(e,t,n){"use strict";function o(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function u(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function a(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/useragent"),i=0,s=550;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var i=this.editor,s=e.getButton();if(s!==0){var o=i.getSelectionRange(),u=o.isEmpty();(u||s==1)&&i.selection.moveToPosition(n),s==2&&(i.textInput.onContextMenu(e.domEvent),r.isMozilla||e.preventDefault());return}this.mousedownEvent.time=Date.now();if(t&&!i.isFocused()){i.focus();if(this.$focusTimeout&&!this.$clickSelection&&!i.inMultiSelectMode){this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;if(!this.mousedownEvent)return;this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle("ace_selecting"),this.setState("select")},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=a(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=a(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=u(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>i||t-this.mousedownEvent.time>this.$focusTimeout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=this.editor;this.$lastScroll||(this.$lastScroll={t:0,vx:0,vy:0,allowed:0});var n=this.$lastScroll,r=e.domEvent.timeStamp,i=r-n.t,o=i?e.wheelX/i:n.vx,u=i?e.wheelY/i:n.vy;i=1&&t.renderer.isScrollableBy(e.wheelX*e.speed,0)&&(f=!0),a<=1&&t.renderer.isScrollableBy(0,e.wheelY*e.speed)&&(f=!0);if(f)n.allowed=r;else if(r-n.allowedt.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("
"),i.setHtml(f),i.show(),t._signal("showGutterTooltip",i),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal("hideGutterTooltip",i),t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.moveCursorToPosition(e),S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.selection.fromOrientedRange(m),t.isFocused()&&!w&&t.$resetCursorStyle(),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.$resetCursorStyle()}this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle("")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.$resetCursorStyle(),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var n=s.isWin?"default":"move";e.renderer.setCursorStyle(n),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),ace.define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event"],function(e,t,n){"use strict";var r=e("./mouse_event").MouseEvent;t.addTouchListeners=function(e,t){function m(){a=null,clearTimeout(a),t.selection.isEmpty()&&t.selection.moveToPosition(c),n="wait"}function g(){a=null,clearTimeout(a),t.selection.moveToPosition(c);var e=h>=2?t.selection.getLineRange(c.row):t.session.getBracketRange(c);e&&!e.isEmpty()?t.selection.setRange(e):t.selection.selectWord(),n="wait"}function y(){l+=60,f=setInterval(function(){l--<=0&&(clearInterval(f),f=null),Math.abs(p)<.01&&(p=0),Math.abs(d)<.01&&(d=0),l<20&&(p=.9*p),l<20&&(d=.9*d),t.renderer.scrollBy(10*p,10*d)},10)}var n="scroll",i,s,o,u,a,f,l=0,c,h=0,p=0,d=0,v;e.addEventListener("contextmenu",function(e){if(!v)return;var n=t.textInput.getElement();n.focus()}),e.addEventListener("touchstart",function(e){var f=e.touches;if(a||f.length>1){clearTimeout(a),a=null,n="zoom";return}v=t.$mouseHandler.isMousePressed=!0;var y=f[0];i=y.clientX,s=y.clientY,p=d=0,e.clientX=y.clientX,e.clientY=y.clientY;var b=e.timeStamp;u=b;var w=new r(e,t);c=w.getDocumentPosition();if(b-o<500&&f.length==1&&!l)h++,e.preventDefault(),e.button=0,g();else{h=0,a=setTimeout(m,450);var E=t.selection.cursor,S=t.selection.isEmpty()?E:t.selection.anchor,x=t.renderer.$cursorLayer.getPixelPosition(E,!0),T=t.renderer.$cursorLayer.getPixelPosition(S,!0),N=t.renderer.scroller.getBoundingClientRect(),C=t.renderer.layerConfig.lineHeight,k=t.renderer.layerConfig.lineHeight,L=function(e,t){return e/=k,t=t/C-.75,e*e+t*t},A=L(e.clientX-N.left-x.left,e.clientY-N.top-x.top),O=L(e.clientX-N.left-T.left,e.clientY-N.top-T.top);A<3.5&&O<3.5&&(n=A>O?"cursor":"anchor"),O<3.5?n="anchor":A<3.5?n="cursor":n="scroll"}o=b}),e.addEventListener("touchend",function(e){v=t.$mouseHandler.isMousePressed=!1,f&&clearInterval(f),n=="zoom"?(n="",l=0):a?(t.selection.moveToPosition(c),l=0):n=="scroll"&&(y(),e.preventDefault()),clearTimeout(a),a=null}),e.addEventListener("touchmove",function(e){a&&(clearTimeout(a),a=null);var o=e.touches;if(o.length>1||n=="zoom")return;var f=o[0],l=i-f.clientX,c=s-f.clientY;if(n=="wait"){if(!(l*l+c*c>4))return e.preventDefault();n="cursor"}i=f.clientX,s=f.clientY,e.clientX=f.clientX,e.clientY=f.clientY;var h=e.timeStamp,v=h-u;u=h;if(n=="scroll"){var m=new r(e,t);m.speed=1,m.wheelX=l,m.wheelY=c,10*Math.abs(l)1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a),f()};var f=function(){!a.basePath&&!a.workerPath&&!a.modePath&&!a.themePath&&!Object.keys(a.$moduleUrls).length&&(console.error("Unable to infer path to ace from script src,","use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes","or with webpack use ace/webpack-resolver"),f=function(){})};t.init=l,t.version="1.4.5"}),ace.define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/mouse/touch_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("./touch_handler").addTouchListeners,l=e("../config"),c=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,"onMouseEvent"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel")),f(e.container,e);var l=e.renderer.$gutter;r.addListener(l,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(l,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(l,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(l,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(l,"mousedown",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousedown",n)),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor,s=this.editor.renderer;s.$isMousePressed=!0;var o=this,a=function(e){if(!e)return;if(i.isWebKit&&!e.which&&o.releaseMouse)return o.releaseMouse();o.x=e.clientX,o.y=e.clientY,t&&t(e),o.mouseEvent=new u(e,o.editor),o.$mouseMoved=!0},f=function(e){n.off("beforeEndOperation",c),clearInterval(h),l(),o[o.state+"End"]&&o[o.state+"End"](e),o.state="",o.isMousePressed=s.$isMousePressed=!1,s.$keepTextAreaAtCursor&&s.$moveTextAreaToCursor(),o.$onCaptureMouseMove=o.releaseMouse=null,e&&o.onMouseEvent("mouseup",e),n.endOperation()},l=function(){o[o.state]&&o[o.state](),o.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){f(e)});var c=function(e){if(!o.releaseMouse)return;n.curOp.command.name&&n.curOp.selectionChanged&&(o[o.state+"End"]&&o[o.state+"End"](),o.state="",o.releaseMouse())};n.on("beforeEndOperation",c),n.startOperation({command:{name:"mouse"}}),o.$onCaptureMouseMove=a,o.releaseMouse=r.capture(this.editor.container,a,f);var h=setInterval(l,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(c.prototype),l.defineOptions(c.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimeout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=c}),ace.define("ace/mouse/fold_handler",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";function i(e){e.on("click",function(t){var n=t.getDocumentPosition(),i=e.session,s=i.getFoldAt(n.row,n.column,1);s&&(t.getAccelKey()?i.removeFold(s):i.expandFold(s),t.stop());var o=t.domEvent&&t.domEvent.target;o&&r.hasCssClass(o,"ace_inline_button")&&r.hasCssClass(o,"ace_toggle_wrap")&&(i.setOption("wrap",!i.getUseWrapMode()),e.renderer.scrollCursorIntoView())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}var r=e("../lib/dom");t.FoldHandler=i}),ace.define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||""}).filter(Boolean).join(" ")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:"insertstring"},o=u.exec("insertstring",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal("keyboardActivity",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),ace.define("ace/lib/bidiutil",["require","exports","module"],function(e,t,n){"use strict";function F(e,t,n,r){var i=s?d:p,c=null,h=null,v=null,m=0,g=null,y=null,b=-1,w=null,E=null,T=[];if(!r)for(w=0,r=[];w0)if(g==16){for(w=b;w-1){for(w=b;w=0;C--){if(r[C]!=N)break;t[C]=s}}}function I(e,t,n){if(o=e){u=i+1;while(u=e)u++;for(a=i,l=u-1;a=t.length||(o=n[r-1])!=b&&o!=w||(c=t[r+1])!=b&&c!=w)return E;return u&&(c=w),c==o?c:E;case k:o=r>0?n[r-1]:S;if(o==b&&r+10&&n[r-1]==b)return b;if(u)return E;p=r+1,h=t.length;while(p=1425&&d<=2303||d==64286;o=t[p];if(v&&(o==y||o==T))return y}if(r<1||(o=t[r-1])==S)return E;return n[r-1];case S:return u=!1,f=!0,s;case x:return l=!0,E;case O:case M:case D:case P:case _:u=!1;case H:return E}}function R(e){var t=e.charCodeAt(0),n=t>>8;return n==0?t>191?g:B[t]:n==5?/[\u0591-\u05f4]/.test(e)?y:g:n==6?/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(e)?A:/[\u0660-\u0669\u066b-\u066c]/.test(e)?w:t==1642?L:/[\u06f0-\u06f9]/.test(e)?b:T:n==32&&t<=8287?j[t&255]:n==254?t>=65136?T:E:E}function U(e){return e>="\u064b"&&e<="\u0655"}var r=["\u0621","\u0641"],i=["\u063a","\u064a"],s=0,o=0,u=!1,a=!1,f=!1,l=!1,c=!1,h=!1,p=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],d=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],v=0,m=1,g=0,y=1,b=2,w=3,E=4,S=5,x=6,T=7,N=8,C=9,k=10,L=11,A=12,O=13,M=14,_=15,D=16,P=17,H=18,B=[H,H,H,H,H,H,H,H,H,x,S,x,N,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,S,S,S,x,N,E,E,L,L,L,E,E,E,E,E,k,C,k,C,C,b,b,b,b,b,b,b,b,b,b,C,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,H,H,H,H,H,H,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,C,E,L,L,L,L,E,E,E,E,g,E,E,H,E,E,L,L,b,b,E,g,E,E,E,b,g,E,E,E,E,E],j=[N,N,N,N,N,N,N,N,N,N,N,H,H,H,g,y,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N,S,O,M,_,D,P,C,L,L,L,L,L,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,C,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N];t.L=g,t.R=y,t.EN=b,t.ON_R=3,t.AN=4,t.R_H=5,t.B=6,t.RLE=7,t.DOT="\u00b7",t.doBidiReorder=function(e,n,r){if(e.length<2)return{};var i=e.split(""),o=new Array(i.length),u=new Array(i.length),a=[];s=r?m:v,F(i,a,i.length,n);for(var f=0;fT&&n[f]0&&i[f-1]==="\u0644"&&/\u0622|\u0623|\u0625|\u0627/.test(i[f])&&(a[f-1]=a[f]=t.R_H,f++);i[i.length-1]===t.DOT&&(a[i.length-1]=t.B),i[0]==="\u202b"&&(a[0]=t.RLE);for(var f=0;f=0&&(e=this.session.$docRowCache[n])}return e},this.getSplitIndex=function(){var e=0,t=this.session.$screenRowCache;if(t.length){var n,r=this.session.$getRowCacheIndex(t,this.currentRow);while(this.currentRow-e>0){n=this.session.$getRowCacheIndex(t,this.currentRow-e-1);if(n!==r)break;r=n,e++}}else e=this.currentRow;return e},this.updateRowLine=function(e,t){e===undefined&&(e=this.getDocumentRow());var n=e===this.session.getLength()-1,s=n?this.EOF:this.EOL;this.wrapIndent=0,this.line=this.session.getLine(e),this.isRtlDir=this.$isRtl||this.line.charAt(0)===this.RLE;if(this.session.$useWrapMode){var o=this.session.$wrapData[e];o&&(t===undefined&&(t=this.getSplitIndex()),t>0&&o.length?(this.wrapIndent=o.indent,this.wrapOffset=this.wrapIndent*this.charWidths[r.L],this.line=tt?this.session.getOverwrite()?e:e-1:t,i=r.getVisualFromLogicalIdx(n,this.bidiMap),s=this.bidiMap.bidiLevels,o=0;!this.session.getOverwrite()&&e<=t&&s[i]%2!==0&&i++;for(var u=0;ut&&s[i]%2===0&&(o+=this.charWidths[s[i]]),this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset),this.isRtlDir&&(o+=this.rtlLineOffset),o},this.getSelections=function(e,t){var n=this.bidiMap,r=n.bidiLevels,i,s=[],o=0,u=Math.min(e,t)-this.wrapIndent,a=Math.max(e,t)-this.wrapIndent,f=!1,l=!1,c=0;this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset);for(var h,p=0;p=u&&hn+s/2){n+=s;if(r===i.length-1){s=0;break}s=this.charWidths[i[++r]]}return r>0&&i[r-1]%2!==0&&i[r]%2===0?(e0&&i[r-1]%2===0&&i[r]%2!==0?t=1+(e>n?this.bidiMap.logicalFromVisual[r]:this.bidiMap.logicalFromVisual[r-1]):this.isRtlDir&&r===i.length-1&&s===0&&i[r-1]%2===0||!this.isRtlDir&&r===0&&i[r]%2!==0?t=1+this.bidiMap.logicalFromVisual[r]:(r>0&&i[r-1]%2!==0&&s!==0&&r--,t=this.bidiMap.logicalFromVisual[r]),t===0&&this.isRtlDir&&t++,t+this.wrapIndent}}).call(o.prototype),t.BidiHandler=o}),ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.cursor=this.lead=this.doc.createAnchor(0,0),this.anchor=this.doc.createAnchor(0,0),this.$silent=!1;var t=this;this.cursor.on("change",function(e){t.$cursorChanged=!0,t.$silent||t._emit("changeCursor"),!t.$isEmpty&&!t.$silent&&t._emit("changeSelection"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.anchor.on("change",function(){t.$anchorChanged=!0,!t.$isEmpty&&!t.$silent&&t._emit("changeSelection")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return!this.$isEmpty&&this.anchor.row!=this.cursor.row},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.$isEmpty=!1,this.anchor.setPosition(e,t)},this.getAnchor=this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.$isEmpty?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){this.$setSelection(0,0,Number.MAX_VALUE,Number.MAX_VALUE)},this.setRange=this.setSelectionRange=function(e,t){var n=t?e.end:e.start,r=t?e.start:e.end;this.$setSelection(n.row,n.column,r.row,r.column)},this.$setSelection=function(e,t,n,r){var i=this.$isEmpty,s=this.inMultiSelectMode;this.$silent=!0,this.$cursorChanged=this.$anchorChanged=!1,this.anchor.setPosition(e,t),this.cursor.setPosition(n,r),this.$isEmpty=!o.comparePoints(this.anchor,this.cursor),this.$silent=!1,this.$cursorChanged&&this._emit("changeCursor"),(this.$cursorChanged||this.$anchorChanged||i!=this.$isEmpty||s)&&this._emit("changeSelection")},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.wouldMoveIntoSoftTab=function(e,t,n){var r=e.column,i=e.column+t;return n<0&&(r=e.column-t,i=e.column),this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(r,i).split(" ").length-1==t},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.wouldMoveIntoSoftTab(e,n,-1)&&!this.session.getNavigateWithinSoftTabs()?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t);this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var i=this.session.getFoldAt(e,t,1);if(i){this.moveCursorTo(i.end.row,i.end.column);return}this.session.nonTokenRe.exec(r)&&(t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t));if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e0&&this.moveCursorWordLeft();return}this.session.tokenRe.exec(s)&&(t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0),this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t=0,n,r=/\s/,i=this.session.tokenRe;i.lastIndex=0;if(this.session.tokenRe.exec(e))t=this.session.tokenRe.lastIndex;else{while((n=e[t])&&r.test(n))t++;if(t<1){i.lastIndex=0;while((n=e[t])&&!i.test(n)){i.lastIndex=0,t++;if(r.test(n)){if(t>2){t--;break}while((n=e[t])&&r.test(n))t++;if(t>2)break}}}}return i.lastIndex=0,t},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column),r;t===0&&(e!==0&&(this.session.$bidiHandler.isBidiRow(n.row,this.lead.row)?(r=this.session.$bidiHandler.getPosLeft(n.column),n.column=Math.round(r/this.session.$bidiHandler.charWidths[0])):r=n.column*this.session.$bidiHandler.charWidths[0]),this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var i=this.session.screenToDocumentPosition(n.row+e,n.column,r);e!==0&&t===0&&i.row===this.lead.row&&i.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[i.row]&&(i.row>0||e>0)&&i.row++,this.moveCursorTo(i.row,i.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0;var i=this.session.getLine(e);/[\uDC00-\uDFFF]/.test(i.charAt(t))&&i.charAt(t-1)&&(this.lead.row==e&&this.lead.column==t+1?t-=1:t+=1),this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList&&e.length>1){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),ace.define("ace/tokenizer",["require","exports","module","ace/config"],function(e,t,n){"use strict";var r=e("./config"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;il){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;yi){c>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});while(l1&&n[0]!==r&&n.unshift("#tmp",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}},this.getCurrentTokenRange=function(){var e=this.$rowTokens[this.$tokenIndex],t=this.getCurrentTokenColumn();return new r(this.$row,t,this.$row,t+e.value.length)}}).call(i.prototype),t.TokenIterator=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c={'"':'"',"'":"'"},h=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},p=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},d=function(e){this.add("braces","insertion",function(t,n,r,i,s){var u=r.getCursorPosition(),a=i.doc.getLine(u.row);if(s=="{"){h(r);var l=r.getSelectionRange(),c=i.doc.getTextRange(l);if(c!==""&&c!=="{"&&r.getWrapBehavioursEnabled())return p(l,c,"{","}");if(d.isSaneInsertion(r,i))return/[\]\}\)]/.test(a[u.column])||r.inMultiSelectMode||e&&e.braces?(d.recordAutoInsert(r,i,"}"),{text:"{}",selection:[1,1]}):(d.recordMaybeInsert(r,i,"{"),{text:"{",selection:[1,1]})}else if(s=="}"){h(r);var v=a.substring(u.column,u.column+1);if(v=="}"){var m=i.$findOpeningBracket("}",{column:u.column+1,row:u.row});if(m!==null&&d.isAutoInsertedClosing(u,a,s))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(s=="\n"||s=="\r\n"){h(r);var g="";d.isMaybeInsertedClosing(u,a)&&(g=o.stringRepeat("}",f.maybeInsertedBrackets),d.clearMaybeInsertedClosing());var v=a.substring(u.column,u.column+1);if(v==="}"){var y=i.findMatchingBracket({row:u.row,column:u.column+1},"}");if(!y)return null;var b=this.$getIndent(i.getLine(y.row))}else{if(!g){d.clearMaybeInsertedClosing();return}var b=this.$getIndent(a)}var w=b+i.getTabString();return{text:"\n"+w+"\n"+b+g,selection:[1,w.length,1,w.length]}}d.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return p(s,o,"(",")");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return p(s,o,"[","]");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){var s=r.$mode.$quotes||c;if(i.length==1&&s[i]){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;h(n);var o=i,u=n.getSelectionRange(),a=r.doc.getTextRange(u);if(a!==""&&(a.length!=1||!s[a])&&n.getWrapBehavioursEnabled())return p(u,a,o,o);if(!a){var f=n.getCursorPosition(),l=r.doc.getLine(f.row),d=l.substring(f.column-1,f.column),v=l.substring(f.column,f.column+1),m=r.getTokenAt(f.row,f.column),g=r.getTokenAt(f.row,f.column+1);if(d=="\\"&&m&&/escape/.test(m.type))return null;var y=m&&/string|escape/.test(m.type),b=!g||/string|escape/.test(g.type),w;if(v==o)w=y!==b,w&&/string\.end/.test(g.type)&&(w=!1);else{if(y&&!b)return null;if(y&&b)return null;var E=r.$mode.tokenRe;E.lastIndex=0;var S=E.test(d);E.lastIndex=0;var x=E.test(d);if(S||x)return null;if(v&&!/[\s;,.})\]\\]/.test(v))return null;var T=l[f.column-2];if(!(d!=o||T!=o&&!E.test(T)))return null;w=!0}return{text:w?o+o:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.$mode.$quotes||c,o=r.doc.getTextRange(i);if(!i.isMultiLine()&&s.hasOwnProperty(o)){h(n);var u=r.doc.getLine(i.start.row),a=u.substring(i.start.column+1,i.start.column+2);if(a==o)return i.end.column++,i}})};d.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},d.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},d.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},d.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},d.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},d.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},d.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},d.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(d,i),t.CstyleBehaviour=d}),ace.define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";var r=[48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2],i=0,s=[];for(var o=0;o2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(ne.length&&(E=e.length)}),u==Infinity&&(u=E,s=!1,o=!1),l&&u%f!=0&&(u=Math.floor(u/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new f(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,a=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new l(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new f(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new l(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);a.start.row==c&&(a.start.column+=h),a.end.row==c&&(a.end.column+=h),t.selection.fromOrientedRange(a)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)if(e[t]){var n=e[t],i=n.prototype.$id,s=r.$modes[i];s||(r.$modes[i]=s=new n),r.$modes[t]||(r.$modes[t]=s),this.$embeds.push(t),this.$modes[t]=s}var o=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.columnthis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,r==-1&&(r=t),s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action=="remove")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.rowthis.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row=r)break}if(e.action=="insert"){var f=i-r,l=-t.column+n.column;for(;or)break;a.start.row==r&&a.start.column>=t.column&&(a.start.column!=t.column||!this.$insertRight)&&(a.start.column+=l,a.start.row+=f);if(a.end.row==r&&a.end.column>=t.column){if(a.end.column==t.column&&this.$insertRight)continue;a.end.column==t.column&&l>0&&oa.start.column&&a.end.column==s[o+1].start.column&&(a.end.column-=l),a.end.column+=l,a.end.row+=f}}}else{var f=r-i,l=t.column-n.column;for(;oi)break;if(a.end.rowt.column)a.end.column=t.column,a.end.row=t.row}else a.end.column+=l,a.end.row+=f;else a.end.row>i&&(a.end.row+=f);if(a.start.rowt.column)a.start.column=t.column,a.start.row=t.row}else a.start.column+=l,a.start.row+=f;else a.start.row>i&&(a.start.row+=f)}}if(f!=0&&o=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i=t){u=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column,c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);c&&!c.range.isStart(u,a)&&this.removeFold(c),h&&!h.range.isEnd(f,l)&&this.removeFold(h);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(tl)break}while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return f.end.row=i.getCurrentTokenRow(),f.end.column=i.getCurrentTokenColumn()+s.value.length-2,f}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action=="remove")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{","<":">",">":"<"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,u),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;e.addSession(this),this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.mergeUndoDeltas=!1},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}else this.$syncInformUndoManager=function(){}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){},add:function(){},addSelection:function(){},startNewGroup:function(){},addSession:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):" "},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.setNavigateWithinSoftTabs=function(e){this.setOption("navigateWithinSoftTabs",e)},this.getNavigateWithinSoftTabs=function(){return this.$navigateWithinSoftTabs},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(oe&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;ao){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=e.length-1;n!=-1;n--){var r=e[n];r.action=="insert"||r.action=="remove"?this.doc.revertDelta(r):r.folds&&this.addFolds(r.folds)}!t&&this.$undoSelect&&(e.selectionBefore?this.selection.fromJSON(e.selectionBefore):this.selection.setRange(this.$getUndoSelection(e,!0))),this.$fromUndo=!1},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=0;ne.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,f=s.start,o=f.row-a.row,u=f.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new l(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new l(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$bidiHandler.markAsDirty(),this.$useWrapMode&&this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n==="remove"){this[t?"$wrapData":"$rowLengthCache"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n==="remove"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),o=this.$wrapData,u=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,o){var u;if(e!=null){u=this.$getDisplayTokens(e,a.length),u[0]=n;for(var f=1;fr-b){var w=f+r-b;if(e[w-1]>=c&&e[w]>=c){y(w);continue}if(e[w]==n||e[w]==s){for(w;w!=f-1;w--)if(e[w]==n)break;if(w>f){y(w);continue}w=f+r;for(w;w>2)),f-1);while(w>E&&e[w]E&&e[w]E&&e[w]==a)w--}else while(w>E&&e[w]E){y(++w);continue}w=f+r,e[w]==t&&w--,y(w-b)}return o},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o39&&u<48||u>57&&u<64?i.push(a):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]=0)var u=f[l],i=this.$docRowCache[l],h=e>f[c-1];else var h=!c;var p=this.getLength()-1,d=this.getNextFoldLine(i),v=d?d.start.row:Infinity;while(u<=e){a=this.getRowLength(i);if(u+a>e||i>=p)break;u+=a,i++,i>v&&(i=d.end.row+1,d=this.getNextFoldLine(i,d),v=d?d.start.row:Infinity),h&&(this.$docRowCache.push(i),this.$screenRowCache.push(u))}if(d&&d.start.row<=i)r=this.getFoldDisplayLine(d),i=d.start.row;else{if(u+a<=e||i>p)return{row:p,column:this.getLine(p).length};r=this.getLine(i),d=null}var m=0,g=Math.floor(e-u);if(this.$useWrapMode){var y=this.$wrapData[i];y&&(o=y[g],g>0&&y.length&&(m=y.indent,s=y[g-1]||y[y.length-1],r=r.substring(s)))}return n!==undefined&&this.$bidiHandler.isBidiRow(u+g,i,g)&&(t=this.$bidiHandler.offsetToCol(n)),s+=this.$getStringScreenWidth(r,t-m)[1],this.$useWrapMode&&s>=o&&(s=o-1),d?d.idxToPosition(s):{row:i,column:s}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;ro&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;sn)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()},this.isFullWidth=m}.call(d.prototype),e("./edit_session/folding").Folding.call(d.prototype),e("./edit_session/bracket_match").BracketMatch.call(d.prototype),o.defineOptions(d.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0)))},initialValue:"auto"},indentedSoftWrap:{set:function(){this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0))},initialValue:!0},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){e=parseInt(e),e>0&&this.$tabSize!==e&&(this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize"))},initialValue:4,handlesSet:!0},navigateWithinSoftTabs:{initialValue:!1},foldStyle:{set:function(e){this.setFoldStyle(e)},handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId},handlesSet:!0}}),t.EditSession=d}),ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";function u(e,t){function n(e){return/\w/.test(e)||t.regExp?"\\b":""}return n(e[0])+e+n(e[e.length-1])}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i,o){return r=new s(e,n,i,o),n==o&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start)?(r=null,!1):!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;hv)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;gE&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g=u;n--)if(c(n,Number.MAX_VALUE,e))return;if(t.wrap==0)return;for(n=a,u=o.row;n>=u;n--)if(c(n,Number.MAX_VALUE,e))return};else var f=function(e){var n=o.row;if(c(n,o.column,e))return;for(n+=1;n<=a;n++)if(c(n,0,e))return;if(t.wrap==0)return;for(n=u,a=o.row;n<=a;n++)if(c(n,0,e))return};if(t.$isMultiLine)var l=n.length,c=function(t,i,s){var o=r?t-l+1:t;if(o<0)return;var u=e.getLine(o),a=u.search(n[0]);if(!r&&ai)return;if(s(o,a,o+l-1,c))return!0};else if(r)var c=function(t,r,i){var s=e.getLine(t),o=[],u,a=0;n.lastIndex=0;while(u=n.exec(s)){var f=u[0].length;a=u.index;if(!f){if(a>=s.length)break;n.lastIndex=a+=1}if(u.index+f>r)break;o.push(u.index,f)}for(var l=o.length-1;l>=0;l-=2){var c=o[l-1],f=o[l];if(i(t,c,t,c+f))return!0}};else var c=function(t,r,i){var s=e.getLine(t),o,u;n.lastIndex=r;while(u=n.exec(s)){var a=u[0].length;o=u.index;if(i(t,o,t,o+a))return!0;if(!a){n.lastIndex=o+=1;if(o>=s.length)return!1}}};return{forEach:f}}}).call(o.prototype),t.Search=o}),ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e("../lib/keys"),i=e("../lib/useragent"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e=="object"&&e.bindKey&&e.bindKey.position||(e.isDefault?-100:0)}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e=="string"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e=="object"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t=="function")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split("|").forEach(function(e){var r="";if(e.indexOf(" ")!=-1){var i=e.split(/\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?" ":"")+n,this._addCommandToBinding(r,"chainKeys")},this),r+=" "}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!="number"&&(r=e(n));var o=i[t];for(s=0;sr)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=" "+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o=="chainKeys"||o[o.length-1]=="chainKeys")return e.$keyChain=e.$keyChain||i,{command:"null"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=""}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||""}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").MultiHashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;if(this.$checkCommandState!=0&&e.isAvailable&&!e.isAvailable(t))return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit("exec",i),this._signal("afterExec",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","F4"),exec:function(e){i.loadModule("./ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Shift-F4"),exec:function(e){i.loadModule("./ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",description:"Select all",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",description:"Center selection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",description:"Go to line...",bindKey:o("Ctrl-L","Command-L"),exec:function(e,t){typeof t=="number"&&!isNaN(t)&&e.gotoLine(t),e.prompt({$type:"gotoLine"})},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"foldall",description:"Fold all",bindKey:o(null,"Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",description:"Fold other",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",description:"Unfold all",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",description:"Find next",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",description:"Find previous",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",description:"Select or find next",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",description:"Select or find previous",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",description:"Find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",description:"Overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",description:"Select to start",bindKey:o("Ctrl-Shift-Home","Command-Shift-Home|Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",description:"Go to start",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",description:"Select up",bindKey:o("Shift-Up","Shift-Up|Ctrl-Shift-P"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golineup",description:"Go line up",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttoend",description:"Select to end",bindKey:o("Ctrl-Shift-End","Command-Shift-End|Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",description:"Go to end",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",description:"Select down",bindKey:o("Shift-Down","Shift-Down|Ctrl-Shift-N"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",description:"Go line down",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",description:"Select word left",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",description:"Go to word left",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",description:"Select to line start",bindKey:o("Alt-Shift-Left","Command-Shift-Left|Ctrl-Shift-A"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",description:"Go to line start",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",description:"Select left",bindKey:o("Shift-Left","Shift-Left|Ctrl-Shift-B"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",description:"Go to left",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",description:"Select word right",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",description:"Go to word right",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",description:"Select to line end",bindKey:o("Alt-Shift-Right","Command-Shift-Right|Shift-End|Ctrl-Shift-E"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",description:"Go to line end",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",description:"Select right",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",description:"Go to right",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",description:"Select page down",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",description:"Page down",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",description:"Go to page down",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",description:"Select page up",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",description:"Page up",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",description:"Go to page up",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",description:"Scroll up",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",description:"Scroll down",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",description:"Select line start",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",description:"Select line end",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",description:"Toggle recording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",description:"Replay macro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",description:"Jump to matching",bindKey:o("Ctrl-P","Ctrl-P"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"selecttomatching",description:"Select to matching",bindKey:o("Ctrl-Shift-P","Ctrl-Shift-P"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"expandToMatching",description:"Expand to matching",bindKey:o("Ctrl-Shift-M","Ctrl-Shift-M"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"passKeysToBrowser",description:"Pass keys to browser",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:"copy",description:"Copy",exec:function(e){},readOnly:!0},{name:"cut",description:"Cut",exec:function(e){var t=e.$copyWithEmptySelection&&e.selection.isEmpty(),n=t?e.selection.getLineRange():e.selection.getRange();e._emit("cut",n),n.isEmpty()||e.session.remove(n),e.clearSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"paste",description:"Paste",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:"cursor"},{name:"removeline",description:"Remove line",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",description:"Duplicate selection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",description:"Sort lines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",description:"Toggle comment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",description:"Toggle block comment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",description:"Modify number up",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"modifyNumberDown",description:"Modify number down",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"replace",description:"Replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",description:"Undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",description:"Redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",description:"Copy lines up",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",description:"Move lines up",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",description:"Copy lines down",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",description:"Move lines down",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",description:"Delete",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",description:"Backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",description:"Cut or delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",description:"Remove to line start",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",description:"Remove to line end",bindKey:o("Alt-Delete","Ctrl-K|Command-Delete"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestarthard",description:"Remove to line start hard",bindKey:o("Ctrl-Shift-Backspace",null),exec:function(e){var t=e.selection.getRange();t.start.column=0,e.session.remove(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineendhard",description:"Remove to line end hard",bindKey:o("Ctrl-Shift-Delete",null),exec:function(e){var t=e.selection.getRange();t.end.column=Number.MAX_VALUE,e.session.remove(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",description:"Remove word left",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",description:"Remove word right",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",description:"Outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",description:"Indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",description:"Block outdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",description:"Block indent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",description:"Insert string",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",description:"Insert text",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",description:"Split line",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",description:"Transpose letters",bindKey:o("Alt-Shift-X","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",description:"To uppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",description:"To lowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",description:"Expand to line",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",description:"Join lines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+10?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",description:"Invert selection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}var s=this.selection.toJSON();this.curOp.selectionAfter=s,this.$lastSel=this.selection.toJSON(),this.session.getUndoManager().addSelection(s),this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e=="string"&&e!="ace"){this.$keybindingId=e;var n=this;g.loadModule(["keybinding",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off("change",this.$onDocumentChange),this.session.off("changeMode",this.$onChangeMode),this.session.off("tokenizerUpdate",this.$onTokenizerUpdate),this.session.off("changeTabSize",this.$onChangeTabSize),this.session.off("changeWrapLimit",this.$onChangeWrapLimit),this.session.off("changeWrapMode",this.$onChangeWrapMode),this.session.off("changeFold",this.$onChangeFold),this.session.off("changeFrontMarker",this.$onChangeFrontMarker),this.session.off("changeBackMarker",this.$onChangeBackMarker),this.session.off("changeBreakpoint",this.$onChangeBreakpoint),this.session.off("changeAnnotation",this.$onChangeAnnotation),this.session.off("changeOverwrite",this.$onCursorChange),this.session.off("changeScrollTop",this.$onScrollTopChange),this.session.off("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.off("changeCursor",this.$onCursorChange),n.off("changeSelection",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.onCursorChange(),this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal("changeSession",{session:e,oldSession:t}),this.curOp=null,t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this}),e&&e.bgTokenizer&&e.bgTokenizer.scheduleStart()},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container).fontSize},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,"ace_bracket","text"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf("tag-open")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column,r=t.end.column,i=e.getLine(t.start.row),s=i.substring(n,r);if(s.length>5e3||!/[\w\d]/.test(s))return;var o=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:s}),u=i.substring(n-1,r+1);if(!o.test(u))return;return o},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText(),t=this.session.doc.getNewLineCharacter(),n=!1;if(!e&&this.$copyWithEmptySelection){n=!0;var r=this.selection.getAllRanges();for(var i=0;is.length||i.length<2||!i[1])return this.commands.exec("insertstring",this,t);for(var o=s.length;o--;){var u=s[o];u.isEmpty()||r.remove(u),r.insert(u.start,i[o])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),"insertion",this,n,e);s&&(e!==s.text&&(this.inVirtualSelectionMode||(this.session.mergeUndoDeltas=!1,this.mergeNextCommand=!1)),e=s.text)}e==" "&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()&&e.indexOf("\n")==-1){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e=="\n"||e=="\r\n"){var u=n.getLine(i.row);if(i.column>u.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e,t){if(!t)return this.keyBinding.onTextInput(e);this.startOperation({command:{name:"insertstring"}});var n=this.applyComposition.bind(this,e,t);this.selection.rangeCount?this.forEachSelection(n):n(),this.endOperation()},this.applyComposition=function(e,t){if(t.extendLeft||t.extendRight){var n=this.selection.getRange();n.start.column-=t.extendLeft,n.end.column+=t.extendRight,this.selection.setRange(n),!e&&!n.isEmpty()&&this.remove()}(e||!this.selection.isEmpty())&&this.insert(e,!0);if(t.restoreStart||t.restoreEnd){var n=this.selection.getRange();n.start.column-=t.restoreStart,n.end.column-=t.restoreEnd,this.selection.setRange(n)}},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;tt.toLowerCase()?1:0});var i=new p(0,0,0,0);for(var r=e.first;r<=e.last;r++){var s=t.getLine(r);i.start.row=r,i.end.row=r,i.end.column=s.length,t.replace(i,n[r-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n=u&&o<=a&&(n=t,f.selection.clearSelection(),f.moveCursorTo(e,u+r),f.selection.selectTo(e,a+r)),u=a});var l=this.$toggleWordPairs,c;for(var h=0;hp+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(e)},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection());var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.selection.selectAll()},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(s.value.match(/[{}()\[\]]/g))for(;f=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.session.unfold(e),this.selection.setSelectionRange(e);var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.session.getUndoManager().undo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.session.getUndoManager().redo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.topwindow.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off("changeSelection",s),this.renderer.off("afterRender",u),this.renderer.off("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))},this.prompt=function(e,t,n){var r=this;g.loadModule("./ext/prompt",function(i){i.prompt(r,e,t,n)})}}.call(w.prototype),g.defineOptions(w.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.textInput.setReadOnly(e),this.$resetCursorStyle()},initialValue:!1},copyWithEmptySelection:{set:function(e){this.textInput.setCopyWithEmptySelection(e)},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.$keybindingId},handlesSet:!0},value:{set:function(e){this.session.setValue(e)},get:function(){return this.getValue()},handlesSet:!0,hidden:!0},session:{set:function(e){this.setSession(e)},get:function(){return this.session},handlesSet:!0,hidden:!0},showLineNumbers:{set:function(e){this.renderer.$gutterLayer.setShowLineNumbers(e),this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER),e&&this.$relativeLineNumbers?E.attach(this):E.detach(this)},initialValue:!0},relativeLineNumbers:{set:function(e){this.$showLineNumbers&&e?E.attach(this):E.detach(this)}},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",displayIndentGuides:"renderer",showGutter:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",hasCssTransforms:"renderer",maxPixelHeight:"renderer",useTextareaForIME:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimeout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",navigateWithinSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"});var E={getText:function(e,t){return(Math.abs(e.selection.lead.row-t)||t+1+(t<9?"\u00b7":""))+""},getWidth:function(e,t,n){return Math.max(t.toString().length,(n.lastRow+1).toString().length,2)*n.characterWidth},update:function(e,t){t.renderer.$loop.schedule(t.renderer.CHANGE_GUTTER)},attach:function(e){e.renderer.$gutterLayer.$renderer=this,e.on("changeSelection",this.update),this.update(null,e)},detach:function(e){e.renderer.$gutterLayer.$renderer==this&&(e.renderer.$gutterLayer.$renderer=null),e.off("changeSelection",this.update),this.update(null,e)}};t.Editor=w}),ace.define("ace/undomanager",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){for(var n=t;n--;){var r=e[n];if(r&&!r[0].ignore){while(n0){a.row+=i,a.column+=a.row==r.row?s:0;continue}!t&&l<=0&&(a.row=n.row,a.column=n.column,l===0&&(a.bias=1))}}function f(e){return{row:e.row,column:e.column}}function l(e){return{start:f(e.start),end:f(e.end),action:e.action,lines:e.lines.slice()}}function c(e){e=e||this;if(Array.isArray(e))return e.map(c).join("\n");var t="";e.action?(t=e.action=="insert"?"+":"-",t+="["+e.lines+"]"):e.value&&(Array.isArray(e.value)?t=e.value.map(h).join("\n"):t=h(e.value)),e.start&&(t+=h(e));if(e.id||e.rev)t+=" ("+(e.id||e.rev)+")";return t}function h(e){return e.start.row+":"+e.start.column+"=>"+e.end.row+":"+e.end.column}function p(e,t){var n=e.action=="insert",r=t.action=="insert";if(n&&r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}else if(!n&&r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(!n&&!r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}return[t,e]}function d(e,t){for(var n=e.length;n--;)for(var r=0;r=0?m(e,t,-1):o(e.start,t.start)<=0?m(t,e,1):(m(e,s.fromPoints(t.start,e.start),-1),m(t,e,1));else if(!n&&r)o(t.start,e.end)>=0?m(t,e,-1):o(t.start,e.start)<=0?m(e,t,1):(m(t,s.fromPoints(e.start,t.start),-1),m(e,t,1));else if(!n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0)){var i,u;return o(e.start,t.start)<0&&(i=e,e=y(e,t.start)),o(e.end,t.end)>0&&(u=y(e,t.end)),g(t.end,e.start,e.end,-1),u&&!i&&(e.lines=u.lines,e.start=u.start,e.end=u.end,u=e),[t,i,u].filter(Boolean)}m(e,t,-1)}return[t,e]}function m(e,t,n){g(e.start,t.start,t.end,n),g(e.end,t.start,t.end,n)}function g(e,t,n,r){e.row==(r==1?t:n).row&&(e.column+=r*(n.column-t.column)),e.row+=r*(n.row-t.row)}function y(e,t){var n=e.lines,r=e.end;e.end=f(t);var i=e.end.row-e.start.row,s=n.splice(i,n.length),o=i?t.column:t.column-e.start.column;n.push(s[0].substring(0,o)),s[0]=s[0].substr(o);var u={start:f(t),end:r,lines:s,action:e.action};return u}function b(e,t){t=l(t);for(var n=e.length;n--;){var r=e[n];for(var i=0;i0},this.canRedo=function(){return this.$redoStack.length>0},this.bookmark=function(e){e==undefined&&(e=this.$rev),this.mark=e},this.isAtBookmark=function(){return this.$rev===this.mark},this.toJSON=function(){},this.fromJSON=function(){},this.hasUndo=this.canUndo,this.hasRedo=this.canRedo,this.isClean=this.isAtBookmark,this.markClean=this.bookmark,this.$prettyPrint=function(e){return e?c(e):c(this.$undoStack)+"\n---\n"+c(this.$redoStack)}}).call(r.prototype);var s=e("./range").Range,o=s.comparePoints,u=s.comparePoints;t.UndoManager=r}),ace.define("ace/layer/lines",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=function(e,t){this.element=e,this.canvasHeight=t||5e5,this.element.style.height=this.canvasHeight*2+"px",this.cells=[],this.cellCache=[],this.$offsetCoefficient=0};(function(){this.moveContainer=function(e){r.translate(this.element,0,-(e.firstRowScreen*e.lineHeight%this.canvasHeight)-e.offset*this.$offsetCoefficient)},this.pageChanged=function(e,t){return Math.floor(e.firstRowScreen*e.lineHeight/this.canvasHeight)!==Math.floor(t.firstRowScreen*t.lineHeight/this.canvasHeight)},this.computeLineTop=function(e,t,n){var r=t.firstRowScreen*t.lineHeight,i=Math.floor(r/this.canvasHeight),s=n.documentToScreenRow(e,0)*t.lineHeight;return s-i*this.canvasHeight},this.computeLineHeight=function(e,t,n){return t.lineHeight*n.getRowLength(e)},this.getLength=function(){return this.cells.length},this.get=function(e){return this.cells[e]},this.shift=function(){this.$cacheCell(this.cells.shift())},this.pop=function(){this.$cacheCell(this.cells.pop())},this.push=function(e){if(Array.isArray(e)){this.cells.push.apply(this.cells,e);var t=r.createFragment(this.element);for(var n=0;ns&&(a=i.end.row+1,i=t.getNextFoldLine(a,i),s=i?i.start.row:Infinity);if(a>r){while(this.$lines.getLength()>u+1)this.$lines.pop();break}o=this.$lines.get(++u),o?o.row=a:(o=this.$lines.createCell(a,e,this.session,f),this.$lines.push(o)),this.$renderCell(o,e,i,a),a++}this._signal("afterRender"),this.$updateGutterWidth(e)},this.$updateGutterWidth=function(e){var t=this.session,n=t.gutterRenderer||this.$renderer,r=t.$firstLineNumber,i=this.$lines.last()?this.$lines.last().text:"";if(this.$fixedWidth||t.$useWrapMode)i=t.getLength()+r-1;var s=n?n.getWidth(t,i,e):i.toString().length*e.characterWidth,o=this.$padding||this.$computePadding();s+=o.left+o.right,s!==this.gutterWidth&&!isNaN(s)&&(this.gutterWidth=s,this.element.parentNode.style.width=this.element.style.width=Math.ceil(this.gutterWidth)+"px",this._signal("changeGutterWidth",s))},this.$updateCursorRow=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.getCursor();if(this.$cursorRow===e.row)return;this.$cursorRow=e.row},this.updateLineHighlight=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.cursor.row;this.$cursorRow=e;if(this.$cursorCell&&this.$cursorCell.row==e)return;this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ",""));var t=this.$lines.cells;this.$cursorCell=null;for(var n=0;n=this.$cursorRow){if(r.row>this.$cursorRow){var i=this.session.getFoldLine(this.$cursorRow);if(!(n>0&&i&&i.start.row==t[n-1].row))break;r=t[n-1]}r.element.className="ace_gutter-active-line "+r.element.className,this.$cursorCell=r;break}}},this.scrollLines=function(e){var t=this.config;this.config=e,this.$updateCursorRow();if(this.$lines.pageChanged(t,e))return this.update(e);this.$lines.moveContainer(e);var n=Math.min(e.lastRow+e.gutterOffset,this.session.getLength()-1),r=this.oldLastRow;this.oldLastRow=n;if(!t||r0;i--)this.$lines.shift();if(r>n)for(var i=this.session.getFoldedRowCount(n+1,r);i>0;i--)this.$lines.pop();e.firstRowr&&this.$lines.push(this.$renderLines(e,r+1,n)),this.updateLineHighlight(),this._signal("afterRender"),this.$updateGutterWidth(e)},this.$renderLines=function(e,t,n){var r=[],i=t,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>n)break;var u=this.$lines.createCell(i,e,this.session,f);this.$renderCell(u,e,s,i),r.push(u),i++}return r},this.$renderCell=function(e,t,n,i){var s=e.element,o=this.session,u=s.childNodes[0],a=s.childNodes[1],f=o.$firstLineNumber,l=o.$breakpoints,c=o.$decorations,h=o.gutterRenderer||this.$renderer,p=this.$showFoldWidgets&&o.foldWidgets,d=n?n.start.row:Number.MAX_VALUE,v="ace_gutter-cell ";this.$highlightGutterLine&&(i==this.$cursorRow||n&&i=d&&this.$cursorRow<=n.end.row)&&(v+="ace_gutter-active-line ",this.$cursorCell!=e&&(this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ","")),this.$cursorCell=e)),l[i]&&(v+=l[i]),c[i]&&(v+=c[i]),this.$annotations[i]&&(v+=this.$annotations[i].className),s.className!=v&&(s.className=v);if(p){var m=p[i];m==null&&(m=p[i]=o.getFoldWidget(i))}if(m){var v="ace_fold-widget ace_"+m;m=="start"&&i==d&&in.right-t.right)return"foldWidgets"}}).call(a.prototype),t.Gutter=a}),ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.elt=function(e,t){var n=this.i!=-1&&this.element.childNodes[this.i];n?this.i++:(n=document.createElement("div"),this.element.appendChild(n),this.i=-1),n.style.cssText=t,n.className=e},this.update=function(e){if(!e)return;this.config=e,this.i=0;var t;for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start"+" ace_br15",e)}if(this.i!=-1)while(this.ip,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"";if(this.session.$bidiHandler.isBidiRow(t.start.row)){var f=t.clone();f.end.row=f.start.row,f.end.column=this.session.getLine(f.start.row).length,this.drawBidiSingleLineMarker(e,f,n+" ace_br1 ace_start",r,null,i)}else this.elt(n+" ace_br1 ace_start","height:"+o+"px;"+"right:0;"+"top:"+u+"px;left:"+a+"px;"+(i||""));if(this.session.$bidiHandler.isBidiRow(t.end.row)){var f=t.clone();f.start.row=f.end.row,f.start.column=0,this.drawBidiSingleLineMarker(e,f,n+" ace_br12",r,null,i)}else{u=this.$getTop(t.end.row,r);var l=t.end.column*r.characterWidth;this.elt(n+" ace_br12","height:"+o+"px;"+"width:"+l+"px;"+"top:"+u+"px;"+"left:"+s+"px;"+(i||""))}o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var c=(t.start.column?1:0)|(t.end.column?0:8);this.elt(n+(c?" ace_br"+c:""),"height:"+o+"px;"+"right:0;"+"top:"+u+"px;"+"left:"+s+"px;"+(i||""))},this.drawSingleLineMarker=function(e,t,n,r,i,s){if(this.session.$bidiHandler.isBidiRow(t.start.row))return this.drawBidiSingleLineMarker(e,t,n,r,i,s);var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;this.elt(n,"height:"+o+"px;"+"width:"+u+"px;"+"top:"+a+"px;"+"left:"+f+"px;"+(s||""))},this.drawBidiSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=this.$getTop(t.start.row,r),a=this.$padding,f=this.session.$bidiHandler.getSelections(t.start.column,t.end.column);f.forEach(function(e){this.elt(n,"height:"+o+"px;"+"width:"+e.width+(i||0)+"px;"+"top:"+u+"px;"+"left:"+(a+e.left)+"px;"+(s||""))},this)},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),this.elt(n,"height:"+o+"px;"+"top:"+s+"px;"+"left:0;right:0;"+(i||""))},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;this.elt(n,"height:"+o+"px;"+"top:"+s+"px;"+"left:0;right:0;"+(i||""))}}).call(s.prototype),t.Marker=s}),ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/layer/lines","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("./lines").Lines,u=e("../lib/event_emitter").EventEmitter,a=function(e){this.dom=i,this.element=this.dom.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this),this.$lines=new o(this.element)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2014",this.SPACE_CHAR="\u00b7",this.$padding=0,this.MAX_LINE_LENGTH=1e4,this.$updateEolChar=function(){var e=this.session.doc,t=e.getNewLineCharacter()=="\n"&&e.getNewLineMode()!="windows",n=t?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=n)return this.EOL_CHAR=n,!0},this.setPadding=function(e){this.$padding=e,this.element.style.margin="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;nl&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),l=a?a.start.row:Infinity);if(u>i)break;var c=s[o++];if(c){this.dom.removeChildren(c),this.$renderLine(c,u,u==l?a:!1);var h=e.lineHeight*this.session.getRowLength(u)+"px";c.style.height!=h&&(f=!0,c.style.height=h)}u++}if(f)while(o0;i--)this.$lines.shift();if(t.lastRow>e.lastRow)for(var i=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);i>0;i--)this.$lines.pop();e.firstRowt.lastRow&&this.$lines.push(this.$renderLinesFragment(e,t.lastRow+1,e.lastRow))},this.$renderLinesFragment=function(e,t,n){var r=[],s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=this.$lines.createCell(s,e,this.session),f=a.element;this.dom.removeChildren(f),i.setStyle(f.style,"height",this.$lines.computeLineHeight(s,e,this.session)+"px"),i.setStyle(f.style,"top",this.$lines.computeLineTop(s,e,this.session)+"px"),this.$renderLine(f,s,s==u?o:!1),this.$useLineGroups()?f.className="ace_line_group":f.className="ace_line",r.push(a),s++}return r},this.update=function(e){this.$lines.moveContainer(e),this.config=e;var t=e.firstRow,n=e.lastRow,r=this.$lines;while(r.getLength())r.pop();r.push(this.$renderLinesFragment(e,t,n))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/(\t)|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\uFEFF\uFFF9-\uFFFC]+)|(\u3000)|([\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3001-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF])/g,u=this.dom.createFragment(this.element),a,f=0;while(a=o.exec(r)){var l=a[1],c=a[2],h=a[3],p=a[4],d=a[5];if(!i.showInvisibles&&c)continue;var v=f!=a.index?r.slice(f,a.index):"";f=a.index+a[0].length,v&&u.appendChild(this.dom.createTextNode(v,this.element));if(l){var m=i.session.getScreenTabSize(t+a.index);u.appendChild(i.$tabStrings[m].cloneNode(!0)),t+=m-1}else if(c)if(i.showInvisibles){var g=this.dom.createElement("span");g.className="ace_invisible ace_invisible_space",g.textContent=s.stringRepeat(i.SPACE_CHAR,c.length),u.appendChild(g)}else u.appendChild(this.com.createTextNode(c,this.element));else if(h){var g=this.dom.createElement("span");g.className="ace_invisible ace_invisible_space ace_invalid",g.textContent=s.stringRepeat(i.SPACE_CHAR,h.length),u.appendChild(g)}else if(p){var y=i.showInvisibles?i.SPACE_CHAR:"";t+=1;var g=this.dom.createElement("span");g.style.width=i.config.characterWidth*2+"px",g.className=i.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",g.textContent=i.showInvisibles?i.SPACE_CHAR:"",u.appendChild(g)}else if(d){t+=1;var g=this.dom.createElement("span");g.style.width=i.config.characterWidth*2+"px",g.className="ace_cjk",g.textContent=d,u.appendChild(g)}}u.appendChild(this.dom.createTextNode(f?r.slice(f):r,this.element));if(!this.$textToken[n.type]){var b="ace_"+n.type.replace(/\./g," ace_"),g=this.dom.createElement("span");n.type=="fold"&&(g.style.width=n.value.length*this.config.characterWidth+"px"),g.className=b,g.appendChild(u),e.appendChild(g)}else e.appendChild(u);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);if(r<=0||r>=n)return t;if(t[0]==" "){r-=r%this.tabSize;var i=r/this.tabSize;for(var s=0;s=o)u=this.$renderToken(a,u,l,c.substring(0,o-r)),c=c.substring(o-r),r=o,a=this.$createLineElement(),e.appendChild(a),a.appendChild(this.dom.createTextNode(s.stringRepeat("\u00a0",n.indent),this.element)),i++,u=0,o=n[i]||Number.MAX_VALUE;c.length!=0&&(r+=c.length,u=this.$renderToken(a,u,l,c))}}n[n.length-1]>this.MAX_LINE_LENGTH&&this.$renderOverflowMessage(a,u,null,"",!0)},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;sthis.MAX_LINE_LENGTH)return this.$renderOverflowMessage(e,n,r,i);n=this.$renderToken(e,n,r,i)}},this.$renderOverflowMessage=function(e,t,n,r,i){n&&this.$renderToken(e,t,n,r.slice(0,this.MAX_LINE_LENGTH-t));var s=this.dom.createElement("span");s.className="ace_inline_button ace_keyword ace_toggle_wrap",s.textContent=i?"":"",e.appendChild(s)},this.$renderLine=function(e,t,n){!n&&n!=0&&(n=this.session.getFoldLine(t));if(n)var r=this.$getFoldLineTokens(t,n);else var r=this.session.getTokens(t);var i=e;if(r.length){var s=this.session.getRowSplitData(t);if(s&&s.length){this.$renderWrappedLine(e,r,s);var i=e.lastChild}else{var i=e;this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i)),this.$renderSimpleLine(i,r)}}else this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i));if(this.showInvisibles&&i){n&&(t=n.end.row);var o=this.dom.createElement("span");o.className="ace_invisible ace_invisible_eol",o.textContent=t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,i.appendChild(o)}},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.lengthn-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(sn?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){}}).call(a.prototype),t.Text=a}),ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=this.$updateOpacity.bind(this)};(function(){this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)r.setStyle(t[n].style,"opacity",e?"":"0")},this.$startCssAnimation=function(){var e=this.cursors;for(var t=e.length;t--;)e[t].style.animationDuration=this.blinkInterval+"ms";setTimeout(function(){r.addCssClass(this.element,"ace_animate-blinking")}.bind(this))},this.$stopCssAnimation=function(){r.removeCssClass(this.element,"ace_animate-blinking")},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.$stopCssAnimation(),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible){this.$stopCssAnimation();return}this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));if(r.HAS_CSS_ANIMATION)this.$startCssAnimation();else{var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()}},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+(this.session.$bidiHandler.isBidiRow(n.row,e.row)?this.session.$bidiHandler.getPosLeft(n.column):n.column*this.config.characterWidth),i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.isCursorInView=function(e,t){return e.top>=0&&e.tope.height+e.offset||o.top<0)&&n>1)continue;var u=this.cursors[i++]||this.addCursor(),a=u.style;this.drawCursor?this.drawCursor(u,o,e,t[n],this.session):this.isCursorInView(o,e)?(r.setStyle(a,"display","block"),r.translate(u,o.left,o.top),r.setStyle(a,"width",Math.round(e.characterWidth)+"px"),r.setStyle(a,"height",e.lineHeight+"px")):r.setStyle(a,"display","none")}while(this.cursors.length>i)this.removeCursor();var f=this.session.getOverwrite();this.$setOverwrite(f),this.$pixelPos=o,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(i.prototype),t.Cursor=i}),ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=32768,a=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.inner.textContent="\u00a0",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px",this.$minWidth=0};r.inherits(f,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return Math.max(this.isVisible?this.width:0,this.$minWidth||0)},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(l,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),ace.define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.$recursionLimit=2,this.window=t||window;var n=this;this._flush=function(e){n.pending=!1;var t=n.changes;t&&(r.blockIdle(100),n.changes=0,n.onRender(t));if(n.changes){if(n.$recursionLimit--<0)return;n.schedule()}else n.$recursionLimit=2}};(function(){this.schedule=function(e){this.changes=this.changes|e,this.changes&&!this.pending&&(r.nextFrame(this._flush),this.pending=!0)},this.clear=function(e){var t=this.changes;return this.changes=0,t}}).call(i.prototype),t.RenderLoop=i}),ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/event"),u=e("../lib/useragent"),a=e("../lib/event_emitter").EventEmitter,f=256,l=typeof ResizeObserver=="function",c=200,h=t.FontMetrics=function(e){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),this.$measureNode.innerHTML=s.stringRepeat("X",f),this.$characterSize={width:0,height:0},l?this.$addObserver():this.checkForSizeChanges()};(function(){r.implement(this,a),this.$characterSize={width:0,height:0},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",u.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(e){e===undefined&&(e=this.$measureSizes());if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$addObserver=function(){var e=this;this.$observer=new window.ResizeObserver(function(t){var n=t[0].contentRect;e.checkForSizeChanges({height:n.height,width:n.width/f})}),this.$observer.observe(this.$measureNode)},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer||this.$observer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=o.onIdle(function t(){e.checkForSizeChanges(),o.onIdle(t,500)},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(e){var t={height:(e||this.$measureNode).clientHeight,width:(e||this.$measureNode).clientWidth/f};return t.width===0||t.height===0?null:t},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,f);var t=this.$main.getBoundingClientRect();return t.width/f},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$observer&&this.$observer.disconnect(),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)},this.$getZoom=function e(t){return t?(window.getComputedStyle(t).zoom||1)*e(t.parentElement):1},this.$initTransformMeasureNodes=function(){var e=function(e,t){return["div",{style:"position: absolute;top:"+e+"px;left:"+t+"px;"}]};this.els=i.buildDom([e(0,0),e(c,0),e(0,c),e(c,c)],this.el)},this.transformCoordinates=function(e,t){function r(e,t,n){var r=e[1]*t[0]-e[0]*t[1];return[(-t[1]*n[0]+t[0]*n[1])/r,(+e[1]*n[0]-e[0]*n[1])/r]}function i(e,t){return[e[0]-t[0],e[1]-t[1]]}function s(e,t){return[e[0]+t[0],e[1]+t[1]]}function o(e,t){return[e*t[0],e*t[1]]}function u(e){var t=e.getBoundingClientRect();return[t.left,t.top]}if(e){var n=this.$getZoom(this.el);e=o(1/n,e)}this.els||this.$initTransformMeasureNodes();var a=u(this.els[0]),f=u(this.els[1]),l=u(this.els[2]),h=u(this.els[3]),p=r(i(h,f),i(h,l),i(s(f,l),s(h,a))),d=o(1+p[0],i(f,a)),v=o(1+p[1],i(l,a));if(t){var m=t,g=p[0]*m[0]/c+p[1]*m[1]/c+1,y=s(o(m[0],d),o(m[1],v));return s(o(1/g/c,y),a)}var b=i(e,a),w=r(i(d,o(p[0],b)),i(v,o(p[1],b)),b);return o(c,w)}}).call(h.prototype)}),ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./layer/gutter").Gutter,u=e("./layer/marker").Marker,a=e("./layer/text").Text,f=e("./layer/cursor").Cursor,l=e("./scrollbar").HScrollBar,c=e("./scrollbar").VScrollBar,h=e("./renderloop").RenderLoop,p=e("./layer/font_metrics").FontMetrics,d=e("./lib/event_emitter").EventEmitter,v='.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;box-sizing: border-box;min-width: 100%;contain: style size layout;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;contain: style size layout;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {position: absolute;top: 0;left: 0;right: 0;padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {contain: strict;position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;contain: strict;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: transparent;color: inherit;z-index: 1000;opacity: 1;}.ace_composition_placeholder { color: transparent }.ace_composition_marker { border-bottom: 1px solid;position: absolute;border-radius: 0;margin-top: 1px;}[ace_nocontext=true] {transform: none!important;filter: none!important;perspective: none!important;clip-path: none!important;mask : none!important;contain: none!important;perspective: none!important;mix-blend-mode: initial!important;z-index: auto;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;height: 1000000px;contain: style size layout;}.ace_text-layer {font: inherit !important;position: absolute;height: 1000000px;width: 1000000px;contain: style size layout;}.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {contain: style size layout;position: absolute;top: 0;left: 0;right: 0;}.ace_hidpi .ace_text-layer,.ace_hidpi .ace_gutter-layer,.ace_hidpi .ace_content,.ace_hidpi .ace_gutter {contain: strict;will-change: transform;}.ace_hidpi .ace_text-layer > .ace_line, .ace_hidpi .ace_text-layer > .ace_line_group {contain: strict;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {transition: opacity 0.18s;}.ace_animate-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: step-end;animation-name: blink-ace-animate;animation-iteration-count: infinite;}.ace_animate-blinking.ace_smooth-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: ease-in-out;animation-name: blink-ace-animate-smooth;}@keyframes blink-ace-animate {from, to { opacity: 1; }60% { opacity: 0; }}@keyframes blink-ace-animate-smooth {from, to { opacity: 1; }45% { opacity: 1; }60% { opacity: 0; }85% { opacity: 0; }}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;box-sizing: border-box;}.ace_line .ace_fold {box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_inline_button {border: 1px solid lightgray;display: inline-block;margin: -1px 8px;padding: 0 5px;pointer-events: auto;cursor: pointer;}.ace_inline_button:hover {border-color: gray;background: rgba(200,200,200,0.2);display: inline-block;pointer-events: auto;}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}',m=e("./lib/useragent"),g=m.isIE;i.importCssString(v,"ace_editor.css");var y=function(e,t){var n=this;this.container=e||i.createElement("div"),i.addCssClass(this.container,"ace_editor"),i.HI_DPI&&i.addCssClass(this.container,"ace_hidpi"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.$gutter.setAttribute("aria-hidden",!0),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new o(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new u(this.content);var r=this.$textLayer=new a(this.content);this.canvas=r.element,this.$markerFront=new u(this.content),this.$cursorLayer=new f(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new c(this.container,this),this.scrollBarH=new l(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new p(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.margin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$keepTextAreaAtCursor=!m.isIOS,this.$loop=new h(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._signal("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,d),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarH.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRowthis.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar(),this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR)},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var s=0,o=this.$size,u={width:o.width,height:o.height,scrollerHeight:o.scrollerHeight,scrollerWidth:o.scrollerWidth};r&&(e||o.height!=r)&&(o.height=r,s|=this.CHANGE_SIZE,o.scrollerHeight=o.height,this.$horizScroll&&(o.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",s|=this.CHANGE_SCROLL);if(n&&(e||o.width!=n)){s|=this.CHANGE_SIZE,o.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,i.setStyle(this.scrollBarH.element.style,"left",t+"px"),i.setStyle(this.scroller.style,"left",t+this.margin.left+"px"),o.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()-this.margin.h),i.setStyle(this.$gutter.style,"left",this.margin.left+"px");var a=this.scrollBarV.getWidth()+"px";i.setStyle(this.scrollBarH.element.style,"right",a),i.setStyle(this.scroller.style,"right",a),i.setStyle(this.scroller.style,"bottom",this.scrollBarH.getHeight());if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)s|=this.CHANGE_FULL}return o.$dirty=!n||!r,s&&this._signal("resize",u),s},this.onGutterResize=function(e){var t=this.$showGutter?e:0;t!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,t,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):this.$computeLayerConfig()},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e),this.session.$bidiHandler.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=Math.round(this.characterWidth*this.$printMarginColumn+this.$padding)+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(this.$isMousePressed)return;var e=this.textarea.style,t=this.$composition;if(!this.$keepTextAreaAtCursor&&!t){i.translate(this.textarea,-100,0);return}var n=this.$cursorLayer.$pixelPos;if(!n)return;t&&t.markerRange&&(n=this.$cursorLayer.getPixelPosition(t.markerRange.start,!0));var r=this.layerConfig,s=n.top,o=n.left;s-=r.offset;var u=t&&t.useTextareaForIME?this.lineHeight:g?0:1;if(s<0||s>r.height-u){i.translate(this.textarea,0,0);return}var a=1;if(!t)s+=this.lineHeight;else if(t.useTextareaForIME){var f=this.textarea.value;a=this.characterWidth*this.session.$getStringScreenWidth(f)[0],u+=2}else s+=this.lineHeight+2;o-=this.scrollLeft,o>this.$size.scrollerWidth-a&&(o=this.$size.scrollerWidth-a),o+=this.gutterWidth+this.margin.left,i.setStyle(e,"height",u+"px"),i.setStyle(e,"width",a+"px"),i.translate(this.textarea,Math.min(o,this.$size.scrollerWidth-a),Math.min(s,this.$size.height-u))},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.setMargin=function(e,t,n,r){var i=this.margin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,this.$updateCachedSize(!0,this.gutterWidth,this.$size.width,this.$size.height),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender"),this.session&&this.session.$bidiHandler&&this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig()|this.$loop.clear();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig()|this.$loop.clear())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),i.translate(this.content,-this.scrollLeft,-n.offset);var s=n.width+2*this.$padding+"px",o=n.minHeight+"px";i.setStyle(this.content.style,"width",s),i.setStyle(this.content.style,"height",o)}e&this.CHANGE_H_SCROLL&&(i.translate(this.content,-this.scrollLeft,-n.offset),this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal("afterRender");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&(e&this.CHANGE_GUTTER||e&this.CHANGE_LINES?this.$gutterLayer.update(n):this.$gutterLayer.scrollLines(n)),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal("afterRender");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER?this.$showGutter&&this.$gutterLayer.update(n):e&this.CHANGE_CURSOR&&this.$highlightGutterLine&&this.$gutterLayer.updateLineHighlight(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=n<=2*this.lineHeight,i=!r&&e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||i!=this.$vScroll){i!=this.$vScroll&&(this.$vScroll=i,this.scrollBarV.setVisible(i));var s=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,s,n),this.desiredHeight=n,this._signal("autosize")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=t.scrollerHeight+this.lineHeight,l=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=l;var c=this.scrollMargin;this.session.setScrollTop(Math.max(-c.top,Math.min(this.scrollTop,i-t.scrollerHeight+c.bottom))),this.session.setScrollLeft(Math.max(-c.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+c.right)));var h=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+l<0||this.scrollTop>c.top),p=a!==h;p&&(this.$vScroll=h,this.scrollBarV.setVisible(h));var d=this.scrollTop%this.lineHeight,v=Math.ceil(f/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-d)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),f=t.scrollerHeight+e.getRowLength(g)*w+b,d=this.scrollTop-y*w;var S=0;if(this.layerConfig.width!=s||u)S=this.CHANGE_H_SCROLL;if(u||p)S|=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),p&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:f,maxHeight:i,offset:d,gutterOffset:w?Math.max(0,Math.ceil((d+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},this.session.$bidiHandler&&this.session.$bidiHandler.setContentWidth(s-this.$padding),S},this.$updateLines=function(){if(!this.$changedLines)return;var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(tthis.$textLayer.MAX_LINE_LENGTH&&(e=this.$textLayer.MAX_LINE_LENGTH+30),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-ui?(i=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),u=this.$blockCursor?Math.floor(s):Math.round(s);return{row:o,column:u,side:s-u>0?1:-1,offsetX:i}},this.screenToTextCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=this.$blockCursor?Math.floor(s):Math.round(s),u=Math.floor((t+this.scrollTop-n.top)/this.lineHeight);return this.session.screenToDocumentPosition(u,Math.max(o,0),i)},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+(this.session.$bidiHandler.isBidiRow(r.row,e)?this.session.$bidiHandler.getPosLeft(r.column):Math.round(r.column*this.characterWidth)),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition=e,e.cssText||(e.cssText=this.textarea.style.cssText),e.useTextareaForIME=this.$useTextareaForIME,this.$useTextareaForIME?(i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor(),this.$cursorLayer.element.style.display="none"):e.markerId=this.session.addMarker(e.markerRange,"ace_composition_marker","text")},this.setCompositionText=function(e){var t=this.session.selection.cursor;this.addToken(e,"composition_placeholder",t.row,t.column),this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;this.$composition.markerId&&this.session.removeMarker(this.$composition.markerId),i.removeCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText=this.$composition.cssText,this.$composition=null,this.$cursorLayer.element.style.display=""},this.addToken=function(e,t,n,r){var i=this.session;i.bgTokenizer.lines[n]=null;var s={type:t,value:e},o=i.getTokens(n);if(r==null)o.push(s);else{var u=0;for(var a=0;a50&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})}}).call(f.prototype);var l=function(e,t,n){var r=null,i=!1,u=Object.create(s),a=[],l=new f({messageBuffer:a,terminate:function(){},postMessage:function(e){a.push(e);if(!r)return;i?setTimeout(c):c()}});l.setEmitSync=function(e){i=e};var c=function(){var e=a.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};return u.postMessage=function(e){l.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.length)c()}),l};t.UIWorkerClient=l,t.WorkerClient=f,t.createWorker=a}),ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action==="insert")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action==="remove")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length&&this.$onRemoveRange(e)},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.cursor),s=this.session.documentToScreenPosition(this.anchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column0)g--;if(g>0){var y=0;while(r[y].isEmpty())y++}for(var b=g;b>=y;b--)r[b].isEmpty()&&r.splice(b,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges(),u.ranges[0]&&u.fromOrientedRange(u.ranges[0]);var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),io?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),st[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++tf){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.$id="ace/theme/textmate";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./range").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action=="add";for(var u=i+1;u0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+"px";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+"px"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(o.prototype),t.LineWidgets=o}),ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("../line_widgets").LineWidgets,i=e("../lib/dom"),s=e("../range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type=="errorMarker"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div"),type:"errorMarker"},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("
"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/range","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./range").Range,o=e("./editor").Editor,u=e("./edit_session").EditSession,a=e("./undomanager").UndoManager,f=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,typeof define=="function"&&(t.define=define),t.edit=function(e,n){if(typeof e=="string"){var s=e;e=document.getElementById(s);if(!e)throw new Error("ace.edit can't find div #"+s)}if(e&&e.env&&e.env.editor instanceof o)return e.env.editor;var u="";if(e&&/input|textarea/i.test(e.tagName)){var a=e;u=a.value,e=r.createElement("pre"),a.parentNode.replaceChild(e,a)}else e&&(u=e.textContent,e.innerHTML="");var l=t.createEditSession(u),c=new o(new f(e),l,n),h={document:l,editor:c,onResize:c.resize.bind(c,null)};return a&&(h.textarea=a),i.addListener(window,"resize",h.onResize),c.on("destroy",function(){i.removeListener(window,"resize",h.onResize),h.editor.container.env=null}),c.container.env=c.env=h,c},t.createEditSession=function(e,t){var n=new u(e,t);return n.setUndoManager(new a),n},t.Range=s,t.Editor=o,t.EditSession=u,t.UndoManager=a,t.VirtualRenderer=f,t.version=t.config.version}); (function() { + ace.require(["ace/ace"], function(a) { + if (a) { + a.config.init(true); + a.define = ace.define; + } + if (!window.ace) + window.ace = a; + for (var key in a) if (a.hasOwnProperty(key)) + window.ace[key] = a[key]; + window.ace["default"] = window.ace; + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = window.ace; + } + }); + })(); + \ No newline at end of file diff --git a/public/static/libs/ace/mode-sh.js b/public/static/libs/ace/mode-sh.js new file mode 100755 index 0000000..1debff2 --- /dev/null +++ b/public/static/libs/ace/mode-sh.js @@ -0,0 +1 @@ +ace.define("ace/mode/sh",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/sh_highlight_rules","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./sh_highlight_rules").ShHighlightRules,u=e("../range").Range,a=function(){this.$tokenizer=new s((new o).getRules())};r.inherits(a,i),function(){this.toggleCommentLines=function(e,t,n,r){var i=!0,s=/^(\s*)#/;for(var o=n;o<=r;o++)if(!s.test(t.getLine(o))){i=!1;break}if(i){var a=new u(0,0,0,0);for(var o=n;o<=r;o++){var f=t.getLine(o),l=f.match(s);a.start.row=o,a.end.row=o,a.end.column=l[0].length,t.replace(a,l[1])}}else t.indentRows(n,r,"#")},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.$tokenizer.getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.$tokenizer.getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))}}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set",o=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",u=function(){var e=this.createKeywordMapper({keyword:s,"support.function.builtin":o,"invalid.deprecated":"debugger"},"identifier"),t="(?:(?:[1-9]\\d*)|(?:0))",n="(?:\\.\\d+)",r="(?:\\d+)",i="(?:(?:"+r+"?"+n+")|(?:"+r+"\\.))",u="(?:(?:"+i+"|"+r+")"+")",a="(?:"+u+"|"+i+")",f="(?:&"+r+")",l="[a-zA-Z][a-zA-Z0-9_]*",c="(?:(?:\\$"+l+")|(?:"+l+"=))",h="(?:\\$(?:SHLVL|\\$|\\!|\\?))",p="(?:"+l+"\\s*\\(\\))";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:'"(?:[^\\\\]|\\\\.)*?"'},{token:"variable.language",regex:h},{token:"variable",regex:c},{token:"support.function",regex:p},{token:"support.function",regex:f},{token:"string",regex:"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:t+"\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}]}};r.inherits(u,i),t.ShHighlightRules=u}) \ No newline at end of file diff --git a/public/static/libs/ace/theme-github.js b/public/static/libs/ace/theme-github.js new file mode 100755 index 0000000..e5dd93d --- /dev/null +++ b/public/static/libs/ace/theme-github.js @@ -0,0 +1,5 @@ +ace.define("ace/theme/github", ["require", "exports", "module", "ace/lib/dom"], function (e, t, n) { + t.isDark = !1, t.cssClass = "ace-github", t.cssText = '/* CSS style content from github\'s default pygments highlighter template.Cursor and selection styles from textmate.css. */.ace-github .ace_gutter {background: #e8e8e8;color: #AAA;}.ace-github .ace_scroller {background: #fff;}.ace-github .ace_keyword {font-weight: bold;}.ace-github .ace_string {color: #D14;}.ace-github .ace_variable.ace_class {color: teal;}.ace-github .ace_constant.ace_numeric {color: #099;}.ace-github .ace_constant.ace_buildin {color: #0086B3;}.ace-github .ace_support.ace_function {color: #0086B3;}.ace-github .ace_comment {color: #998;font-style: italic;}.ace-github .ace_variable.ace_language {color: #0086B3;}.ace-github .ace_paren {font-weight: bold;}.ace-github .ace_boolean {font-weight: bold;}.ace-github .ace_string.ace_regexp {color: #009926;font-weight: normal;}.ace-github .ace_variable.ace_instance {color: teal;}.ace-github .ace_constant.ace_language {font-weight: bold;}.ace-github .ace_text-layer {}.ace-github .ace_cursor {border-left: 2px solid black;}.ace-github .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid black;}.ace-github .ace_marker-layer .ace_active-line {background: rgb(255, 255, 204);}.ace-github .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-github.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}/* bold keywords cause cursor issues for some fonts *//* this disables bold style for editor and keeps for static highlighter */.ace-github.ace_nobold .ace_line > span {font-weight: normal !important;}.ace-github .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-github .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-github .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-github .ace_gutter-active-line {background-color : rgba(0, 0, 0, 0.07);}.ace-github .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-github .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-github .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}'; + var r = e("../lib/dom"); + r.importCssString(t.cssText, t.cssClass) +}) diff --git a/public/static/libs/ace/theme-one-dark.js b/public/static/libs/ace/theme-one-dark.js new file mode 100644 index 0000000..eb2ec1d --- /dev/null +++ b/public/static/libs/ace/theme-one-dark.js @@ -0,0 +1,5 @@ +ace.define("ace/theme/one-dark", ["require", "exports", "module", "ace/lib/dom"], function (e, t, n) { + t.isDark = !1, t.cssClass = "ace-one-dark", t.cssText = '/* CSS style content from one-dark\'s default pygments highlighter template.Cursor and selection styles from textmate.css. */.ace-one-dark .ace_gutter{background:#282c34;color:#6a6f7a}.ace-one-dark .ace_print-margin{width:1px;background:#e8e8e8}.ace-one-dark{background-color:#282c34;color:#abb2bf}.ace-one-dark .ace_cursor{color:#528bff}.ace-one-dark .ace_marker-layer .ace_selection{background:#3d4350}.ace-one-dark.ace_multiselect .ace_selection.ace_start{box-shadow:0 0 3px 0 #282c34;border-radius:2px}.ace-one-dark .ace_marker-layer .ace_step{background:#c6dbae}.ace-one-dark .ace_marker-layer .ace_bracket{margin:-1px 0 0 -1px;border:1px solid #747369}.ace-one-dark .ace_marker-layer .ace_active-line{background:rgba(76,87,103,.19)}.ace-one-dark .ace_gutter-active-line{background-color:rgba(76,87,103,.19)}.ace-one-dark .ace_marker-layer .ace_selected-word{border:1px solid #3d4350}.ace-one-dark .ace_fold{background-color:#61afef;border-color:#abb2bf}.ace-one-dark .ace_keyword{color:#c678dd}.ace-one-dark .ace_keyword.ace_operator{color:#c678dd}.ace-one-dark .ace_keyword.ace_other.ace_unit{color:#d19a66}.ace-one-dark .ace_constant.ace_language{color:#d19a66}.ace-one-dark .ace_constant.ace_numeric{color:#d19a66}.ace-one-dark .ace_constant.ace_character{color:#56b6c2}.ace-one-dark .ace_constant.ace_other{color:#56b6c2}.ace-one-dark .ace_support.ace_function{color:#61afef}.ace-one-dark .ace_support.ace_constant{color:#d19a66}.ace-one-dark .ace_support.ace_class{color:#e5c07b}.ace-one-dark .ace_support.ace_type{color:#e5c07b}.ace-one-dark .ace_storage{color:#c678dd}.ace-one-dark .ace_storage.ace_type{color:#c678dd}.ace-one-dark .ace_invalid{color:#fff;background-color:#f2777a}.ace-one-dark .ace_invalid.ace_deprecated{color:#272b33;background-color:#d27b53}.ace-one-dark .ace_string{color:#98c379}.ace-one-dark .ace_string.ace_regexp{color:#e06c75}.ace-one-dark .ace_comment{font-style:italic;color:#5c6370}.ace-one-dark .ace_variable{color:#e06c75}.ace-one-dark .ace_variable.ace_parameter{color:#d19a66}.ace-one-dark .ace_meta.ace_tag{color:#e06c75}.ace-one-dark .ace_entity.ace_other.ace_attribute-name{color:#e06c75}.ace-one-dark .ace_entity.ace_name.ace_function{color:#61afef}.ace-one-dark .ace_entity.ace_name.ace_tag{color:#e06c75}.ace-one-dark .ace_markup.ace_heading{color:#98c379}.ace-one-dark .ace_indent-guide{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y}'; + var r = e("../lib/dom"); + r.importCssString(t.cssText, t.cssClass) +}) diff --git a/public/vendor/telescope/app-dark.css b/public/vendor/telescope/app-dark.css new file mode 100644 index 0000000..28cd438 --- /dev/null +++ b/public/vendor/telescope/app-dark.css @@ -0,0 +1,8 @@ +@charset "UTF-8";.form-control:-moz-focusring{text-shadow:none!important} + +/*! + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#4b5563;--gray-dark:#1f2937;--primary:#4040c8;--secondary:#4b5563;--success:#059669;--info:#2563eb;--warning:#d97706;--danger:#dc2626;--light:#f3f4f6;--dark:#1f2937;--breakpoint-xs:0;--breakpoint-sm:2px;--breakpoint-md:8px;--breakpoint-lg:9px;--breakpoint-xl:10px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);font-family:sans-serif;line-height:1.15}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{background-color:#111827;color:#f3f4f6;font-family:Figtree,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;margin:0;text-align:left}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;margin-top:0}p{margin-bottom:1rem;margin-top:0}abbr[data-original-title],abbr[title]{border-bottom:0;cursor:help;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:600}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{background-color:transparent;color:#818cf8;text-decoration:none}a:hover{color:#a5b4fc;text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{-ms-overflow-style:scrollbar;margin-bottom:1rem;margin-top:0;overflow:auto}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{caption-side:bottom;color:#9ca3af;padding-bottom:.75rem;padding-top:.75rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{color:inherit;display:block;font-size:1.5rem;line-height:inherit;margin-bottom:.5rem;max-width:100%;padding:0;white-space:normal;width:100%}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:none;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}output{display:inline-block}summary{cursor:pointer;display:list-item}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:500;line-height:1.2;margin-bottom:.5rem}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem}.display-1,.display-2{font-weight:300;line-height:1.2}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-3,.display-4{font-weight:300;line-height:1.2}.display-4{font-size:3.5rem}hr{border:0;border-top:1px solid rgba(0,0,0,.1);margin-bottom:1rem;margin-top:1rem}.small,small{font-size:80%;font-weight:400}.mark,mark{background-color:#fcf8e3;padding:.2em}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{font-size:1.25rem;margin-bottom:1rem}.blockquote-footer{color:#4b5563;display:block;font-size:80%}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{height:auto;max-width:100%}.img-thumbnail{background-color:#111827;border:1px solid #d1d5db;border-radius:.25rem;padding:.25rem}.figure{display:inline-block}.figure-img{line-height:1;margin-bottom:.5rem}.figure-caption{color:#4b5563;font-size:90%}code{word-wrap:break-word;color:#e83e8c;font-size:87.5%}a>code{color:inherit}kbd{background-color:#111827;border-radius:.2rem;color:#fff;font-size:87.5%;padding:.2rem .4rem}kbd kbd{font-size:100%;font-weight:600;padding:0}pre{color:#111827;display:block;font-size:87.5%}pre code{color:inherit;font-size:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media (min-width:2px){.container,.container-sm{max-width:1137px}}@media (min-width:8px){.container,.container-md,.container-sm{max-width:1138px}}@media (min-width:9px){.container,.container-lg,.container-md,.container-sm{max-width:1139px}}@media (min-width:10px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.no-gutters{margin-left:0;margin-right:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-left:0;padding-right:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{padding-left:15px;padding-right:15px;position:relative;width:100%}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;max-width:100%;width:auto}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width:2px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width:8px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;max-width:100%;width:auto}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width:9px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;max-width:100%;width:auto}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width:10px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;max-width:100%;width:auto}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.table{color:#f3f4f6;margin-bottom:1rem;width:100%}.table td,.table th{border-top:1px solid #374151;padding:.75rem;vertical-align:top}.table thead th{border-bottom:2px solid #374151;vertical-align:bottom}.table tbody+tbody{border-top:2px solid #374151}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #374151}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:#374151;color:#f3f4f6}.table-primary,.table-primary>td,.table-primary>th{background-color:#cacaf0}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#9c9ce2}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#b6b6ea}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#cdcfd3}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#a1a7ae}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#bfc2c7}.table-success,.table-success>td,.table-success>th{background-color:#b9e2d5}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#7dc8b1}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a7dbca}.table-info,.table-info>td,.table-info>th{background-color:#c2d3f9}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#8eaef5}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abc2f7}.table-warning,.table-warning>td,.table-warning>th{background-color:#f4d9b9}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ebb87e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#f1cda3}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c2c2}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed8e8e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1acac}.table-light,.table-light>td,.table-light>th{background-color:#fcfcfc}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#f9f9fa}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#efefef}.table-dark,.table-dark>td,.table-dark>th{background-color:#c0c3c7}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#8b9097}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b3b6bb}.table-active,.table-active>td,.table-active>th{background-color:#374151}.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:#2d3542}.table .thead-dark th{background-color:#1f2937;border-color:#2d3b4f;color:#fff}.table .thead-light th{background-color:#e5e7eb;border-color:#374151;color:#374151}.table-dark{background-color:#1f2937;color:#fff}.table-dark td,.table-dark th,.table-dark thead th{border-color:#2d3b4f}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{background-color:hsla(0,0%,100%,.075);color:#fff}@media (max-width:1.98px){.table-responsive-sm{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:7.98px){.table-responsive-md{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-md>.table-bordered{border:0}}@media (max-width:8.98px){.table-responsive-lg{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:9.98px){.table-responsive-xl{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive>.table-bordered{border:0}.form-control{background-clip:padding-box;background-color:#1f2937;border:1px solid #4b5563;border-radius:.25rem;color:#e5e7eb;display:block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #e5e7eb}.form-control:focus{background-color:#1f2937;border-color:#a3a3e5;box-shadow:0 0 0 .2rem rgba(64,64,200,.25);color:#e5e7eb;outline:0}.form-control::-moz-placeholder{color:#4b5563;opacity:1}.form-control:-ms-input-placeholder{color:#4b5563;opacity:1}.form-control::placeholder{color:#4b5563;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e5e7eb;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{background-color:#1f2937;color:#e5e7eb}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + 1px);padding-top:calc(.375rem + 1px)}.col-form-label-lg{font-size:1.25rem;line-height:1.5;padding-bottom:calc(.5rem + 1px);padding-top:calc(.5rem + 1px)}.col-form-label-sm{font-size:.875rem;line-height:1.5;padding-bottom:calc(.25rem + 1px);padding-top:calc(.25rem + 1px)}.form-control-plaintext{background-color:transparent;border:solid transparent;border-width:1px 0;color:#f3f4f6;display:block;font-size:1rem;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.form-control-sm{border-radius:.2rem;font-size:.875rem;height:calc(1.5em + .5rem + 2px);line-height:1.5;padding:.25rem .5rem}.form-control-lg{border-radius:6px;font-size:1.25rem;height:calc(1.5em + 1rem + 2px);line-height:1.5;padding:.5rem 1rem}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-left:-5px;margin-right:-5px}.form-row>.col,.form-row>[class*=col-]{padding-left:5px;padding-right:5px}.form-check{display:block;padding-left:1.25rem;position:relative}.form-check-input{margin-left:-1.25rem;margin-top:.3rem;position:absolute}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#9ca3af}.form-check-label{margin-bottom:0}.form-check-inline{align-items:center;display:inline-flex;margin-right:.75rem;padding-left:0}.form-check-inline .form-check-input{margin-left:0;margin-right:.3125rem;margin-top:0;position:static}.valid-feedback{color:#059669;display:none;font-size:80%;margin-top:.25rem;width:100%}.valid-tooltip{background-color:rgba(5,150,105,.9);border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23059669' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#059669;padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#059669;box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.custom-select.is-valid,.was-validated .custom-select:valid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%231f2937' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#1f2937 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23059669' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#059669;padding-right:calc(.75em + 2.3125rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#059669;box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#059669}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#059669}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#059669}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{background-color:#07c78c;border-color:#07c78c}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before{border-color:#059669}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#059669}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#059669;box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.invalid-feedback{color:#dc2626;display:none;font-size:80%;margin-top:.25rem;width:100%}.invalid-tooltip{background-color:rgba(220,38,38,.9);border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc2626'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc2626' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc2626;padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc2626;box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%231f2937' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#1f2937 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc2626'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc2626' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#dc2626;padding-right:calc(.75em + 2.3125rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc2626;box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc2626}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc2626}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc2626}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{background-color:#e35252;border-color:#e35252}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before{border-color:#dc2626}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc2626}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc2626;box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.form-inline{align-items:center;display:flex;flex-flow:row wrap}.form-inline .form-check{width:100%}@media (min-width:2px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{align-items:center;display:flex;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .form-control{display:inline-block;vertical-align:middle;width:auto}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{align-items:center;display:flex;justify-content:center;padding-left:0;width:auto}.form-inline .form-check-input{flex-shrink:0;margin-left:0;margin-right:.25rem;margin-top:0;position:relative}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;color:#f3f4f6;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#f3f4f6;text-decoration:none}.btn.focus,.btn:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.25);outline:0}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{background-color:#3232af;border-color:#3030a5;color:#fff}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(93,93,208,.5)}.btn-primary.disabled,.btn-primary:disabled{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{background-color:#3030a5;border-color:#2d2d9b;color:#fff}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(93,93,208,.5)}.btn-secondary{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{background-color:#3b424d;border-color:#353c46;color:#fff}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem hsla(213,9%,44%,.5)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{background-color:#353c46;border-color:#30363f;color:#fff}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem hsla(213,9%,44%,.5)}.btn-success{background-color:#059669;border-color:#059669;color:#fff}.btn-success.focus,.btn-success:focus,.btn-success:hover{background-color:#04714f;border-color:#036546;color:#fff}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(43,166,128,.5)}.btn-success.disabled,.btn-success:disabled{background-color:#059669;border-color:#059669;color:#fff}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{background-color:#036546;border-color:#03583e;color:#fff}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(43,166,128,.5)}.btn-info{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-info.focus,.btn-info:focus,.btn-info:hover{background-color:#1451d6;border-color:#134cca;color:#fff}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(70,122,238,.5)}.btn-info.disabled,.btn-info:disabled{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{background-color:#134cca;border-color:#1248bf;color:#fff}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(70,122,238,.5)}.btn-warning{background-color:#d97706;border-color:#d97706;color:#fff}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{background-color:#b46305;border-color:#a75c05;color:#fff}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(223,139,43,.5)}.btn-warning.disabled,.btn-warning:disabled{background-color:#d97706;border-color:#d97706;color:#fff}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{background-color:#a75c05;border-color:#9b5504;color:#fff}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(223,139,43,.5)}.btn-danger{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{background-color:#bd1f1f;border-color:#b21d1d;color:#fff}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,71,71,.5)}.btn-danger.disabled,.btn-danger:disabled{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{background-color:#b21d1d;border-color:#a71b1b;color:#fff}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,71,71,.5)}.btn-light{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-light.focus,.btn-light:focus,.btn-light:hover{background-color:#dde0e6;border-color:#d6d9e0;color:#111827}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem hsla(220,7%,83%,.5)}.btn-light.disabled,.btn-light:disabled{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{background-color:#d6d9e0;border-color:#cfd3db;color:#111827}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem hsla(220,7%,83%,.5)}.btn-dark{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{background-color:#11171f;border-color:#0d1116;color:#fff}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(65,73,85,.5)}.btn-dark.disabled,.btn-dark:disabled{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{background-color:#0d1116;border-color:#080b0e;color:#fff}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(65,73,85,.5)}.btn-outline-primary{border-color:#4040c8;color:#4040c8}.btn-outline-primary:hover{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{background-color:transparent;color:#4040c8}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.5)}.btn-outline-secondary{border-color:#4b5563;color:#4b5563}.btn-outline-secondary:hover{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(75,85,99,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{background-color:transparent;color:#4b5563}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(75,85,99,.5)}.btn-outline-success{border-color:#059669;color:#059669}.btn-outline-success:hover{background-color:#059669;border-color:#059669;color:#fff}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(5,150,105,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{background-color:transparent;color:#059669}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{background-color:#059669;border-color:#059669;color:#fff}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(5,150,105,.5)}.btn-outline-info{border-color:#2563eb;color:#2563eb}.btn-outline-info:hover{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(37,99,235,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{background-color:transparent;color:#2563eb}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(37,99,235,.5)}.btn-outline-warning{border-color:#d97706;color:#d97706}.btn-outline-warning:hover{background-color:#d97706;border-color:#d97706;color:#fff}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(217,119,6,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{background-color:transparent;color:#d97706}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{background-color:#d97706;border-color:#d97706;color:#fff}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(217,119,6,.5)}.btn-outline-danger{border-color:#dc2626;color:#dc2626}.btn-outline-danger:hover{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,38,38,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{background-color:transparent;color:#dc2626}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,38,38,.5)}.btn-outline-light{border-color:#f3f4f6;color:#f3f4f6}.btn-outline-light:hover{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(243,244,246,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{background-color:transparent;color:#f3f4f6}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(243,244,246,.5)}.btn-outline-dark{border-color:#1f2937;color:#1f2937}.btn-outline-dark:hover{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(31,41,55,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{background-color:transparent;color:#1f2937}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(31,41,55,.5)}.btn-link{color:#818cf8;font-weight:400;text-decoration:none}.btn-link:hover{color:#a5b4fc}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#4b5563;pointer-events:none}.btn-group-lg>.btn,.btn-lg{border-radius:6px;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.btn-group-sm>.btn,.btn-sm{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;position:relative;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{border-bottom:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{background-clip:padding-box;background-color:#374151;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;color:#f3f4f6;display:none;float:left;font-size:1rem;left:0;list-style:none;margin:.125rem 0 0;min-width:10rem;padding:.5rem 0;position:absolute;text-align:left;top:100%;z-index:1000}.dropdown-menu-left{left:0;right:auto}.dropdown-menu-right{left:auto;right:0}@media (min-width:2px){.dropdown-menu-sm-left{left:0;right:auto}.dropdown-menu-sm-right{left:auto;right:0}}@media (min-width:8px){.dropdown-menu-md-left{left:0;right:auto}.dropdown-menu-md-right{left:auto;right:0}}@media (min-width:9px){.dropdown-menu-lg-left{left:0;right:auto}.dropdown-menu-lg-right{left:auto;right:0}}@media (min-width:10px){.dropdown-menu-xl-left{left:0;right:auto}.dropdown-menu-xl-right{left:auto;right:0}}.dropup .dropdown-menu{bottom:100%;margin-bottom:.125rem;margin-top:0;top:auto}.dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{left:100%;margin-left:.125rem;margin-top:0;right:auto;top:0}.dropright .dropdown-toggle:after{border-bottom:.3em solid transparent;border-left:.3em solid;border-right:0;border-top:.3em solid transparent;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{left:auto;margin-right:.125rem;margin-top:0;right:100%;top:0}.dropleft .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.dropleft .dropdown-toggle:before{border-bottom:.3em solid transparent;border-right:.3em solid;border-top:.3em solid transparent;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{bottom:auto;right:auto}.dropdown-divider{border-top:1px solid #e5e7eb;height:0;margin:.5rem 0;overflow:hidden}.dropdown-item{background-color:transparent;border:0;clear:both;color:#fff;display:block;font-weight:400;padding:.25rem 1.5rem;text-align:inherit;white-space:nowrap;width:100%}.dropdown-item:focus,.dropdown-item:hover{background-color:#e5e7eb;color:#090d15;text-decoration:none}.dropdown-item.active,.dropdown-item:active{background-color:#4040c8;color:#fff;text-decoration:none}.dropdown-item.disabled,.dropdown-item:disabled{background-color:transparent;color:#6b7280;pointer-events:none}.dropdown-menu.show{display:block}.dropdown-header{color:#4b5563;display:block;font-size:.875rem;margin-bottom:0;padding:.5rem 1.5rem;white-space:nowrap}.dropdown-item-text{color:#fff;display:block;padding:.25rem 1.5rem}.btn-group,.btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{flex:1 1 auto;position:relative}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{flex:1 1 auto;margin-bottom:0;min-width:0;position:relative;width:1%}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group>.custom-file{align-items:center;display:flex}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label{border-bottom-left-radius:0;border-top-left-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label:after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label:after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{align-items:center;background-color:#e5e7eb;border:1px solid #4b5563;border-radius:.25rem;color:#e5e7eb;display:flex;font-size:1rem;font-weight:400;line-height:1.5;margin-bottom:0;padding:.375rem .75rem;text-align:center;white-space:nowrap}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{border-radius:6px;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-bottom-right-radius:0;border-top-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-bottom-left-radius:0;border-top-left-radius:0}.custom-control{-webkit-print-color-adjust:exact;color-adjust:exact;display:block;min-height:1.5rem;padding-left:1.5rem;position:relative;z-index:1}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{height:1.25rem;left:0;opacity:0;position:absolute;width:1rem;z-index:-1}.custom-control-input:checked~.custom-control-label:before{background-color:#4040c8;border-color:#4040c8;color:#fff}.custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(64,64,200,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#a3a3e5}.custom-control-input:not(:disabled):active~.custom-control-label:before{background-color:#cbcbf0;border-color:#cbcbf0;color:#fff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#4b5563}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e5e7eb}.custom-control-label{margin-bottom:0;position:relative;vertical-align:top}.custom-control-label:before{background-color:#1f2937;border:1px solid #6b7280;pointer-events:none}.custom-control-label:after,.custom-control-label:before{content:"";display:block;height:1rem;left:-1.5rem;position:absolute;top:.25rem;width:1rem}.custom-control-label:after{background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label:before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='m6.564.75-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{background-color:#4040c8;border-color:#4040c8}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{border-radius:.5rem;left:-2.25rem;pointer-events:all;width:1.75rem}.custom-switch .custom-control-label:after{background-color:#6b7280;border-radius:.5rem;height:calc(1rem - 4px);left:calc(-2.25rem + 2px);top:calc(.25rem + 2px);transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:calc(1rem - 4px)}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#1f2937;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#1f2937 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%231f2937' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat;border:1px solid #4b5563;border-radius:.25rem;color:#e5e7eb;display:inline-block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem 1.75rem .375rem .75rem;vertical-align:middle;width:100%}.custom-select:focus{border-color:#a3a3e5;box-shadow:0 0 0 .2rem rgba(64,64,200,.25);outline:0}.custom-select:focus::-ms-value{background-color:#1f2937;color:#e5e7eb}.custom-select[multiple],.custom-select[size]:not([size="1"]){background-image:none;height:auto;padding-right:.75rem}.custom-select:disabled{background-color:#e5e7eb;color:#4b5563}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #e5e7eb}.custom-select-sm{font-size:.875rem;height:calc(1.5em + .5rem + 2px);padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.custom-select-lg{font-size:1.25rem;height:calc(1.5em + 1rem + 2px);padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{height:calc(1.5em + .75rem + 2px);position:relative;width:100%}.custom-file-input{margin:0;opacity:0;overflow:hidden;z-index:2}.custom-file-input:focus~.custom-file-label{border-color:#a3a3e5;box-shadow:0 0 0 .2rem rgba(64,64,200,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e5e7eb}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{background-color:#1f2937;border:1px solid #4b5563;border-radius:.25rem;font-weight:400;height:calc(1.5em + .75rem + 2px);left:0;overflow:hidden;z-index:1}.custom-file-label,.custom-file-label:after{color:#e5e7eb;line-height:1.5;padding:.375rem .75rem;position:absolute;right:0;top:0}.custom-file-label:after{background-color:#e5e7eb;border-left:inherit;border-radius:0 .25rem .25rem 0;bottom:0;content:"Browse";display:block;height:calc(1.5em + .75rem);z-index:3}.custom-range{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;height:1.4rem;padding:0;width:100%}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #111827,0 0 0 .2rem rgba(64,64,200,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #111827,0 0 0 .2rem rgba(64,64,200,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #111827,0 0 0 .2rem rgba(64,64,200,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#4040c8;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#cbcbf0}.custom-range::-webkit-slider-runnable-track{background-color:#d1d5db;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.custom-range::-moz-range-thumb{-moz-appearance:none;appearance:none;background-color:#4040c8;border:0;border-radius:1rem;height:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#cbcbf0}.custom-range::-moz-range-track{background-color:#d1d5db;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.custom-range::-ms-thumb{appearance:none;background-color:#4040c8;border:0;border-radius:1rem;height:1rem;margin-left:.2rem;margin-right:.2rem;margin-top:0;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#cbcbf0}.custom-range::-ms-track{background-color:transparent;border-color:transparent;border-width:.5rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#d1d5db;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#6b7280}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#6b7280}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#6b7280}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#4b5563;cursor:default;pointer-events:none}.nav-tabs{border-bottom:1px solid #d1d5db}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem;margin-bottom:-1px}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e5e7eb #e5e7eb #d1d5db}.nav-tabs .nav-link.disabled{background-color:transparent;border-color:transparent;color:#4b5563}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{background-color:#111827;border-color:#d1d5db #d1d5db #111827;color:#374151}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{background-color:#1f2937;color:#fff}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{padding:.5rem 1rem;position:relative}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.navbar-brand{display:inline-block;font-size:1.25rem;line-height:inherit;margin-right:1rem;padding-bottom:.3125rem;padding-top:.3125rem;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link{padding-left:0;padding-right:0}.navbar-nav .dropdown-menu{float:none;position:static}.navbar-text{display:inline-block;padding-bottom:.5rem;padding-top:.5rem}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:1px solid transparent;border-radius:.25rem;font-size:1.25rem;line-height:1;padding:.25rem .75rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{background:50%/100% 100% no-repeat;content:"";display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:1.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-left:0;padding-right:0}}@media (min-width:2px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:7.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-left:0;padding-right:0}}@media (min-width:8px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:8.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-left:0;padding-right:0}}@media (min-width:9px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:9.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-left:0;padding-right:0}}@media (min-width:10px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-left:0;padding-right:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{border-color:rgba(0,0,0,.1);color:rgba(0,0,0,.5)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{border-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{word-wrap:break-word;background-clip:border-box;background-color:#1f2937;border:1px solid rgba(0,0,0,.125);border-radius:6px;display:flex;flex-direction:column;min-width:0;position:relative}.card>hr{margin-left:0;margin-right:0}.card>.list-group{border-bottom:inherit;border-top:inherit}.card>.list-group:first-child{border-top-left-radius:5px;border-top-right-radius:5px;border-top-width:0}.card>.list-group:last-child{border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{background-color:#374151;border-bottom:1px solid rgba(0,0,0,.125);margin-bottom:0;padding:.75rem 1.25rem}.card-header:first-child{border-radius:5px 5px 0 0}.card-footer{background-color:#374151;border-top:1px solid rgba(0,0,0,.125);padding:.75rem 1.25rem}.card-footer:last-child{border-radius:0 0 5px 5px}.card-header-tabs{border-bottom:0;margin-bottom:-.75rem}.card-header-pills,.card-header-tabs{margin-left:-.625rem;margin-right:-.625rem}.card-img-overlay{border-radius:5px;bottom:0;left:0;padding:1.25rem;position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:5px;border-top-right-radius:5px}.card-img,.card-img-bottom{border-bottom-left-radius:5px;border-bottom-right-radius:5px}.card-deck .card{margin-bottom:15px}@media (min-width:2px){.card-deck{display:flex;flex-flow:row wrap;margin-left:-15px;margin-right:-15px}.card-deck .card{flex:1 0 0%;margin-bottom:0;margin-left:15px;margin-right:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:2px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{border-left:0;margin-left:0}.card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:2px){.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{background-color:#e5e7eb;border-radius:.25rem;display:flex;flex-wrap:wrap;list-style:none;margin-bottom:1rem;padding:.75rem 1rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{color:#4b5563;content:"/";float:left;padding-right:.5rem}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#4b5563}.pagination{border-radius:.25rem;display:flex;list-style:none;padding-left:0}.page-link{background-color:#fff;border:1px solid #d1d5db;color:#818cf8;display:block;line-height:1.25;margin-left:-1px;padding:.5rem .75rem;position:relative}.page-link:hover{background-color:#e5e7eb;border-color:#d1d5db;color:#a5b4fc;text-decoration:none;z-index:2}.page-link:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.25);outline:0;z-index:3}.page-item:first-child .page-link{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem;margin-left:0}.page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.page-item.active .page-link{background-color:#4040c8;border-color:#4040c8;color:#fff;z-index:3}.page-item.disabled .page-link{background-color:#fff;border-color:#d1d5db;color:#4b5563;cursor:auto;pointer-events:none}.pagination-lg .page-link{font-size:1.25rem;line-height:1.5;padding:.75rem 1.5rem}.pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm .page-link{font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.badge{border-radius:.25rem;display:inline-block;font-size:.875rem;font-weight:600;line-height:1;padding:.25em .4em;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:baseline;white-space:nowrap}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{border-radius:10rem;padding-left:.6em;padding-right:.6em}.badge-primary{background-color:#4040c8;color:#fff}a.badge-primary:focus,a.badge-primary:hover{background-color:#3030a5;color:#fff}a.badge-primary.focus,a.badge-primary:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.5);outline:0}.badge-secondary{background-color:#4b5563;color:#fff}a.badge-secondary:focus,a.badge-secondary:hover{background-color:#353c46;color:#fff}a.badge-secondary.focus,a.badge-secondary:focus{box-shadow:0 0 0 .2rem rgba(75,85,99,.5);outline:0}.badge-success{background-color:#059669}a.badge-success:focus,a.badge-success:hover{background-color:#036546;color:#fff}a.badge-success.focus,a.badge-success:focus{box-shadow:0 0 0 .2rem rgba(5,150,105,.5);outline:0}.badge-info{background-color:#2563eb}a.badge-info:focus,a.badge-info:hover{background-color:#134cca;color:#fff}a.badge-info.focus,a.badge-info:focus{box-shadow:0 0 0 .2rem rgba(37,99,235,.5);outline:0}.badge-warning{background-color:#d97706}a.badge-warning:focus,a.badge-warning:hover{background-color:#a75c05;color:#fff}a.badge-warning.focus,a.badge-warning:focus{box-shadow:0 0 0 .2rem rgba(217,119,6,.5);outline:0}.badge-danger{background-color:#dc2626}a.badge-danger:focus,a.badge-danger:hover{background-color:#b21d1d;color:#fff}a.badge-danger.focus,a.badge-danger:focus{box-shadow:0 0 0 .2rem rgba(220,38,38,.5);outline:0}.badge-light{background-color:#f3f4f6;color:#111827}a.badge-light:focus,a.badge-light:hover{background-color:#d6d9e0;color:#111827}a.badge-light.focus,a.badge-light:focus{box-shadow:0 0 0 .2rem rgba(243,244,246,.5);outline:0}.badge-dark{background-color:#1f2937;color:#fff}a.badge-dark:focus,a.badge-dark:hover{background-color:#0d1116;color:#fff}a.badge-dark.focus,a.badge-dark:focus{box-shadow:0 0 0 .2rem rgba(31,41,55,.5);outline:0}.jumbotron{background-color:#e5e7eb;border-radius:6px;margin-bottom:2rem;padding:2rem 1rem}@media (min-width:2px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{border-radius:0;padding-left:0;padding-right:0}.alert{border:1px solid transparent;border-radius:.25rem;margin-bottom:1rem;padding:.75rem 1.25rem;position:relative}.alert-heading{color:inherit}.alert-link{font-weight:600}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{color:inherit;padding:.75rem 1.25rem;position:absolute;right:0;top:0;z-index:2}.alert-primary{background-color:#d9d9f4;border-color:#cacaf0;color:#212168}.alert-primary hr{border-top-color:#b6b6ea}.alert-primary .alert-link{color:#151541}.alert-secondary{background-color:#dbdde0;border-color:#cdcfd3;color:#272c33}.alert-secondary hr{border-top-color:#bfc2c7}.alert-secondary .alert-link{color:#111316}.alert-success{background-color:#cdeae1;border-color:#b9e2d5;color:#034e37}.alert-success hr{border-top-color:#a7dbca}.alert-success .alert-link{color:#011d14}.alert-info{background-color:#d3e0fb;border-color:#c2d3f9;color:#13337a}.alert-info hr{border-top-color:#abc2f7}.alert-info .alert-link{color:#0c214e}.alert-warning{background-color:#f7e4cd;border-color:#f4d9b9;color:#713e03}.alert-warning hr{border-top-color:#f1cda3}.alert-warning .alert-link{color:#3f2302}.alert-danger{background-color:#f8d4d4;border-color:#f5c2c2;color:#721414}.alert-danger hr{border-top-color:#f1acac}.alert-danger .alert-link{color:#470c0c}.alert-light{background-color:#fdfdfd;border-color:#fcfcfc;color:#7e7f80}.alert-light hr{border-top-color:#efefef}.alert-light .alert-link{color:#656666}.alert-dark{background-color:#d2d4d7;border-color:#c0c3c7;color:#10151d}.alert-dark hr{border-top-color:#b3b6bb}.alert-dark .alert-link{color:#000}@-webkit-keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{background-color:#e5e7eb;border-radius:.25rem;font-size:.75rem;height:1rem;line-height:0}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{background-color:#4040c8;color:#fff;flex-direction:column;justify-content:center;text-align:center;transition:width .6s ease;white-space:nowrap}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{align-items:flex-start;display:flex}.media-body{flex:1}.list-group{border-radius:.25rem;display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.list-group-item-action{color:#374151;text-align:inherit;width:100%}.list-group-item-action:focus,.list-group-item-action:hover{background-color:#f3f4f6;color:#374151;text-decoration:none;z-index:1}.list-group-item-action:active{background-color:#e5e7eb;color:#f3f4f6}.list-group-item{background-color:#fff;border:1px solid rgba(0,0,0,.125);display:block;padding:.75rem 1.25rem;position:relative}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{background-color:#fff;color:#4b5563;pointer-events:none}.list-group-item.active{background-color:#4040c8;border-color:#4040c8;color:#fff;z-index:2}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{border-top-width:1px;margin-top:-1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}@media (min-width:2px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:8px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:9px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:10px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{background-color:#cacaf0;color:#212168}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{background-color:#b6b6ea;color:#212168}.list-group-item-primary.list-group-item-action.active{background-color:#212168;border-color:#212168;color:#fff}.list-group-item-secondary{background-color:#cdcfd3;color:#272c33}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{background-color:#bfc2c7;color:#272c33}.list-group-item-secondary.list-group-item-action.active{background-color:#272c33;border-color:#272c33;color:#fff}.list-group-item-success{background-color:#b9e2d5;color:#034e37}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{background-color:#a7dbca;color:#034e37}.list-group-item-success.list-group-item-action.active{background-color:#034e37;border-color:#034e37;color:#fff}.list-group-item-info{background-color:#c2d3f9;color:#13337a}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{background-color:#abc2f7;color:#13337a}.list-group-item-info.list-group-item-action.active{background-color:#13337a;border-color:#13337a;color:#fff}.list-group-item-warning{background-color:#f4d9b9;color:#713e03}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{background-color:#f1cda3;color:#713e03}.list-group-item-warning.list-group-item-action.active{background-color:#713e03;border-color:#713e03;color:#fff}.list-group-item-danger{background-color:#f5c2c2;color:#721414}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{background-color:#f1acac;color:#721414}.list-group-item-danger.list-group-item-action.active{background-color:#721414;border-color:#721414;color:#fff}.list-group-item-light{background-color:#fcfcfc;color:#7e7f80}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{background-color:#efefef;color:#7e7f80}.list-group-item-light.list-group-item-action.active{background-color:#7e7f80;border-color:#7e7f80;color:#fff}.list-group-item-dark{background-color:#c0c3c7;color:#10151d}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{background-color:#b3b6bb;color:#10151d}.list-group-item-dark.list-group-item-action.active{background-color:#10151d;border-color:#10151d;color:#fff}.close{color:#000;float:right;font-size:1.5rem;font-weight:600;line-height:1;opacity:.5;text-shadow:0 1px 0 #fff}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{background-color:transparent;border:0;padding:0}a.close.disabled{pointer-events:none}.toast{background-clip:padding-box;background-color:hsla(0,0%,100%,.85);border:1px solid rgba(0,0,0,.1);border-radius:.25rem;box-shadow:0 .25rem .75rem rgba(0,0,0,.1);flex-basis:350px;font-size:.875rem;max-width:350px;opacity:0}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{align-items:center;background-clip:padding-box;background-color:hsla(0,0%,100%,.85);border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);color:#4b5563;display:flex;padding:.25rem .75rem}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{display:none;height:100%;left:0;outline:0;overflow:hidden;position:fixed;top:0;width:100%;z-index:1050}.modal-dialog{margin:.5rem;pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{content:"";display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;height:100%;justify-content:center}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{background-clip:padding-box;background-color:#1f2937;border:1px solid rgba(0,0,0,.2);border-radius:6px;display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-backdrop{background-color:#4b5563;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{align-items:flex-start;border-bottom:1px solid #4b5563;border-top-left-radius:5px;border-top-right-radius:5px;display:flex;justify-content:space-between;padding:1rem}.modal-header .close{margin:-1rem -1rem -1rem auto;padding:1rem}.modal-title{line-height:1.5;margin-bottom:0}.modal-body{flex:1 1 auto;padding:1rem;position:relative}.modal-footer{align-items:center;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:1px solid #4b5563;display:flex;flex-wrap:wrap;justify-content:flex-end;padding:.75rem}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{height:50px;overflow:scroll;position:absolute;top:-9999px;width:50px}@media (min-width:2px){.modal-dialog{margin:1.75rem auto;max-width:500px}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:9px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:10px){.modal-xl{max-width:1140px}}.tooltip{word-wrap:break-word;display:block;font-family:Figtree,sans-serif;font-size:.875rem;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:0;opacity:0;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:1070}.tooltip.show{opacity:.9}.tooltip .arrow{display:block;height:.4rem;position:absolute;width:.8rem}.tooltip .arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{border-top-color:#000;border-width:.4rem .4rem 0;top:0}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{height:.8rem;left:0;width:.4rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{border-right-color:#000;border-width:.4rem .4rem .4rem 0;right:0}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{border-bottom-color:#000;border-width:0 .4rem .4rem;bottom:0}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{height:.8rem;right:0;width:.4rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{border-left-color:#000;border-width:.4rem 0 .4rem .4rem;left:0}.tooltip-inner{background-color:#000;border-radius:.25rem;color:#fff;max-width:200px;padding:.25rem .5rem;text-align:center}.popover{word-wrap:break-word;background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;font-family:Figtree,sans-serif;font-size:.875rem;font-style:normal;font-weight:400;left:0;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:276px;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;top:0;white-space:normal;word-break:normal;word-spacing:normal;z-index:1060}.popover,.popover .arrow{display:block;position:absolute}.popover .arrow{height:.5rem;margin:0 6px;width:1rem}.popover .arrow:after,.popover .arrow:before{border-color:transparent;border-style:solid;content:"";display:block;position:absolute}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{border-top-color:rgba(0,0,0,.25);border-width:.5rem .5rem 0;bottom:0}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{border-top-color:#fff;border-width:.5rem .5rem 0;bottom:1px}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{height:1rem;left:calc(-.5rem - 1px);margin:6px 0;width:.5rem}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{border-right-color:rgba(0,0,0,.25);border-width:.5rem .5rem .5rem 0;left:0}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{border-right-color:#fff;border-width:.5rem .5rem .5rem 0;left:1px}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{border-bottom-color:rgba(0,0,0,.25);border-width:0 .5rem .5rem;top:0}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{border-bottom-color:#fff;border-width:0 .5rem .5rem;top:1px}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{border-bottom:1px solid #f7f7f7;content:"";display:block;left:50%;margin-left:-.5rem;position:absolute;top:0;width:1rem}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{height:1rem;margin:6px 0;right:calc(-.5rem - 1px);width:.5rem}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{border-left-color:rgba(0,0,0,.25);border-width:.5rem 0 .5rem .5rem;right:0}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{border-left-color:#fff;border-width:.5rem 0 .5rem .5rem;right:1px}.popover-header{background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:5px;border-top-right-radius:5px;font-size:1rem;margin-bottom:0;padding:.5rem .75rem}.popover-header:empty{display:none}.popover-body{color:#f3f4f6;padding:.5rem .75rem}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{overflow:hidden;position:relative;width:100%}.carousel-inner:after{clear:both;content:"";display:block}.carousel-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1;z-index:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0;transition:opacity 0s .6s;z-index:0}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{align-items:center;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{background:50%/100% 100% no-repeat;display:inline-block;height:20px;width:20px}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m5.25 0-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m2.75 0-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;list-style:none;margin-left:15%;margin-right:15%;padding-left:0;position:absolute;right:0;z-index:15}.carousel-indicators li{background-clip:padding-box;background-color:#fff;border-bottom:10px solid transparent;border-top:10px solid transparent;box-sizing:content-box;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;text-indent:-999px;transition:opacity .6s ease;width:30px}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{bottom:20px;color:#fff;left:15%;padding-bottom:20px;padding-top:20px;position:absolute;right:15%;text-align:center;z-index:10}@-webkit-keyframes spinner-border{to{transform:rotate(1turn)}}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite;border:.25em solid;border-radius:50%;border-right:.25em solid transparent;display:inline-block;height:2rem;vertical-align:text-bottom;width:2rem}.spinner-border-sm{border-width:.2em;height:1rem;width:1rem}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite;background-color:currentColor;border-radius:50%;display:inline-block;height:2rem;opacity:0;vertical-align:text-bottom;width:2rem}.spinner-grow-sm{height:1rem;width:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#4040c8!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#3030a5!important}.bg-secondary{background-color:#4b5563!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#353c46!important}.bg-success{background-color:#059669!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#036546!important}.bg-info{background-color:#2563eb!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#134cca!important}.bg-warning{background-color:#d97706!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#a75c05!important}.bg-danger{background-color:#dc2626!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#b21d1d!important}.bg-light{background-color:#f3f4f6!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#d6d9e0!important}.bg-dark{background-color:#1f2937!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#0d1116!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #4b5563!important}.border-top{border-top:1px solid #4b5563!important}.border-right{border-right:1px solid #4b5563!important}.border-bottom{border-bottom:1px solid #4b5563!important}.border-left{border-left:1px solid #4b5563!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#4040c8!important}.border-secondary{border-color:#4b5563!important}.border-success{border-color:#059669!important}.border-info{border-color:#2563eb!important}.border-warning{border-color:#d97706!important}.border-danger{border-color:#dc2626!important}.border-light{border-color:#f3f4f6!important}.border-dark{border-color:#1f2937!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:6px!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{clear:both;content:"";display:block}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:2px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:8px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:9px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:10px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{display:block;overflow:hidden;padding:0;position:relative;width:100%}.embed-responsive:before{content:"";display:block}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{border:0;bottom:0;height:100%;left:0;position:absolute;top:0;width:100%}.embed-responsive-21by9:before{padding-top:42.8571428571%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:2px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:8px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:9px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:10px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:2px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:8px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:9px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:10px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{left:0;position:fixed;right:0;z-index:1030}.fixed-bottom{bottom:0}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{clip:rect(0,0,0,0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;overflow:visible;position:static;white-space:normal;width:auto}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:2px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:8px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:9px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:10px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link:after{background-color:transparent;bottom:0;content:"";left:0;pointer-events:auto;position:absolute;right:0;top:0;z-index:1}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:2px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:8px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:9px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:10px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:600!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#4040c8!important}a.text-primary:focus,a.text-primary:hover{color:#2a2a92!important}.text-secondary{color:#4b5563!important}a.text-secondary:focus,a.text-secondary:hover{color:#2a3037!important}.text-success{color:#059669!important}a.text-success:focus,a.text-success:hover{color:#034c35!important}.text-info{color:#2563eb!important}a.text-info:focus,a.text-info:hover{color:#1043b3!important}.text-warning{color:#d97706!important}a.text-warning:focus,a.text-warning:hover{color:#8f4e04!important}.text-danger{color:#dc2626!important}a.text-danger:focus,a.text-danger:hover{color:#9c1919!important}.text-light{color:#f3f4f6!important}a.text-light:focus,a.text-light:hover{color:#c7ccd5!important}.text-dark{color:#1f2937!important}a.text-dark:focus,a.text-dark:hover{color:#030506!important}.text-body{color:#f3f4f6!important}.text-muted{color:#9ca3af!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{background-color:transparent;border:0;color:transparent;font:0/0 a;text-shadow:none}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{box-shadow:none!important;text-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #6b7280;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:9px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #d1d5db!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#374151}.table .thead-dark th{border-color:#374151;color:inherit}}.vjs-tree{color:#bfc7d5!important;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.vjs-tree .vjs-tree__content{border-left:1px dotted hsla(0,0%,80%,.28)!important}.vjs-tree .vjs-tree__node{cursor:pointer}.vjs-tree .vjs-tree__node:hover{color:#20a0ff}.vjs-tree .vjs-checkbox{left:-30px;position:absolute}.vjs-tree .vjs-value__boolean,.vjs-tree .vjs-value__null,.vjs-tree .vjs-value__number{color:#a291f5!important}.vjs-tree .vjs-value__string{color:#c3e88d!important}.vjs-tree .vjs-key{color:#c3cbd3!important}.hljs-addition,.hljs-attr,.hljs-keyword,.hljs-selector-tag{color:#13ce66}.hljs-bullet,.hljs-meta,.hljs-name,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable{color:#c3e88d}.hljs-comment,.hljs-deletion,.hljs-quote{color:#bfcbd9}.hljs-literal,.hljs-number,.hljs-title{color:#a291f5!important}body{padding-bottom:20px}.container{max-width:1440px}html{min-width:1140px}[v-cloak]{display:none}svg.icon{height:1rem;width:1rem}.header{border-bottom:1px solid #374151}.header .logo{color:#e5e7eb;text-decoration:none}.header .logo svg{height:1.7rem;width:1.7rem}.sidebar .nav-item a{border-radius:6px;color:#9ca3af;margin-bottom:4px;padding:.5rem .75rem}.sidebar .nav-item a svg{fill:#6b7280;height:1.25rem;margin-right:15px;width:1.25rem}.sidebar .nav-item a:hover{background-color:#1f2937;color:#d1d5db}.sidebar .nav-item a.active{background-color:#1f2937;color:#818cf8}.sidebar .nav-item a.active svg{fill:#6366f1}.card{border:none;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1)}.card .bottom-radius{border-bottom-left-radius:6px;border-bottom-right-radius:6px}.card .card-header{background-color:#374151;border-bottom:none;min-height:60px;padding-bottom:.7rem;padding-top:.7rem}.card .card-header .btn-group .btn{padding:.2rem .5rem}.card .card-header .form-control-with-icon{position:relative}.card .card-header .form-control-with-icon .icon-wrapper{jusify-content:center;align-items:center;bottom:0;display:flex;left:.75rem;position:absolute;top:0}.card .card-header .form-control-with-icon .icon-wrapper .icon{fill:#9ca3af}.card .card-header .form-control-with-icon .form-control{border-radius:9999px;font-size:.875rem;padding-left:2.25rem}.card .table td,.card .table th{padding:.75rem 1.25rem}.card .table th{background-color:#1f2937;border-bottom:0;font-size:.875rem;padding:.5rem 1.25rem}.card .table:not(.table-borderless) td{border-top:1px solid #374151}.card .table.penultimate-column-right td:nth-last-child(2),.card .table.penultimate-column-right th:nth-last-child(2){text-align:right}.card .table td.table-fit,.card .table th.table-fit{white-space:nowrap;width:1%}.fill-text-color{fill:#f3f4f6}.fill-danger{fill:#dc2626}.fill-warning{fill:#d97706}.fill-info{fill:#2563eb}.fill-success{fill:#059669}.fill-primary{fill:#4040c8}button:hover .fill-primary{fill:#fff}.btn-outline-primary.active .fill-primary{fill:#111827}.btn-outline-primary:not(:disabled):not(.disabled).active:focus{box-shadow:none!important}.btn-muted{background:#1f2937;color:#9ca3af}.btn-muted:focus,.btn-muted:hover{background:#374151;color:#d1d5db}.btn-muted.active{background:#4040c8;color:#fff}.badge-secondary{background:#d1d5db;color:#374151}.badge-success{background:#10b981;color:#fff}.badge-info{background:#3b82f6;color:#fff}.badge-warning{background:#f59e0b;color:#fff}.badge-danger{background:#ef4444;color:#fff}.control-action svg{fill:#6b7280;height:1.2rem;width:1.2rem}.control-action svg:hover{fill:#818cf8}@-webkit-keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.spin{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.card .nav-pills{background:#374151}.card .nav-pills .nav-link{border-radius:0;color:#9ca3af;font-size:.9rem;padding:.75rem 1.25rem}.card .nav-pills .nav-link:focus,.card .nav-pills .nav-link:hover{color:#e5e7eb}.card .nav-pills .nav-link.active{background:none;border-bottom:2px solid #a5b4fc;color:#a5b4fc}.list-enter-active:not(.dontanimate){transition:background 1s linear}.list-enter:not(.dontanimate),.list-leave-to:not(.dontanimate){background:#312e81}.code-bg .list-enter:not(.dontanimate),.code-bg .list-leave-to:not(.dontanimate){background:#4b5563}#indexScreen td{vertical-align:middle!important}.card-bg-secondary{background:#1f2937}.code-bg{background:#292d3e}.disabled-watcher{background:#dc2626;color:#fff;padding:.75rem} diff --git a/public/vendor/telescope/app.css b/public/vendor/telescope/app.css new file mode 100644 index 0000000..6d174fc --- /dev/null +++ b/public/vendor/telescope/app.css @@ -0,0 +1,7 @@ +@charset "UTF-8"; +/*! + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#4b5563;--gray-dark:#1f2937;--primary:#4040c8;--secondary:#4b5563;--success:#059669;--info:#2563eb;--warning:#d97706;--danger:#dc2626;--light:#f3f4f6;--dark:#1f2937;--breakpoint-xs:0;--breakpoint-sm:2px;--breakpoint-md:8px;--breakpoint-lg:9px;--breakpoint-xl:10px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);font-family:sans-serif;line-height:1.15}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{background-color:#f3f4f6;color:#111827;font-family:Figtree,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;margin:0;text-align:left}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;margin-top:0}p{margin-bottom:1rem;margin-top:0}abbr[data-original-title],abbr[title]{border-bottom:0;cursor:help;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:600}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{background-color:transparent;color:#6366f1;text-decoration:none}a:hover{color:#4f46e5;text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{-ms-overflow-style:scrollbar;margin-bottom:1rem;margin-top:0;overflow:auto}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{caption-side:bottom;color:#6b7280;padding-bottom:.75rem;padding-top:.75rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{color:inherit;display:block;font-size:1.5rem;line-height:inherit;margin-bottom:.5rem;max-width:100%;padding:0;white-space:normal;width:100%}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:none;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}output{display:inline-block}summary{cursor:pointer;display:list-item}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:500;line-height:1.2;margin-bottom:.5rem}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem}.display-1,.display-2{font-weight:300;line-height:1.2}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-3,.display-4{font-weight:300;line-height:1.2}.display-4{font-size:3.5rem}hr{border:0;border-top:1px solid rgba(0,0,0,.1);margin-bottom:1rem;margin-top:1rem}.small,small{font-size:80%;font-weight:400}.mark,mark{background-color:#fcf8e3;padding:.2em}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{font-size:1.25rem;margin-bottom:1rem}.blockquote-footer{color:#4b5563;display:block;font-size:80%}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{height:auto;max-width:100%}.img-thumbnail{background-color:#f3f4f6;border:1px solid #d1d5db;border-radius:.25rem;padding:.25rem}.figure{display:inline-block}.figure-img{line-height:1;margin-bottom:.5rem}.figure-caption{color:#4b5563;font-size:90%}code{word-wrap:break-word;color:#e83e8c;font-size:87.5%}a>code{color:inherit}kbd{background-color:#111827;border-radius:.2rem;color:#fff;font-size:87.5%;padding:.2rem .4rem}kbd kbd{font-size:100%;font-weight:600;padding:0}pre{color:#111827;display:block;font-size:87.5%}pre code{color:inherit;font-size:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media (min-width:2px){.container,.container-sm{max-width:1137px}}@media (min-width:8px){.container,.container-md,.container-sm{max-width:1138px}}@media (min-width:9px){.container,.container-lg,.container-md,.container-sm{max-width:1139px}}@media (min-width:10px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.no-gutters{margin-left:0;margin-right:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-left:0;padding-right:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{padding-left:15px;padding-right:15px;position:relative;width:100%}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;max-width:100%;width:auto}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width:2px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width:8px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;max-width:100%;width:auto}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width:9px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;max-width:100%;width:auto}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width:10px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;max-width:100%;width:auto}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.table{color:#111827;margin-bottom:1rem;width:100%}.table td,.table th{border-top:1px solid #e5e7eb;padding:.75rem;vertical-align:top}.table thead th{border-bottom:2px solid #e5e7eb;vertical-align:bottom}.table tbody+tbody{border-top:2px solid #e5e7eb}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #e5e7eb}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:#f3f4f6;color:#111827}.table-primary,.table-primary>td,.table-primary>th{background-color:#cacaf0}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#9c9ce2}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#b6b6ea}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#cdcfd3}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#a1a7ae}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#bfc2c7}.table-success,.table-success>td,.table-success>th{background-color:#b9e2d5}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#7dc8b1}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a7dbca}.table-info,.table-info>td,.table-info>th{background-color:#c2d3f9}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#8eaef5}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abc2f7}.table-warning,.table-warning>td,.table-warning>th{background-color:#f4d9b9}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ebb87e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#f1cda3}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c2c2}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed8e8e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1acac}.table-light,.table-light>td,.table-light>th{background-color:#fcfcfc}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#f9f9fa}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#efefef}.table-dark,.table-dark>td,.table-dark>th{background-color:#c0c3c7}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#8b9097}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b3b6bb}.table-active,.table-active>td,.table-active>th{background-color:#f3f4f6}.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:#e4e7eb}.table .thead-dark th{background-color:#1f2937;border-color:#2d3b4f;color:#fff}.table .thead-light th{background-color:#e5e7eb;border-color:#e5e7eb;color:#374151}.table-dark{background-color:#1f2937;color:#fff}.table-dark td,.table-dark th,.table-dark thead th{border-color:#2d3b4f}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{background-color:hsla(0,0%,100%,.075);color:#fff}@media (max-width:1.98px){.table-responsive-sm{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:7.98px){.table-responsive-md{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-md>.table-bordered{border:0}}@media (max-width:8.98px){.table-responsive-lg{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:9.98px){.table-responsive-xl{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.table-responsive>.table-bordered{border:0}.form-control{background-clip:padding-box;background-color:#fff;border:1px solid #d1d5db;border-radius:.25rem;color:#1f2937;display:block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #1f2937}.form-control:focus{background-color:#fff;border-color:#a3a3e5;box-shadow:0 0 0 .2rem rgba(64,64,200,.25);color:#1f2937;outline:0}.form-control::-moz-placeholder{color:#4b5563;opacity:1}.form-control:-ms-input-placeholder{color:#4b5563;opacity:1}.form-control::placeholder{color:#4b5563;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e5e7eb;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{background-color:#fff;color:#1f2937}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + 1px);padding-top:calc(.375rem + 1px)}.col-form-label-lg{font-size:1.25rem;line-height:1.5;padding-bottom:calc(.5rem + 1px);padding-top:calc(.5rem + 1px)}.col-form-label-sm{font-size:.875rem;line-height:1.5;padding-bottom:calc(.25rem + 1px);padding-top:calc(.25rem + 1px)}.form-control-plaintext{background-color:transparent;border:solid transparent;border-width:1px 0;color:#111827;display:block;font-size:1rem;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.form-control-sm{border-radius:.2rem;font-size:.875rem;height:calc(1.5em + .5rem + 2px);line-height:1.5;padding:.25rem .5rem}.form-control-lg{border-radius:6px;font-size:1.25rem;height:calc(1.5em + 1rem + 2px);line-height:1.5;padding:.5rem 1rem}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-left:-5px;margin-right:-5px}.form-row>.col,.form-row>[class*=col-]{padding-left:5px;padding-right:5px}.form-check{display:block;padding-left:1.25rem;position:relative}.form-check-input{margin-left:-1.25rem;margin-top:.3rem;position:absolute}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6b7280}.form-check-label{margin-bottom:0}.form-check-inline{align-items:center;display:inline-flex;margin-right:.75rem;padding-left:0}.form-check-inline .form-check-input{margin-left:0;margin-right:.3125rem;margin-top:0;position:static}.valid-feedback{color:#059669;display:none;font-size:80%;margin-top:.25rem;width:100%}.valid-tooltip{background-color:rgba(5,150,105,.9);border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23059669' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#059669;padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#059669;box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.custom-select.is-valid,.was-validated .custom-select:valid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%231f2937' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23059669' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#059669;padding-right:calc(.75em + 2.3125rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#059669;box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#059669}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#059669}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#059669}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{background-color:#07c78c;border-color:#07c78c}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before{border-color:#059669}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#059669}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#059669;box-shadow:0 0 0 .2rem rgba(5,150,105,.25)}.invalid-feedback{color:#dc2626;display:none;font-size:80%;margin-top:.25rem;width:100%}.invalid-tooltip{background-color:rgba(220,38,38,.9);border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc2626'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc2626' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc2626;padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc2626;box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%231f2937' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc2626'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc2626' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#dc2626;padding-right:calc(.75em + 2.3125rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc2626;box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc2626}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc2626}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc2626}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{background-color:#e35252;border-color:#e35252}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before{border-color:#dc2626}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc2626}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc2626;box-shadow:0 0 0 .2rem rgba(220,38,38,.25)}.form-inline{align-items:center;display:flex;flex-flow:row wrap}.form-inline .form-check{width:100%}@media (min-width:2px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{align-items:center;display:flex;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .form-control{display:inline-block;vertical-align:middle;width:auto}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{align-items:center;display:flex;justify-content:center;padding-left:0;width:auto}.form-inline .form-check-input{flex-shrink:0;margin-left:0;margin-right:.25rem;margin-top:0;position:relative}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;color:#111827;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#111827;text-decoration:none}.btn.focus,.btn:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.25);outline:0}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{background-color:#3232af;border-color:#3030a5;color:#fff}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 0 rgba(93,93,208,.5)}.btn-primary.disabled,.btn-primary:disabled{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{background-color:#3030a5;border-color:#2d2d9b;color:#fff}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(93,93,208,.5)}.btn-secondary{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{background-color:#3b424d;border-color:#353c46;color:#fff}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 0 hsla(213,9%,44%,.5)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{background-color:#353c46;border-color:#30363f;color:#fff}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 hsla(213,9%,44%,.5)}.btn-success{background-color:#059669;border-color:#059669;color:#fff}.btn-success.focus,.btn-success:focus,.btn-success:hover{background-color:#04714f;border-color:#036546;color:#fff}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 0 rgba(43,166,128,.5)}.btn-success.disabled,.btn-success:disabled{background-color:#059669;border-color:#059669;color:#fff}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{background-color:#036546;border-color:#03583e;color:#fff}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(43,166,128,.5)}.btn-info{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-info.focus,.btn-info:focus,.btn-info:hover{background-color:#1451d6;border-color:#134cca;color:#fff}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 0 rgba(70,122,238,.5)}.btn-info.disabled,.btn-info:disabled{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{background-color:#134cca;border-color:#1248bf;color:#fff}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(70,122,238,.5)}.btn-warning{background-color:#d97706;border-color:#d97706;color:#fff}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{background-color:#b46305;border-color:#a75c05;color:#fff}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 0 rgba(223,139,43,.5)}.btn-warning.disabled,.btn-warning:disabled{background-color:#d97706;border-color:#d97706;color:#fff}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{background-color:#a75c05;border-color:#9b5504;color:#fff}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(223,139,43,.5)}.btn-danger{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{background-color:#bd1f1f;border-color:#b21d1d;color:#fff}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 0 rgba(225,71,71,.5)}.btn-danger.disabled,.btn-danger:disabled{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{background-color:#b21d1d;border-color:#a71b1b;color:#fff}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(225,71,71,.5)}.btn-light{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-light.focus,.btn-light:focus,.btn-light:hover{background-color:#dde0e6;border-color:#d6d9e0;color:#111827}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 0 hsla(220,7%,83%,.5)}.btn-light.disabled,.btn-light:disabled{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{background-color:#d6d9e0;border-color:#cfd3db;color:#111827}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 hsla(220,7%,83%,.5)}.btn-dark{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{background-color:#11171f;border-color:#0d1116;color:#fff}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 0 rgba(65,73,85,.5)}.btn-dark.disabled,.btn-dark:disabled{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{background-color:#0d1116;border-color:#080b0e;color:#fff}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(65,73,85,.5)}.btn-outline-primary{border-color:#4040c8;color:#4040c8}.btn-outline-primary:hover{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(64,64,200,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{background-color:transparent;color:#4040c8}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{background-color:#4040c8;border-color:#4040c8;color:#fff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(64,64,200,.5)}.btn-outline-secondary{border-color:#4b5563;color:#4b5563}.btn-outline-secondary:hover{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(75,85,99,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{background-color:transparent;color:#4b5563}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{background-color:#4b5563;border-color:#4b5563;color:#fff}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(75,85,99,.5)}.btn-outline-success{border-color:#059669;color:#059669}.btn-outline-success:hover{background-color:#059669;border-color:#059669;color:#fff}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(5,150,105,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{background-color:transparent;color:#059669}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{background-color:#059669;border-color:#059669;color:#fff}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(5,150,105,.5)}.btn-outline-info{border-color:#2563eb;color:#2563eb}.btn-outline-info:hover{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(37,99,235,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{background-color:transparent;color:#2563eb}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{background-color:#2563eb;border-color:#2563eb;color:#fff}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(37,99,235,.5)}.btn-outline-warning{border-color:#d97706;color:#d97706}.btn-outline-warning:hover{background-color:#d97706;border-color:#d97706;color:#fff}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(217,119,6,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{background-color:transparent;color:#d97706}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{background-color:#d97706;border-color:#d97706;color:#fff}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,119,6,.5)}.btn-outline-danger{border-color:#dc2626;color:#dc2626}.btn-outline-danger:hover{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(220,38,38,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{background-color:transparent;color:#dc2626}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{background-color:#dc2626;border-color:#dc2626;color:#fff}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(220,38,38,.5)}.btn-outline-light{border-color:#f3f4f6;color:#f3f4f6}.btn-outline-light:hover{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(243,244,246,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{background-color:transparent;color:#f3f4f6}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{background-color:#f3f4f6;border-color:#f3f4f6;color:#111827}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(243,244,246,.5)}.btn-outline-dark{border-color:#1f2937;color:#1f2937}.btn-outline-dark:hover{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(31,41,55,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{background-color:transparent;color:#1f2937}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{background-color:#1f2937;border-color:#1f2937;color:#fff}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(31,41,55,.5)}.btn-link{color:#6366f1;font-weight:400;text-decoration:none}.btn-link:hover{color:#4f46e5}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#4b5563;pointer-events:none}.btn-group-lg>.btn,.btn-lg{border-radius:6px;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.btn-group-sm>.btn,.btn-sm{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;position:relative;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{border-bottom:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;color:#111827;display:none;float:left;font-size:1rem;left:0;list-style:none;margin:.125rem 0 0;min-width:10rem;padding:.5rem 0;position:absolute;text-align:left;top:100%;z-index:1000}.dropdown-menu-left{left:0;right:auto}.dropdown-menu-right{left:auto;right:0}@media (min-width:2px){.dropdown-menu-sm-left{left:0;right:auto}.dropdown-menu-sm-right{left:auto;right:0}}@media (min-width:8px){.dropdown-menu-md-left{left:0;right:auto}.dropdown-menu-md-right{left:auto;right:0}}@media (min-width:9px){.dropdown-menu-lg-left{left:0;right:auto}.dropdown-menu-lg-right{left:auto;right:0}}@media (min-width:10px){.dropdown-menu-xl-left{left:0;right:auto}.dropdown-menu-xl-right{left:auto;right:0}}.dropup .dropdown-menu{bottom:100%;margin-bottom:.125rem;margin-top:0;top:auto}.dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{left:100%;margin-left:.125rem;margin-top:0;right:auto;top:0}.dropright .dropdown-toggle:after{border-bottom:.3em solid transparent;border-left:.3em solid;border-right:0;border-top:.3em solid transparent;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{left:auto;margin-right:.125rem;margin-top:0;right:100%;top:0}.dropleft .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.dropleft .dropdown-toggle:before{border-bottom:.3em solid transparent;border-right:.3em solid;border-top:.3em solid transparent;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{bottom:auto;right:auto}.dropdown-divider{border-top:1px solid #e5e7eb;height:0;margin:.5rem 0;overflow:hidden}.dropdown-item{background-color:transparent;border:0;clear:both;color:#374151;display:block;font-weight:400;padding:.25rem 1.5rem;text-align:inherit;white-space:nowrap;width:100%}.dropdown-item:focus,.dropdown-item:hover{background-color:#e5e7eb;color:#090d15;text-decoration:none}.dropdown-item.active,.dropdown-item:active{background-color:#4040c8;color:#fff;text-decoration:none}.dropdown-item.disabled,.dropdown-item:disabled{background-color:transparent;color:#6b7280;pointer-events:none}.dropdown-menu.show{display:block}.dropdown-header{color:#4b5563;display:block;font-size:.875rem;margin-bottom:0;padding:.5rem 1.5rem;white-space:nowrap}.dropdown-item-text{color:#374151;display:block;padding:.25rem 1.5rem}.btn-group,.btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{flex:1 1 auto;position:relative}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{flex:1 1 auto;margin-bottom:0;min-width:0;position:relative;width:1%}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group>.custom-file{align-items:center;display:flex}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label{border-bottom-left-radius:0;border-top-left-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label:after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label:after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{align-items:center;background-color:#e5e7eb;border:1px solid #d1d5db;border-radius:.25rem;color:#1f2937;display:flex;font-size:1rem;font-weight:400;line-height:1.5;margin-bottom:0;padding:.375rem .75rem;text-align:center;white-space:nowrap}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{border-radius:6px;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-bottom-right-radius:0;border-top-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-bottom-left-radius:0;border-top-left-radius:0}.custom-control{-webkit-print-color-adjust:exact;color-adjust:exact;display:block;min-height:1.5rem;padding-left:1.5rem;position:relative;z-index:1}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{height:1.25rem;left:0;opacity:0;position:absolute;width:1rem;z-index:-1}.custom-control-input:checked~.custom-control-label:before{background-color:#4040c8;border-color:#4040c8;color:#fff}.custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(64,64,200,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#a3a3e5}.custom-control-input:not(:disabled):active~.custom-control-label:before{background-color:#cbcbf0;border-color:#cbcbf0;color:#fff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#4b5563}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e5e7eb}.custom-control-label{margin-bottom:0;position:relative;vertical-align:top}.custom-control-label:before{background-color:#fff;border:1px solid #6b7280;pointer-events:none}.custom-control-label:after,.custom-control-label:before{content:"";display:block;height:1rem;left:-1.5rem;position:absolute;top:.25rem;width:1rem}.custom-control-label:after{background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label:before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='m6.564.75-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{background-color:#4040c8;border-color:#4040c8}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{border-radius:.5rem;left:-2.25rem;pointer-events:all;width:1.75rem}.custom-switch .custom-control-label:after{background-color:#6b7280;border-radius:.5rem;height:calc(1rem - 4px);left:calc(-2.25rem + 2px);top:calc(.25rem + 2px);transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:calc(1rem - 4px)}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(64,64,200,.5)}.custom-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%231f2937' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat;border:1px solid #d1d5db;border-radius:.25rem;color:#1f2937;display:inline-block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem 1.75rem .375rem .75rem;vertical-align:middle;width:100%}.custom-select:focus{border-color:#a3a3e5;box-shadow:0 0 0 .2rem rgba(64,64,200,.25);outline:0}.custom-select:focus::-ms-value{background-color:#fff;color:#1f2937}.custom-select[multiple],.custom-select[size]:not([size="1"]){background-image:none;height:auto;padding-right:.75rem}.custom-select:disabled{background-color:#e5e7eb;color:#4b5563}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #1f2937}.custom-select-sm{font-size:.875rem;height:calc(1.5em + .5rem + 2px);padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.custom-select-lg{font-size:1.25rem;height:calc(1.5em + 1rem + 2px);padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{height:calc(1.5em + .75rem + 2px);position:relative;width:100%}.custom-file-input{margin:0;opacity:0;overflow:hidden;z-index:2}.custom-file-input:focus~.custom-file-label{border-color:#a3a3e5;box-shadow:0 0 0 .2rem rgba(64,64,200,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e5e7eb}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{background-color:#fff;border:1px solid #d1d5db;border-radius:.25rem;font-weight:400;height:calc(1.5em + .75rem + 2px);left:0;overflow:hidden;z-index:1}.custom-file-label,.custom-file-label:after{color:#1f2937;line-height:1.5;padding:.375rem .75rem;position:absolute;right:0;top:0}.custom-file-label:after{background-color:#e5e7eb;border-left:inherit;border-radius:0 .25rem .25rem 0;bottom:0;content:"Browse";display:block;height:calc(1.5em + .75rem);z-index:3}.custom-range{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;height:1.4rem;padding:0;width:100%}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #f3f4f6,0 0 0 .2rem rgba(64,64,200,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #f3f4f6,0 0 0 .2rem rgba(64,64,200,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #f3f4f6,0 0 0 .2rem rgba(64,64,200,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#4040c8;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#cbcbf0}.custom-range::-webkit-slider-runnable-track{background-color:#d1d5db;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.custom-range::-moz-range-thumb{-moz-appearance:none;appearance:none;background-color:#4040c8;border:0;border-radius:1rem;height:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#cbcbf0}.custom-range::-moz-range-track{background-color:#d1d5db;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.custom-range::-ms-thumb{appearance:none;background-color:#4040c8;border:0;border-radius:1rem;height:1rem;margin-left:.2rem;margin-right:.2rem;margin-top:0;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#cbcbf0}.custom-range::-ms-track{background-color:transparent;border-color:transparent;border-width:.5rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#d1d5db;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#6b7280}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#6b7280}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#6b7280}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#4b5563;cursor:default;pointer-events:none}.nav-tabs{border-bottom:1px solid #d1d5db}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem;margin-bottom:-1px}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e5e7eb #e5e7eb #d1d5db}.nav-tabs .nav-link.disabled{background-color:transparent;border-color:transparent;color:#4b5563}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{background-color:#f3f4f6;border-color:#d1d5db #d1d5db #f3f4f6;color:#374151}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{background-color:#e5e7eb;color:#fff}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{padding:.5rem 1rem;position:relative}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.navbar-brand{display:inline-block;font-size:1.25rem;line-height:inherit;margin-right:1rem;padding-bottom:.3125rem;padding-top:.3125rem;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link{padding-left:0;padding-right:0}.navbar-nav .dropdown-menu{float:none;position:static}.navbar-text{display:inline-block;padding-bottom:.5rem;padding-top:.5rem}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:1px solid transparent;border-radius:.25rem;font-size:1.25rem;line-height:1;padding:.25rem .75rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{background:50%/100% 100% no-repeat;content:"";display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:1.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-left:0;padding-right:0}}@media (min-width:2px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:7.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-left:0;padding-right:0}}@media (min-width:8px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:8.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-left:0;padding-right:0}}@media (min-width:9px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:9.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-left:0;padding-right:0}}@media (min-width:10px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-left:0;padding-right:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{border-color:rgba(0,0,0,.1);color:rgba(0,0,0,.5)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{border-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{word-wrap:break-word;background-clip:border-box;background-color:#fff;border:1px solid rgba(0,0,0,.125);border-radius:6px;display:flex;flex-direction:column;min-width:0;position:relative}.card>hr{margin-left:0;margin-right:0}.card>.list-group{border-bottom:inherit;border-top:inherit}.card>.list-group:first-child{border-top-left-radius:5px;border-top-right-radius:5px;border-top-width:0}.card>.list-group:last-child{border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{background-color:#fff;border-bottom:1px solid rgba(0,0,0,.125);margin-bottom:0;padding:.75rem 1.25rem}.card-header:first-child{border-radius:5px 5px 0 0}.card-footer{background-color:#fff;border-top:1px solid rgba(0,0,0,.125);padding:.75rem 1.25rem}.card-footer:last-child{border-radius:0 0 5px 5px}.card-header-tabs{border-bottom:0;margin-bottom:-.75rem}.card-header-pills,.card-header-tabs{margin-left:-.625rem;margin-right:-.625rem}.card-img-overlay{border-radius:5px;bottom:0;left:0;padding:1.25rem;position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:5px;border-top-right-radius:5px}.card-img,.card-img-bottom{border-bottom-left-radius:5px;border-bottom-right-radius:5px}.card-deck .card{margin-bottom:15px}@media (min-width:2px){.card-deck{display:flex;flex-flow:row wrap;margin-left:-15px;margin-right:-15px}.card-deck .card{flex:1 0 0%;margin-bottom:0;margin-left:15px;margin-right:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:2px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{border-left:0;margin-left:0}.card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:2px){.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{background-color:#e5e7eb;border-radius:.25rem;display:flex;flex-wrap:wrap;list-style:none;margin-bottom:1rem;padding:.75rem 1rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{color:#4b5563;content:"/";float:left;padding-right:.5rem}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#4b5563}.pagination{border-radius:.25rem;display:flex;list-style:none;padding-left:0}.page-link{background-color:#fff;border:1px solid #d1d5db;color:#6366f1;display:block;line-height:1.25;margin-left:-1px;padding:.5rem .75rem;position:relative}.page-link:hover{background-color:#e5e7eb;border-color:#d1d5db;color:#4f46e5;text-decoration:none;z-index:2}.page-link:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.25);outline:0;z-index:3}.page-item:first-child .page-link{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem;margin-left:0}.page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.page-item.active .page-link{background-color:#4040c8;border-color:#4040c8;color:#fff;z-index:3}.page-item.disabled .page-link{background-color:#fff;border-color:#d1d5db;color:#4b5563;cursor:auto;pointer-events:none}.pagination-lg .page-link{font-size:1.25rem;line-height:1.5;padding:.75rem 1.5rem}.pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm .page-link{font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.badge{border-radius:.25rem;display:inline-block;font-size:.875rem;font-weight:600;line-height:1;padding:.25em .4em;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:baseline;white-space:nowrap}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{border-radius:10rem;padding-left:.6em;padding-right:.6em}.badge-primary{background-color:#4040c8;color:#fff}a.badge-primary:focus,a.badge-primary:hover{background-color:#3030a5;color:#fff}a.badge-primary.focus,a.badge-primary:focus{box-shadow:0 0 0 .2rem rgba(64,64,200,.5);outline:0}.badge-secondary{background-color:#4b5563;color:#fff}a.badge-secondary:focus,a.badge-secondary:hover{background-color:#353c46;color:#fff}a.badge-secondary.focus,a.badge-secondary:focus{box-shadow:0 0 0 .2rem rgba(75,85,99,.5);outline:0}.badge-success{background-color:#059669;color:#fff}a.badge-success:focus,a.badge-success:hover{background-color:#036546;color:#fff}a.badge-success.focus,a.badge-success:focus{box-shadow:0 0 0 .2rem rgba(5,150,105,.5);outline:0}.badge-info{background-color:#2563eb;color:#fff}a.badge-info:focus,a.badge-info:hover{background-color:#134cca;color:#fff}a.badge-info.focus,a.badge-info:focus{box-shadow:0 0 0 .2rem rgba(37,99,235,.5);outline:0}.badge-warning{background-color:#d97706;color:#fff}a.badge-warning:focus,a.badge-warning:hover{background-color:#a75c05;color:#fff}a.badge-warning.focus,a.badge-warning:focus{box-shadow:0 0 0 .2rem rgba(217,119,6,.5);outline:0}.badge-danger{background-color:#dc2626;color:#fff}a.badge-danger:focus,a.badge-danger:hover{background-color:#b21d1d;color:#fff}a.badge-danger.focus,a.badge-danger:focus{box-shadow:0 0 0 .2rem rgba(220,38,38,.5);outline:0}.badge-light{background-color:#f3f4f6;color:#111827}a.badge-light:focus,a.badge-light:hover{background-color:#d6d9e0;color:#111827}a.badge-light.focus,a.badge-light:focus{box-shadow:0 0 0 .2rem rgba(243,244,246,.5);outline:0}.badge-dark{background-color:#1f2937;color:#fff}a.badge-dark:focus,a.badge-dark:hover{background-color:#0d1116;color:#fff}a.badge-dark.focus,a.badge-dark:focus{box-shadow:0 0 0 .2rem rgba(31,41,55,.5);outline:0}.jumbotron{background-color:#e5e7eb;border-radius:6px;margin-bottom:2rem;padding:2rem 1rem}@media (min-width:2px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{border-radius:0;padding-left:0;padding-right:0}.alert{border:1px solid transparent;border-radius:.25rem;margin-bottom:1rem;padding:.75rem 1.25rem;position:relative}.alert-heading{color:inherit}.alert-link{font-weight:600}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{color:inherit;padding:.75rem 1.25rem;position:absolute;right:0;top:0;z-index:2}.alert-primary{background-color:#d9d9f4;border-color:#cacaf0;color:#212168}.alert-primary hr{border-top-color:#b6b6ea}.alert-primary .alert-link{color:#151541}.alert-secondary{background-color:#dbdde0;border-color:#cdcfd3;color:#272c33}.alert-secondary hr{border-top-color:#bfc2c7}.alert-secondary .alert-link{color:#111316}.alert-success{background-color:#cdeae1;border-color:#b9e2d5;color:#034e37}.alert-success hr{border-top-color:#a7dbca}.alert-success .alert-link{color:#011d14}.alert-info{background-color:#d3e0fb;border-color:#c2d3f9;color:#13337a}.alert-info hr{border-top-color:#abc2f7}.alert-info .alert-link{color:#0c214e}.alert-warning{background-color:#f7e4cd;border-color:#f4d9b9;color:#713e03}.alert-warning hr{border-top-color:#f1cda3}.alert-warning .alert-link{color:#3f2302}.alert-danger{background-color:#f8d4d4;border-color:#f5c2c2;color:#721414}.alert-danger hr{border-top-color:#f1acac}.alert-danger .alert-link{color:#470c0c}.alert-light{background-color:#fdfdfd;border-color:#fcfcfc;color:#7e7f80}.alert-light hr{border-top-color:#efefef}.alert-light .alert-link{color:#656666}.alert-dark{background-color:#d2d4d7;border-color:#c0c3c7;color:#10151d}.alert-dark hr{border-top-color:#b3b6bb}.alert-dark .alert-link{color:#000}@-webkit-keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{background-color:#e5e7eb;border-radius:.25rem;font-size:.75rem;height:1rem;line-height:0}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{background-color:#4040c8;color:#fff;flex-direction:column;justify-content:center;text-align:center;transition:width .6s ease;white-space:nowrap}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{align-items:flex-start;display:flex}.media-body{flex:1}.list-group{border-radius:.25rem;display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.list-group-item-action{color:#374151;text-align:inherit;width:100%}.list-group-item-action:focus,.list-group-item-action:hover{background-color:#f3f4f6;color:#374151;text-decoration:none;z-index:1}.list-group-item-action:active{background-color:#e5e7eb;color:#111827}.list-group-item{background-color:#fff;border:1px solid rgba(0,0,0,.125);display:block;padding:.75rem 1.25rem;position:relative}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{background-color:#fff;color:#4b5563;pointer-events:none}.list-group-item.active{background-color:#4040c8;border-color:#4040c8;color:#fff;z-index:2}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{border-top-width:1px;margin-top:-1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}@media (min-width:2px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:8px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:9px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media (min-width:10px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{background-color:#cacaf0;color:#212168}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{background-color:#b6b6ea;color:#212168}.list-group-item-primary.list-group-item-action.active{background-color:#212168;border-color:#212168;color:#fff}.list-group-item-secondary{background-color:#cdcfd3;color:#272c33}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{background-color:#bfc2c7;color:#272c33}.list-group-item-secondary.list-group-item-action.active{background-color:#272c33;border-color:#272c33;color:#fff}.list-group-item-success{background-color:#b9e2d5;color:#034e37}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{background-color:#a7dbca;color:#034e37}.list-group-item-success.list-group-item-action.active{background-color:#034e37;border-color:#034e37;color:#fff}.list-group-item-info{background-color:#c2d3f9;color:#13337a}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{background-color:#abc2f7;color:#13337a}.list-group-item-info.list-group-item-action.active{background-color:#13337a;border-color:#13337a;color:#fff}.list-group-item-warning{background-color:#f4d9b9;color:#713e03}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{background-color:#f1cda3;color:#713e03}.list-group-item-warning.list-group-item-action.active{background-color:#713e03;border-color:#713e03;color:#fff}.list-group-item-danger{background-color:#f5c2c2;color:#721414}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{background-color:#f1acac;color:#721414}.list-group-item-danger.list-group-item-action.active{background-color:#721414;border-color:#721414;color:#fff}.list-group-item-light{background-color:#fcfcfc;color:#7e7f80}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{background-color:#efefef;color:#7e7f80}.list-group-item-light.list-group-item-action.active{background-color:#7e7f80;border-color:#7e7f80;color:#fff}.list-group-item-dark{background-color:#c0c3c7;color:#10151d}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{background-color:#b3b6bb;color:#10151d}.list-group-item-dark.list-group-item-action.active{background-color:#10151d;border-color:#10151d;color:#fff}.close{color:#000;float:right;font-size:1.5rem;font-weight:600;line-height:1;opacity:.5;text-shadow:0 1px 0 #fff}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{background-color:transparent;border:0;padding:0}a.close.disabled{pointer-events:none}.toast{background-clip:padding-box;background-color:hsla(0,0%,100%,.85);border:1px solid rgba(0,0,0,.1);border-radius:.25rem;box-shadow:0 .25rem .75rem rgba(0,0,0,.1);flex-basis:350px;font-size:.875rem;max-width:350px;opacity:0}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{align-items:center;background-clip:padding-box;background-color:hsla(0,0%,100%,.85);border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);color:#4b5563;display:flex;padding:.25rem .75rem}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{display:none;height:100%;left:0;outline:0;overflow:hidden;position:fixed;top:0;width:100%;z-index:1050}.modal-dialog{margin:.5rem;pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{content:"";display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;height:100%;justify-content:center}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{align-items:flex-start;border-bottom:1px solid #d1d5db;border-top-left-radius:5px;border-top-right-radius:5px;display:flex;justify-content:space-between;padding:1rem}.modal-header .close{margin:-1rem -1rem -1rem auto;padding:1rem}.modal-title{line-height:1.5;margin-bottom:0}.modal-body{flex:1 1 auto;padding:1rem;position:relative}.modal-footer{align-items:center;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:1px solid #d1d5db;display:flex;flex-wrap:wrap;justify-content:flex-end;padding:.75rem}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{height:50px;overflow:scroll;position:absolute;top:-9999px;width:50px}@media (min-width:2px){.modal-dialog{margin:1.75rem auto;max-width:500px}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:9px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:10px){.modal-xl{max-width:1140px}}.tooltip{word-wrap:break-word;display:block;font-family:Figtree,sans-serif;font-size:.875rem;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:0;opacity:0;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:1070}.tooltip.show{opacity:.9}.tooltip .arrow{display:block;height:.4rem;position:absolute;width:.8rem}.tooltip .arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{border-top-color:#000;border-width:.4rem .4rem 0;top:0}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{height:.8rem;left:0;width:.4rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{border-right-color:#000;border-width:.4rem .4rem .4rem 0;right:0}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{border-bottom-color:#000;border-width:0 .4rem .4rem;bottom:0}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{height:.8rem;right:0;width:.4rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{border-left-color:#000;border-width:.4rem 0 .4rem .4rem;left:0}.tooltip-inner{background-color:#000;border-radius:.25rem;color:#fff;max-width:200px;padding:.25rem .5rem;text-align:center}.popover{word-wrap:break-word;background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;font-family:Figtree,sans-serif;font-size:.875rem;font-style:normal;font-weight:400;left:0;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:276px;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;top:0;white-space:normal;word-break:normal;word-spacing:normal;z-index:1060}.popover,.popover .arrow{display:block;position:absolute}.popover .arrow{height:.5rem;margin:0 6px;width:1rem}.popover .arrow:after,.popover .arrow:before{border-color:transparent;border-style:solid;content:"";display:block;position:absolute}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{border-top-color:rgba(0,0,0,.25);border-width:.5rem .5rem 0;bottom:0}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{border-top-color:#fff;border-width:.5rem .5rem 0;bottom:1px}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{height:1rem;left:calc(-.5rem - 1px);margin:6px 0;width:.5rem}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{border-right-color:rgba(0,0,0,.25);border-width:.5rem .5rem .5rem 0;left:0}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{border-right-color:#fff;border-width:.5rem .5rem .5rem 0;left:1px}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{border-bottom-color:rgba(0,0,0,.25);border-width:0 .5rem .5rem;top:0}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{border-bottom-color:#fff;border-width:0 .5rem .5rem;top:1px}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{border-bottom:1px solid #f7f7f7;content:"";display:block;left:50%;margin-left:-.5rem;position:absolute;top:0;width:1rem}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{height:1rem;margin:6px 0;right:calc(-.5rem - 1px);width:.5rem}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{border-left-color:rgba(0,0,0,.25);border-width:.5rem 0 .5rem .5rem;right:0}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{border-left-color:#fff;border-width:.5rem 0 .5rem .5rem;right:1px}.popover-header{background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:5px;border-top-right-radius:5px;font-size:1rem;margin-bottom:0;padding:.5rem .75rem}.popover-header:empty{display:none}.popover-body{color:#111827;padding:.5rem .75rem}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{overflow:hidden;position:relative;width:100%}.carousel-inner:after{clear:both;content:"";display:block}.carousel-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1;z-index:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0;transition:opacity 0s .6s;z-index:0}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{align-items:center;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{background:50%/100% 100% no-repeat;display:inline-block;height:20px;width:20px}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m5.25 0-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m2.75 0-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;list-style:none;margin-left:15%;margin-right:15%;padding-left:0;position:absolute;right:0;z-index:15}.carousel-indicators li{background-clip:padding-box;background-color:#fff;border-bottom:10px solid transparent;border-top:10px solid transparent;box-sizing:content-box;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;text-indent:-999px;transition:opacity .6s ease;width:30px}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{bottom:20px;color:#fff;left:15%;padding-bottom:20px;padding-top:20px;position:absolute;right:15%;text-align:center;z-index:10}@-webkit-keyframes spinner-border{to{transform:rotate(1turn)}}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite;border:.25em solid;border-radius:50%;border-right:.25em solid transparent;display:inline-block;height:2rem;vertical-align:text-bottom;width:2rem}.spinner-border-sm{border-width:.2em;height:1rem;width:1rem}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite;background-color:currentColor;border-radius:50%;display:inline-block;height:2rem;opacity:0;vertical-align:text-bottom;width:2rem}.spinner-grow-sm{height:1rem;width:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#4040c8!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#3030a5!important}.bg-secondary{background-color:#4b5563!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#353c46!important}.bg-success{background-color:#059669!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#036546!important}.bg-info{background-color:#2563eb!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#134cca!important}.bg-warning{background-color:#d97706!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#a75c05!important}.bg-danger{background-color:#dc2626!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#b21d1d!important}.bg-light{background-color:#f3f4f6!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#d6d9e0!important}.bg-dark{background-color:#1f2937!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#0d1116!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #d1d5db!important}.border-top{border-top:1px solid #d1d5db!important}.border-right{border-right:1px solid #d1d5db!important}.border-bottom{border-bottom:1px solid #d1d5db!important}.border-left{border-left:1px solid #d1d5db!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#4040c8!important}.border-secondary{border-color:#4b5563!important}.border-success{border-color:#059669!important}.border-info{border-color:#2563eb!important}.border-warning{border-color:#d97706!important}.border-danger{border-color:#dc2626!important}.border-light{border-color:#f3f4f6!important}.border-dark{border-color:#1f2937!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:6px!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{clear:both;content:"";display:block}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:2px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:8px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:9px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:10px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{display:block;overflow:hidden;padding:0;position:relative;width:100%}.embed-responsive:before{content:"";display:block}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{border:0;bottom:0;height:100%;left:0;position:absolute;top:0;width:100%}.embed-responsive-21by9:before{padding-top:42.8571428571%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:2px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:8px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:9px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:10px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:2px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:8px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:9px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:10px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{left:0;position:fixed;right:0;z-index:1030}.fixed-bottom{bottom:0}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{clip:rect(0,0,0,0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;overflow:visible;position:static;white-space:normal;width:auto}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:2px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:8px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:9px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:10px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link:after{background-color:transparent;bottom:0;content:"";left:0;pointer-events:auto;position:absolute;right:0;top:0;z-index:1}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:2px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:8px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:9px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:10px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:600!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#4040c8!important}a.text-primary:focus,a.text-primary:hover{color:#2a2a92!important}.text-secondary{color:#4b5563!important}a.text-secondary:focus,a.text-secondary:hover{color:#2a3037!important}.text-success{color:#059669!important}a.text-success:focus,a.text-success:hover{color:#034c35!important}.text-info{color:#2563eb!important}a.text-info:focus,a.text-info:hover{color:#1043b3!important}.text-warning{color:#d97706!important}a.text-warning:focus,a.text-warning:hover{color:#8f4e04!important}.text-danger{color:#dc2626!important}a.text-danger:focus,a.text-danger:hover{color:#9c1919!important}.text-light{color:#f3f4f6!important}a.text-light:focus,a.text-light:hover{color:#c7ccd5!important}.text-dark{color:#1f2937!important}a.text-dark:focus,a.text-dark:hover{color:#030506!important}.text-body{color:#111827!important}.text-muted{color:#6b7280!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{background-color:transparent;border:0;color:transparent;font:0/0 a;text-shadow:none}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{box-shadow:none!important;text-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #6b7280;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:9px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #d1d5db!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#e5e7eb}.table .thead-dark th{border-color:#e5e7eb;color:inherit}}.vjs-tree{color:#bfc7d5!important;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.vjs-tree .vjs-tree__content{border-left:1px dotted hsla(0,0%,80%,.28)!important}.vjs-tree .vjs-tree__node{cursor:pointer}.vjs-tree .vjs-tree__node:hover{color:#20a0ff}.vjs-tree .vjs-checkbox{left:-30px;position:absolute}.vjs-tree .vjs-value__boolean,.vjs-tree .vjs-value__null,.vjs-tree .vjs-value__number{color:#a291f5!important}.vjs-tree .vjs-value__string{color:#c3e88d!important}.vjs-tree .vjs-key{color:#c3cbd3!important}.hljs-addition,.hljs-attr,.hljs-keyword,.hljs-selector-tag{color:#13ce66}.hljs-bullet,.hljs-meta,.hljs-name,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable{color:#c3e88d}.hljs-comment,.hljs-deletion,.hljs-quote{color:#bfcbd9}.hljs-literal,.hljs-number,.hljs-title{color:#a291f5!important}body{padding-bottom:20px}.container{max-width:1440px}html{min-width:1140px}[v-cloak]{display:none}svg.icon{height:1rem;width:1rem}.header{border-bottom:1px solid #e5e7eb}.header .logo{color:#374151;text-decoration:none}.header .logo svg{height:1.7rem;width:1.7rem}.sidebar .nav-item a{border-radius:6px;color:#4b5563;margin-bottom:4px;padding:.5rem .75rem}.sidebar .nav-item a svg{fill:#9ca3af;height:1.25rem;margin-right:15px;width:1.25rem}.sidebar .nav-item a.active,.sidebar .nav-item a:hover{background-color:#e5e7eb;color:#4040c8}.sidebar .nav-item a.active svg{fill:#4040c8}.card{border:none;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1)}.card .bottom-radius{border-bottom-left-radius:6px;border-bottom-right-radius:6px}.card .card-header{background-color:#fff;border-bottom:none;min-height:60px;padding-bottom:.7rem;padding-top:.7rem}.card .card-header .btn-group .btn{padding:.2rem .5rem}.card .card-header .form-control-with-icon{position:relative}.card .card-header .form-control-with-icon .icon-wrapper{jusify-content:center;align-items:center;bottom:0;display:flex;left:.75rem;position:absolute;top:0}.card .card-header .form-control-with-icon .icon-wrapper .icon{fill:#6b7280}.card .card-header .form-control-with-icon .form-control{border-radius:9999px;font-size:.875rem;padding-left:2.25rem}.card .table td,.card .table th{padding:.75rem 1.25rem}.card .table th{background-color:#f3f4f6;border-bottom:0;font-size:.875rem;padding:.5rem 1.25rem}.card .table:not(.table-borderless) td{border-top:1px solid #e5e7eb}.card .table.penultimate-column-right td:nth-last-child(2),.card .table.penultimate-column-right th:nth-last-child(2){text-align:right}.card .table td.table-fit,.card .table th.table-fit{white-space:nowrap;width:1%}.fill-text-color{fill:#111827}.fill-danger{fill:#dc2626}.fill-warning{fill:#d97706}.fill-info{fill:#2563eb}.fill-success{fill:#059669}.fill-primary{fill:#4040c8}button:hover .fill-primary{fill:#fff}.btn-outline-primary.active .fill-primary{fill:#f3f4f6}.btn-outline-primary:not(:disabled):not(.disabled).active:focus{box-shadow:none!important}.btn-muted{background:#e5e7eb;color:#4b5563}.btn-muted:focus,.btn-muted:hover{background:#d1d5db;color:#111827}.btn-muted.active{background:#4040c8;color:#fff}.badge-secondary{background:#e5e7eb;color:#4b5563}.badge-success{background:#d1fae5;color:#059669}.badge-info{background:#dbeafe;color:#2563eb}.badge-warning{background:#fef3c7;color:#d97706}.badge-danger{background:#fee2e2;color:#dc2626}.control-action svg{fill:#d1d5db;height:1.2rem;width:1.2rem}.control-action svg:hover{fill:#4f46e5}@-webkit-keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.spin{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.card .nav-pills{background:#fff}.card .nav-pills .nav-link{border-radius:0;color:#4b5563;font-size:.9rem;padding:.75rem 1.25rem}.card .nav-pills .nav-link:focus,.card .nav-pills .nav-link:hover{color:#1f2937}.card .nav-pills .nav-link.active{background:none;border-bottom:2px solid #4f46e5;color:#4f46e5}.list-enter-active:not(.dontanimate){transition:background 1s linear}.list-enter:not(.dontanimate),.list-leave-to:not(.dontanimate){background:#eef2ff}.code-bg .list-enter:not(.dontanimate),.code-bg .list-leave-to:not(.dontanimate){background:#4b5563}#indexScreen td{vertical-align:middle!important}.card-bg-secondary{background:#f3f4f6}.code-bg{background:#292d3e}.disabled-watcher{background:#dc2626;color:#fff;padding:.75rem} diff --git a/public/vendor/telescope/app.js b/public/vendor/telescope/app.js new file mode 100644 index 0000000..b4c697e --- /dev/null +++ b/public/vendor/telescope/app.js @@ -0,0 +1,2 @@ +/*! For license information please see app.js.LICENSE.txt */ +(()=>{var e,t={9669:(e,t,n)=>{e.exports=n(1609)},5448:(e,t,n)=>{"use strict";var r=n(4867),o=n(6026),i=n(4372),a=n(5327),c=n(4097),s=n(4109),l=n(7985),u=n(5061);e.exports=function(e){return new Promise((function(t,n){var f=e.data,d=e.headers,p=e.responseType;r.isFormData(f)&&delete d["Content-Type"];var h=new XMLHttpRequest;if(e.auth){var M=e.auth.username||"",v=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";d.Authorization="Basic "+btoa(M+":"+v)}var b=c(e.baseURL,e.url);function m(){if(h){var r="getAllResponseHeaders"in h?s(h.getAllResponseHeaders()):null,i={data:p&&"text"!==p&&"json"!==p?h.response:h.responseText,status:h.status,statusText:h.statusText,headers:r,config:e,request:h};o(t,n,i),h=null}}if(h.open(e.method.toUpperCase(),a(b,e.params,e.paramsSerializer),!0),h.timeout=e.timeout,"onloadend"in h?h.onloadend=m:h.onreadystatechange=function(){h&&4===h.readyState&&(0!==h.status||h.responseURL&&0===h.responseURL.indexOf("file:"))&&setTimeout(m)},h.onabort=function(){h&&(n(u("Request aborted",e,"ECONNABORTED",h)),h=null)},h.onerror=function(){n(u("Network Error",e,null,h)),h=null},h.ontimeout=function(){var t="timeout of "+e.timeout+"ms exceeded";e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(u(t,e,e.transitional&&e.transitional.clarifyTimeoutError?"ETIMEDOUT":"ECONNABORTED",h)),h=null},r.isStandardBrowserEnv()){var g=(e.withCredentials||l(b))&&e.xsrfCookieName?i.read(e.xsrfCookieName):void 0;g&&(d[e.xsrfHeaderName]=g)}"setRequestHeader"in h&&r.forEach(d,(function(e,t){void 0===f&&"content-type"===t.toLowerCase()?delete d[t]:h.setRequestHeader(t,e)})),r.isUndefined(e.withCredentials)||(h.withCredentials=!!e.withCredentials),p&&"json"!==p&&(h.responseType=e.responseType),"function"==typeof e.onDownloadProgress&&h.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&h.upload&&h.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then((function(e){h&&(h.abort(),n(e),h=null)})),f||(f=null),h.send(f)}))}},1609:(e,t,n)=>{"use strict";var r=n(4867),o=n(1849),i=n(321),a=n(7185);function c(e){var t=new i(e),n=o(i.prototype.request,t);return r.extend(n,i.prototype,t),r.extend(n,t),n}var s=c(n(5655));s.Axios=i,s.create=function(e){return c(a(s.defaults,e))},s.Cancel=n(5263),s.CancelToken=n(4972),s.isCancel=n(6502),s.all=function(e){return Promise.all(e)},s.spread=n(8713),s.isAxiosError=n(6268),e.exports=s,e.exports.default=s},5263:e=>{"use strict";function t(e){this.message=e}t.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},t.prototype.__CANCEL__=!0,e.exports=t},4972:(e,t,n)=>{"use strict";var r=n(5263);function o(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise((function(e){t=e}));var n=this;e((function(e){n.reason||(n.reason=new r(e),t(n.reason))}))}o.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},o.source=function(){var e;return{token:new o((function(t){e=t})),cancel:e}},e.exports=o},6502:e=>{"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},321:(e,t,n)=>{"use strict";var r=n(4867),o=n(5327),i=n(782),a=n(3572),c=n(7185),s=n(4875),l=s.validators;function u(e){this.defaults=e,this.interceptors={request:new i,response:new i}}u.prototype.request=function(e){"string"==typeof e?(e=arguments[1]||{}).url=arguments[0]:e=e||{},(e=c(this.defaults,e)).method?e.method=e.method.toLowerCase():this.defaults.method?e.method=this.defaults.method.toLowerCase():e.method="get";var t=e.transitional;void 0!==t&&s.assertOptions(t,{silentJSONParsing:l.transitional(l.boolean,"1.0.0"),forcedJSONParsing:l.transitional(l.boolean,"1.0.0"),clarifyTimeoutError:l.transitional(l.boolean,"1.0.0")},!1);var n=[],r=!0;this.interceptors.request.forEach((function(t){"function"==typeof t.runWhen&&!1===t.runWhen(e)||(r=r&&t.synchronous,n.unshift(t.fulfilled,t.rejected))}));var o,i=[];if(this.interceptors.response.forEach((function(e){i.push(e.fulfilled,e.rejected)})),!r){var u=[a,void 0];for(Array.prototype.unshift.apply(u,n),u.concat(i),o=Promise.resolve(e);u.length;)o=o.then(u.shift(),u.shift());return o}for(var f=e;n.length;){var d=n.shift(),p=n.shift();try{f=d(f)}catch(e){p(e);break}}try{o=a(f)}catch(e){return Promise.reject(e)}for(;i.length;)o=o.then(i.shift(),i.shift());return o},u.prototype.getUri=function(e){return e=c(this.defaults,e),o(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},r.forEach(["delete","get","head","options"],(function(e){u.prototype[e]=function(t,n){return this.request(c(n||{},{method:e,url:t,data:(n||{}).data}))}})),r.forEach(["post","put","patch"],(function(e){u.prototype[e]=function(t,n,r){return this.request(c(r||{},{method:e,url:t,data:n}))}})),e.exports=u},782:(e,t,n)=>{"use strict";var r=n(4867);function o(){this.handlers=[]}o.prototype.use=function(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1},o.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},o.prototype.forEach=function(e){r.forEach(this.handlers,(function(t){null!==t&&e(t)}))},e.exports=o},4097:(e,t,n)=>{"use strict";var r=n(1793),o=n(7303);e.exports=function(e,t){return e&&!r(t)?o(e,t):t}},5061:(e,t,n)=>{"use strict";var r=n(481);e.exports=function(e,t,n,o,i){var a=new Error(e);return r(a,t,n,o,i)}},3572:(e,t,n)=>{"use strict";var r=n(4867),o=n(8527),i=n(6502),a=n(5655);function c(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(e){return c(e),e.headers=e.headers||{},e.data=o.call(e,e.data,e.headers,e.transformRequest),e.headers=r.merge(e.headers.common||{},e.headers[e.method]||{},e.headers),r.forEach(["delete","get","head","post","put","patch","common"],(function(t){delete e.headers[t]})),(e.adapter||a.adapter)(e).then((function(t){return c(e),t.data=o.call(e,t.data,t.headers,e.transformResponse),t}),(function(t){return i(t)||(c(e),t&&t.response&&(t.response.data=o.call(e,t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)}))}},481:e=>{"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},7185:(e,t,n)=>{"use strict";var r=n(4867);e.exports=function(e,t){t=t||{};var n={},o=["url","method","data"],i=["headers","auth","proxy","params"],a=["baseURL","transformRequest","transformResponse","paramsSerializer","timeout","timeoutMessage","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","decompress","maxContentLength","maxBodyLength","maxRedirects","transport","httpAgent","httpsAgent","cancelToken","socketPath","responseEncoding"],c=["validateStatus"];function s(e,t){return r.isPlainObject(e)&&r.isPlainObject(t)?r.merge(e,t):r.isPlainObject(t)?r.merge({},t):r.isArray(t)?t.slice():t}function l(o){r.isUndefined(t[o])?r.isUndefined(e[o])||(n[o]=s(void 0,e[o])):n[o]=s(e[o],t[o])}r.forEach(o,(function(e){r.isUndefined(t[e])||(n[e]=s(void 0,t[e]))})),r.forEach(i,l),r.forEach(a,(function(o){r.isUndefined(t[o])?r.isUndefined(e[o])||(n[o]=s(void 0,e[o])):n[o]=s(void 0,t[o])})),r.forEach(c,(function(r){r in t?n[r]=s(e[r],t[r]):r in e&&(n[r]=s(void 0,e[r]))}));var u=o.concat(i).concat(a).concat(c),f=Object.keys(e).concat(Object.keys(t)).filter((function(e){return-1===u.indexOf(e)}));return r.forEach(f,l),n}},6026:(e,t,n)=>{"use strict";var r=n(5061);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},8527:(e,t,n)=>{"use strict";var r=n(4867),o=n(5655);e.exports=function(e,t,n){var i=this||o;return r.forEach(n,(function(n){e=n.call(i,e,t)})),e}},5655:(e,t,n)=>{"use strict";var r=n(4155),o=n(4867),i=n(6016),a=n(481),c={"Content-Type":"application/x-www-form-urlencoded"};function s(e,t){!o.isUndefined(e)&&o.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}var l,u={transitional:{silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},adapter:(("undefined"!=typeof XMLHttpRequest||void 0!==r&&"[object process]"===Object.prototype.toString.call(r))&&(l=n(5448)),l),transformRequest:[function(e,t){return i(t,"Accept"),i(t,"Content-Type"),o.isFormData(e)||o.isArrayBuffer(e)||o.isBuffer(e)||o.isStream(e)||o.isFile(e)||o.isBlob(e)?e:o.isArrayBufferView(e)?e.buffer:o.isURLSearchParams(e)?(s(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):o.isObject(e)||t&&"application/json"===t["Content-Type"]?(s(t,"application/json"),JSON.stringify(e)):e}],transformResponse:[function(e){var t=this.transitional,n=t&&t.silentJSONParsing,r=t&&t.forcedJSONParsing,i=!n&&"json"===this.responseType;if(i||r&&o.isString(e)&&e.length)try{return JSON.parse(e)}catch(e){if(i){if("SyntaxError"===e.name)throw a(e,this,"E_JSON_PARSE");throw e}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,validateStatus:function(e){return e>=200&&e<300}};u.headers={common:{Accept:"application/json, text/plain, */*"}},o.forEach(["delete","get","head"],(function(e){u.headers[e]={}})),o.forEach(["post","put","patch"],(function(e){u.headers[e]=o.merge(c)})),e.exports=u},1849:e=>{"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r{"use strict";var r=n(4867);function o(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(r.isURLSearchParams(t))i=t.toString();else{var a=[];r.forEach(t,(function(e,t){null!=e&&(r.isArray(e)?t+="[]":e=[e],r.forEach(e,(function(e){r.isDate(e)?e=e.toISOString():r.isObject(e)&&(e=JSON.stringify(e)),a.push(o(t)+"="+o(e))})))})),i=a.join("&")}if(i){var c=e.indexOf("#");-1!==c&&(e=e.slice(0,c)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}},7303:e=>{"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},4372:(e,t,n)=>{"use strict";var r=n(4867);e.exports=r.isStandardBrowserEnv()?{write:function(e,t,n,o,i,a){var c=[];c.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&c.push("expires="+new Date(n).toGMTString()),r.isString(o)&&c.push("path="+o),r.isString(i)&&c.push("domain="+i),!0===a&&c.push("secure"),document.cookie=c.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},1793:e=>{"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},6268:e=>{"use strict";e.exports=function(e){return"object"==typeof e&&!0===e.isAxiosError}},7985:(e,t,n)=>{"use strict";var r=n(4867);e.exports=r.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function o(e){var r=e;return t&&(n.setAttribute("href",r),r=n.href),n.setAttribute("href",r),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return e=o(window.location.href),function(t){var n=r.isString(t)?o(t):t;return n.protocol===e.protocol&&n.host===e.host}}():function(){return!0}},6016:(e,t,n)=>{"use strict";var r=n(4867);e.exports=function(e,t){r.forEach(e,(function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])}))}},4109:(e,t,n)=>{"use strict";var r=n(4867),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,a={};return e?(r.forEach(e.split("\n"),(function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(a[t]&&o.indexOf(t)>=0)return;a[t]="set-cookie"===t?(a[t]?a[t]:[]).concat([n]):a[t]?a[t]+", "+n:n}})),a):a}},8713:e=>{"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},4875:(e,t,n)=>{"use strict";var r=n(8593),o={};["object","boolean","number","function","string","symbol"].forEach((function(e,t){o[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));var i={},a=r.version.split(".");function c(e,t){for(var n=t?t.split("."):a,r=e.split("."),o=0;o<3;o++){if(n[o]>r[o])return!0;if(n[o]0;){var i=r[o],a=t[i];if(a){var c=e[i],s=void 0===c||a(c,i,e);if(!0!==s)throw new TypeError("option "+i+" must be "+s)}else if(!0!==n)throw Error("Unknown option "+i)}},validators:o}},4867:(e,t,n)=>{"use strict";var r=n(1849),o=Object.prototype.toString;function i(e){return"[object Array]"===o.call(e)}function a(e){return void 0===e}function c(e){return null!==e&&"object"==typeof e}function s(e){if("[object Object]"!==o.call(e))return!1;var t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}function l(e){return"[object Function]"===o.call(e)}function u(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),i(e))for(var n=0,r=e.length;n{"use strict";var r=Object.freeze({});function o(e){return null==e}function i(e){return null!=e}function a(e){return!0===e}function c(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function s(e){return null!==e&&"object"==typeof e}var l=Object.prototype.toString;function u(e){return"[object Object]"===l.call(e)}function f(e){return"[object RegExp]"===l.call(e)}function d(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function p(e){return i(e)&&"function"==typeof e.then&&"function"==typeof e.catch}function h(e){return null==e?"":Array.isArray(e)||u(e)&&e.toString===l?JSON.stringify(e,null,2):String(e)}function M(e){var t=parseFloat(e);return isNaN(t)?e:t}function v(e,t){for(var n=Object.create(null),r=e.split(","),o=0;o-1)return e.splice(n,1)}}var A=Object.prototype.hasOwnProperty;function _(e,t){return A.call(e,t)}function y(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}var E=/-(\w)/g,T=y((function(e){return e.replace(E,(function(e,t){return t?t.toUpperCase():""}))})),O=y((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),N=/\B([A-Z])/g,z=y((function(e){return e.replace(N,"-$1").toLowerCase()}));var L=Function.prototype.bind?function(e,t){return e.bind(t)}:function(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n};function C(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function w(e,t){for(var n in t)e[n]=t[n];return e}function S(e){for(var t={},n=0;n0,ee=Z&&Z.indexOf("edge/")>0,te=(Z&&Z.indexOf("android"),Z&&/iphone|ipad|ipod|ios/.test(Z)||"ios"===K),ne=(Z&&/chrome\/\d+/.test(Z),Z&&/phantomjs/.test(Z),Z&&Z.match(/firefox\/(\d+)/)),re={}.watch,oe=!1;if(V)try{var ie={};Object.defineProperty(ie,"passive",{get:function(){oe=!0}}),window.addEventListener("test-passive",null,ie)}catch(e){}var ae=function(){return void 0===$&&($=!V&&!Y&&void 0!==n.g&&(n.g.process&&"server"===n.g.process.env.VUE_ENV)),$},ce=V&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function se(e){return"function"==typeof e&&/native code/.test(e.toString())}var le,ue="undefined"!=typeof Symbol&&se(Symbol)&&"undefined"!=typeof Reflect&&se(Reflect.ownKeys);le="undefined"!=typeof Set&&se(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var fe=R,de=0,pe=function(){this.id=de++,this.subs=[]};pe.prototype.addSub=function(e){this.subs.push(e)},pe.prototype.removeSub=function(e){g(this.subs,e)},pe.prototype.depend=function(){pe.target&&pe.target.addDep(this)},pe.prototype.notify=function(){var e=this.subs.slice();for(var t=0,n=e.length;t-1)if(i&&!_(o,"default"))a=!1;else if(""===a||a===z(e)){var s=He(String,o.type);(s<0||c0&&(ht((r=Mt(r,(t||"")+"_"+n))[0])&&ht(l)&&(u[s]=Ae(l.text+r[0].text),r.shift()),u.push.apply(u,r)):c(r)?ht(l)?u[s]=Ae(l.text+r):""!==r&&u.push(Ae(r)):ht(r)&&ht(l)?u[s]=Ae(l.text+r.text):(a(e._isVList)&&i(r.tag)&&o(r.key)&&i(t)&&(r.key="__vlist"+t+"_"+n+"__"),u.push(r)));return u}function vt(e,t){if(e){for(var n=Object.create(null),r=ue?Reflect.ownKeys(e):Object.keys(e),o=0;o0,a=e?!!e.$stable:!i,c=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(a&&n&&n!==r&&c===n.$key&&!i&&!n.$hasNormal)return n;for(var s in o={},e)e[s]&&"$"!==s[0]&&(o[s]=At(t,s,e[s]))}else o={};for(var l in t)l in o||(o[l]=_t(t,l));return e&&Object.isExtensible(e)&&(e._normalized=o),H(o,"$stable",a),H(o,"$key",c),H(o,"$hasNormal",i),o}function At(e,t,n){var r=function(){var e=arguments.length?n.apply(null,arguments):n({});return(e=e&&"object"==typeof e&&!Array.isArray(e)?[e]:pt(e))&&(0===e.length||1===e.length&&e[0].isComment)?void 0:e};return n.proxy&&Object.defineProperty(e,t,{get:r,enumerable:!0,configurable:!0}),r}function _t(e,t){return function(){return e[t]}}function yt(e,t){var n,r,o,a,c;if(Array.isArray(e)||"string"==typeof e)for(n=new Array(e.length),r=0,o=e.length;rdocument.createEvent("Event").timeStamp&&(Mn=function(){return vn.now()})}function bn(){var e,t;for(hn=Mn(),dn=!0,sn.sort((function(e,t){return e.id-t.id})),pn=0;pnpn&&sn[n].id>e.id;)n--;sn.splice(n+1,0,e)}else sn.push(e);fn||(fn=!0,ot(bn))}}(this)},gn.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||s(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Fe(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},gn.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},gn.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},gn.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||g(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var An={enumerable:!0,configurable:!0,get:R,set:R};function _n(e,t,n){An.get=function(){return this[t][n]},An.set=function(e){this[t][n]=e},Object.defineProperty(e,n,An)}function yn(e){e._watchers=[];var t=e.$options;t.props&&function(e,t){var n=e.$options.propsData||{},r=e._props={},o=e.$options._propKeys=[];e.$parent&&Ne(!1);var i=function(i){o.push(i);var a=Pe(i,t,n,e);Ce(r,i,a),i in e||_n(e,"_props",i)};for(var a in t)i(a);Ne(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]="function"!=typeof t[n]?R:L(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;u(t=e._data="function"==typeof t?function(e,t){Me();try{return e.call(t,t)}catch(e){return Fe(e,t,"data()"),{}}finally{ve()}}(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,o=(e.$options.methods,n.length);for(;o--;){var i=n[o];0,r&&_(r,i)||U(i)||_n(e,"_data",i)}Le(t,!0)}(e):Le(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=ae();for(var o in t){var i=t[o],a="function"==typeof i?i:i.get;0,r||(n[o]=new gn(e,a||R,R,En)),o in e||Tn(e,o,i)}}(e,t.computed),t.watch&&t.watch!==re&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var o=0;o-1:"string"==typeof e?e.split(",").indexOf(t)>-1:!!f(e)&&e.test(t)}function qn(e,t){var n=e.cache,r=e.keys,o=e._vnode;for(var i in n){var a=n[i];if(a){var c=Rn(a.componentOptions);c&&!t(c)&&Wn(n,i,r,o)}}}function Wn(e,t,n,r){var o=e[t];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),e[t]=null,g(n,t)}!function(e){e.prototype._init=function(e){var t=this;t._uid=Ln++,t._isVue=!0,e&&e._isComponent?function(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}(t,e):t.$options=De(Cn(t.constructor),e||{},t),t._renderProxy=t,t._self=t,function(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}(t),function(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&en(e,t)}(t),function(e){e._vnode=null,e._staticTrees=null;var t=e.$options,n=e.$vnode=t._parentVnode,o=n&&n.context;e.$slots=bt(t._renderChildren,o),e.$scopedSlots=r,e._c=function(t,n,r,o){return Ht(e,t,n,r,o,!1)},e.$createElement=function(t,n,r,o){return Ht(e,t,n,r,o,!0)};var i=n&&n.data;Ce(e,"$attrs",i&&i.attrs||r,null,!0),Ce(e,"$listeners",t._parentListeners||r,null,!0)}(t),cn(t,"beforeCreate"),function(e){var t=vt(e.$options.inject,e);t&&(Ne(!1),Object.keys(t).forEach((function(n){Ce(e,n,t[n])})),Ne(!0))}(t),yn(t),function(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}(t),cn(t,"created"),t.$options.el&&t.$mount(t.$options.el)}}(wn),function(e){var t={get:function(){return this._data}},n={get:function(){return this._props}};Object.defineProperty(e.prototype,"$data",t),Object.defineProperty(e.prototype,"$props",n),e.prototype.$set=we,e.prototype.$delete=Se,e.prototype.$watch=function(e,t,n){var r=this;if(u(t))return zn(r,e,t,n);(n=n||{}).user=!0;var o=new gn(r,e,t,n);if(n.immediate)try{t.call(r,o.value)}catch(e){Fe(e,r,'callback for immediate watcher "'+o.expression+'"')}return function(){o.teardown()}}}(wn),function(e){var t=/^hook:/;e.prototype.$on=function(e,n){var r=this;if(Array.isArray(e))for(var o=0,i=e.length;o1?C(n):n;for(var r=C(arguments,1),o='event handler for "'+e+'"',i=0,a=n.length;iparseInt(this.max)&&Wn(a,c[0],c,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};!function(e){var t={get:function(){return P}};Object.defineProperty(e,"config",t),e.util={warn:fe,extend:w,mergeOptions:De,defineReactive:Ce},e.set=we,e.delete=Se,e.nextTick=ot,e.observable=function(e){return Le(e),e},e.options=Object.create(null),D.forEach((function(t){e.options[t+"s"]=Object.create(null)})),e.options._base=e,w(e.options.components,Bn),function(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=C(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this}}(e),function(e){e.mixin=function(e){return this.options=De(this.options,e),this}}(e),Sn(e),function(e){D.forEach((function(t){e[t]=function(e,n){return n?("component"===t&&u(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"==typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}}))}(e)}(wn),Object.defineProperty(wn.prototype,"$isServer",{get:ae}),Object.defineProperty(wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(wn,"FunctionalRenderContext",{value:Bt}),wn.version="2.6.12";var In=v("style,class"),Dn=v("input,textarea,option,select,progress"),Xn=function(e,t,n){return"value"===n&&Dn(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},Pn=v("contenteditable,draggable,spellcheck"),jn=v("events,caret,typing,plaintext-only"),Un=v("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),Hn="http://www.w3.org/1999/xlink",Fn=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},$n=function(e){return Fn(e)?e.slice(6,e.length):""},Gn=function(e){return null==e||!1===e};function Vn(e){for(var t=e.data,n=e,r=e;i(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(t=Yn(r.data,t));for(;i(n=n.parent);)n&&n.data&&(t=Yn(t,n.data));return function(e,t){if(i(e)||i(t))return Kn(e,Zn(t));return""}(t.staticClass,t.class)}function Yn(e,t){return{staticClass:Kn(e.staticClass,t.staticClass),class:i(e.class)?[e.class,t.class]:t.class}}function Kn(e,t){return e?t?e+" "+t:e:t||""}function Zn(e){return Array.isArray(e)?function(e){for(var t,n="",r=0,o=e.length;r-1?yr(e,t,n):Un(t)?Gn(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):Pn(t)?e.setAttribute(t,function(e,t){return Gn(t)||"false"===t?"false":"contenteditable"===e&&jn(t)?t:"true"}(t,n)):Fn(t)?Gn(n)?e.removeAttributeNS(Hn,$n(t)):e.setAttributeNS(Hn,t,n):yr(e,t,n)}function yr(e,t,n){if(Gn(n))e.removeAttribute(t);else{if(Q&&!J&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var r=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",r)};e.addEventListener("input",r),e.__ieph=!0}e.setAttribute(t,n)}}var Er={create:Ar,update:Ar};function Tr(e,t){var n=t.elm,r=t.data,a=e.data;if(!(o(r.staticClass)&&o(r.class)&&(o(a)||o(a.staticClass)&&o(a.class)))){var c=Vn(t),s=n._transitionClasses;i(s)&&(c=Kn(c,Zn(s))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Or,Nr,zr,Lr,Cr,wr,Sr={create:Tr,update:Tr},Rr=/[\w).+\-_$\]]/;function xr(e){var t,n,r,o,i,a=!1,c=!1,s=!1,l=!1,u=0,f=0,d=0,p=0;for(r=0;r=0&&" "===(M=e.charAt(h));h--);M&&Rr.test(M)||(l=!0)}}else void 0===o?(p=r+1,o=e.slice(0,r).trim()):v();function v(){(i||(i=[])).push(e.slice(p,r).trim()),p=r+1}if(void 0===o?o=e.slice(0,r).trim():0!==p&&v(),i)for(r=0;r-1?{exp:e.slice(0,Lr),key:'"'+e.slice(Lr+1)+'"'}:{exp:e,key:null};Nr=e,Lr=Cr=wr=0;for(;!Kr();)Zr(zr=Yr())?Jr(zr):91===zr&&Qr(zr);return{exp:e.slice(0,Cr),key:e.slice(Cr+1,wr)}}(e);return null===n.key?e+"="+t:"$set("+n.exp+", "+n.key+", "+t+")"}function Yr(){return Nr.charCodeAt(++Lr)}function Kr(){return Lr>=Or}function Zr(e){return 34===e||39===e}function Qr(e){var t=1;for(Cr=Lr;!Kr();)if(Zr(e=Yr()))Jr(e);else if(91===e&&t++,93===e&&t--,0===t){wr=Lr;break}}function Jr(e){for(var t=e;!Kr()&&(e=Yr())!==t;);}var eo,to="__r";function no(e,t,n){var r=eo;return function o(){var i=t.apply(null,arguments);null!==i&&io(e,o,n,r)}}var ro=Ke&&!(ne&&Number(ne[1])<=53);function oo(e,t,n,r){if(ro){var o=hn,i=t;t=i._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=o||e.timeStamp<=0||e.target.ownerDocument!==document)return i.apply(this,arguments)}}eo.addEventListener(e,t,oe?{capture:n,passive:r}:n)}function io(e,t,n,r){(r||eo).removeEventListener(e,t._wrapper||t,n)}function ao(e,t){if(!o(e.data.on)||!o(t.data.on)){var n=t.data.on||{},r=e.data.on||{};eo=t.elm,function(e){if(i(e.__r)){var t=Q?"change":"input";e[t]=[].concat(e.__r,e[t]||[]),delete e.__r}i(e.__c)&&(e.change=[].concat(e.__c,e.change||[]),delete e.__c)}(n),ut(n,r,oo,io,no,t.context),eo=void 0}}var co,so={create:ao,update:ao};function lo(e,t){if(!o(e.data.domProps)||!o(t.data.domProps)){var n,r,a=t.elm,c=e.data.domProps||{},s=t.data.domProps||{};for(n in i(s.__ob__)&&(s=t.data.domProps=w({},s)),c)n in s||(a[n]="");for(n in s){if(r=s[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),r===c[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=r;var l=o(r)?"":String(r);uo(a,l)&&(a.value=l)}else if("innerHTML"===n&&er(a.tagName)&&o(a.innerHTML)){(co=co||document.createElement("div")).innerHTML=""+r+"";for(var u=co.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;u.firstChild;)a.appendChild(u.firstChild)}else if(r!==c[n])try{a[n]=r}catch(e){}}}}function uo(e,t){return!e.composing&&("OPTION"===e.tagName||function(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}(e,t)||function(e,t){var n=e.value,r=e._vModifiers;if(i(r)){if(r.number)return M(n)!==M(t);if(r.trim)return n.trim()!==t.trim()}return n!==t}(e,t))}var fo={create:lo,update:lo},po=y((function(e){var t={},n=/:(.+)/;return e.split(/;(?![^(]*\))/g).forEach((function(e){if(e){var r=e.split(n);r.length>1&&(t[r[0].trim()]=r[1].trim())}})),t}));function ho(e){var t=Mo(e.style);return e.staticStyle?w(e.staticStyle,t):t}function Mo(e){return Array.isArray(e)?S(e):"string"==typeof e?po(e):e}var vo,bo=/^--/,mo=/\s*!important$/,go=function(e,t,n){if(bo.test(t))e.style.setProperty(t,n);else if(mo.test(n))e.style.setProperty(z(t),n.replace(mo,""),"important");else{var r=_o(t);if(Array.isArray(n))for(var o=0,i=n.length;o-1?t.split(To).forEach((function(t){return e.classList.add(t)})):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function No(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(To).forEach((function(t){return e.classList.remove(t)})):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" "+(e.getAttribute("class")||"")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?e.setAttribute("class",n):e.removeAttribute("class")}}function zo(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&w(t,Lo(e.name||"v")),w(t,e),t}return"string"==typeof e?Lo(e):void 0}}var Lo=y((function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}})),Co=V&&!J,wo="transition",So="animation",Ro="transition",xo="transitionend",qo="animation",Wo="animationend";Co&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Ro="WebkitTransition",xo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(qo="WebkitAnimation",Wo="webkitAnimationEnd"));var ko=V?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function Bo(e){ko((function(){ko(e)}))}function Io(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),Oo(e,t))}function Do(e,t){e._transitionClasses&&g(e._transitionClasses,t),No(e,t)}function Xo(e,t,n){var r=jo(e,t),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var c=o===wo?xo:Wo,s=0,l=function(){e.removeEventListener(c,u),n()},u=function(t){t.target===e&&++s>=a&&l()};setTimeout((function(){s0&&(n=wo,u=a,f=i.length):t===So?l>0&&(n=So,u=l,f=s.length):f=(n=(u=Math.max(a,l))>0?a>l?wo:So:null)?n===wo?i.length:s.length:0,{type:n,timeout:u,propCount:f,hasTransform:n===wo&&Po.test(r[Ro+"Property"])}}function Uo(e,t){for(;e.length1}function Yo(e,t){!0!==t.data.show&&Fo(t)}var Ko=function(e){var t,n,r={},s=e.modules,l=e.nodeOps;for(t=0;th?g(e,o(n[b+1])?null:n[b+1].elm,n,p,b,r):p>b&&_(t,d,h)}(d,v,b,n,u):i(b)?(i(e.text)&&l.setTextContent(d,""),g(d,null,b,0,b.length-1,n)):i(v)?_(v,0,v.length-1):i(e.text)&&l.setTextContent(d,""):e.text!==t.text&&l.setTextContent(d,t.text),i(h)&&i(p=h.hook)&&i(p=p.postpatch)&&p(e,t)}}}function O(e,t,n){if(a(n)&&i(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(W(ti(a),r))return void(e.selectedIndex!==c&&(e.selectedIndex=c));o||(e.selectedIndex=-1)}}function ei(e,t){return t.every((function(t){return!W(t,e)}))}function ti(e){return"_value"in e?e._value:e.value}function ni(e){e.target.composing=!0}function ri(e){e.target.composing&&(e.target.composing=!1,oi(e.target,"input"))}function oi(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function ii(e){return!e.componentInstance||e.data&&e.data.transition?e:ii(e.componentInstance._vnode)}var ai={bind:function(e,t,n){var r=t.value,o=(n=ii(n)).data&&n.data.transition,i=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;r&&o?(n.data.show=!0,Fo(n,(function(){e.style.display=i}))):e.style.display=r?i:"none"},update:function(e,t,n){var r=t.value;!r!=!t.oldValue&&((n=ii(n)).data&&n.data.transition?(n.data.show=!0,r?Fo(n,(function(){e.style.display=e.__vOriginalDisplay})):$o(n,(function(){e.style.display="none"}))):e.style.display=r?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,r,o){o||(e.style.display=e.__vOriginalDisplay)}},ci={model:Zo,show:ai},si={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function li(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?li(Kt(t.children)):e}function ui(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var o=n._parentListeners;for(var i in o)t[T(i)]=o[i];return t}function fi(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var di=function(e){return e.tag||Yt(e)},pi=function(e){return"show"===e.name},hi={name:"transition",props:si,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(di)).length){0;var r=this.mode;0;var o=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return o;var i=li(o);if(!i)return o;if(this._leaving)return fi(e,o);var a="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?a+"comment":a+i.tag:c(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s=(i.data||(i.data={})).transition=ui(this),l=this._vnode,u=li(l);if(i.data.directives&&i.data.directives.some(pi)&&(i.data.show=!0),u&&u.data&&!function(e,t){return t.key===e.key&&t.tag===e.tag}(i,u)&&!Yt(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var f=u.data.transition=w({},s);if("out-in"===r)return this._leaving=!0,ft(f,"afterLeave",(function(){t._leaving=!1,t.$forceUpdate()})),fi(e,o);if("in-out"===r){if(Yt(i))return l;var d,p=function(){d()};ft(s,"afterEnter",p),ft(s,"enterCancelled",p),ft(f,"delayLeave",(function(e){d=e}))}}return o}}},Mi=w({tag:String,moveClass:String},si);delete Mi.mode;var vi={props:Mi,beforeMount:function(){var e=this,t=this._update;this._update=function(n,r){var o=nn(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,o(),t.call(e,n,r)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=ui(this),c=0;c-1?rr[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:rr[e]=/HTMLUnknownElement/.test(t.toString())},w(wn.options.directives,ci),w(wn.options.components,Ai),wn.prototype.__patch__=V?Ko:R,wn.prototype.$mount=function(e,t){return function(e,t,n){var r;return e.$el=t,e.$options.render||(e.$options.render=ge),cn(e,"beforeMount"),r=function(){e._update(e._render(),n)},new gn(e,r,R,{before:function(){e._isMounted&&!e._isDestroyed&&cn(e,"beforeUpdate")}},!0),n=!1,null==e.$vnode&&(e._isMounted=!0,cn(e,"mounted")),e}(this,e=e&&V?ir(e):void 0,t)},V&&setTimeout((function(){P.devtools&&ce&&ce.emit("init",wn)}),0);var _i=/\{\{((?:.|\r?\n)+?)\}\}/g,yi=/[-.*+?^${}()|[\]\/\\]/g,Ei=y((function(e){var t=e[0].replace(yi,"\\$&"),n=e[1].replace(yi,"\\$&");return new RegExp(t+"((?:.|\\n)+?)"+n,"g")}));var Ti={staticKeys:["staticClass"],transformNode:function(e,t){t.warn;var n=Hr(e,"class");n&&(e.staticClass=JSON.stringify(n));var r=Ur(e,"class",!1);r&&(e.classBinding=r)},genData:function(e){var t="";return e.staticClass&&(t+="staticClass:"+e.staticClass+","),e.classBinding&&(t+="class:"+e.classBinding+","),t}};var Oi,Ni={staticKeys:["staticStyle"],transformNode:function(e,t){t.warn;var n=Hr(e,"style");n&&(e.staticStyle=JSON.stringify(po(n)));var r=Ur(e,"style",!1);r&&(e.styleBinding=r)},genData:function(e){var t="";return e.staticStyle&&(t+="staticStyle:"+e.staticStyle+","),e.styleBinding&&(t+="style:("+e.styleBinding+"),"),t}},zi=function(e){return(Oi=Oi||document.createElement("div")).innerHTML=e,Oi.textContent},Li=v("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),Ci=v("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),wi=v("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),Si=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,Ri=/^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,xi="[a-zA-Z_][\\-\\.0-9_a-zA-Z"+j.source+"]*",qi="((?:"+xi+"\\:)?"+xi+")",Wi=new RegExp("^<"+qi),ki=/^\s*(\/?)>/,Bi=new RegExp("^<\\/"+qi+"[^>]*>"),Ii=/^]+>/i,Di=/^",""":'"',"&":"&"," ":"\n"," ":"\t","'":"'"},Hi=/&(?:lt|gt|quot|amp|#39);/g,Fi=/&(?:lt|gt|quot|amp|#39|#10|#9);/g,$i=v("pre,textarea",!0),Gi=function(e,t){return e&&$i(e)&&"\n"===t[0]};function Vi(e,t){var n=t?Fi:Hi;return e.replace(n,(function(e){return Ui[e]}))}var Yi,Ki,Zi,Qi,Ji,ea,ta,na,ra=/^@|^v-on:/,oa=/^v-|^@|^:|^#/,ia=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,aa=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,ca=/^\(|\)$/g,sa=/^\[.*\]$/,la=/:(.*)$/,ua=/^:|^\.|^v-bind:/,fa=/\.[^.\]]+(?=[^\]]*$)/g,da=/^v-slot(:|$)|^#/,pa=/[\r\n]/,ha=/\s+/g,Ma=y(zi),va="_empty_";function ba(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:Ta(t),rawAttrsMap:{},parent:n,children:[]}}function ma(e,t){Yi=t.warn||Wr,ea=t.isPreTag||x,ta=t.mustUseProp||x,na=t.getTagNamespace||x;var n=t.isReservedTag||x;(function(e){return!!e.component||!n(e.tag)}),Zi=kr(t.modules,"transformNode"),Qi=kr(t.modules,"preTransformNode"),Ji=kr(t.modules,"postTransformNode"),Ki=t.delimiters;var r,o,i=[],a=!1!==t.preserveWhitespace,c=t.whitespace,s=!1,l=!1;function u(e){if(f(e),s||e.processed||(e=ga(e,t)),i.length||e===r||r.if&&(e.elseif||e.else)&&_a(r,{exp:e.elseif,block:e}),o&&!e.forbidden)if(e.elseif||e.else)a=e,c=function(e){for(var t=e.length;t--;){if(1===e[t].type)return e[t];e.pop()}}(o.children),c&&c.if&&_a(c,{exp:a.elseif,block:a});else{if(e.slotScope){var n=e.slotTarget||'"default"';(o.scopedSlots||(o.scopedSlots={}))[n]=e}o.children.push(e),e.parent=o}var a,c;e.children=e.children.filter((function(e){return!e.slotScope})),f(e),e.pre&&(s=!1),ea(e.tag)&&(l=!1);for(var u=0;u]*>)","i")),d=e.replace(f,(function(e,n,r){return l=r.length,Pi(u)||"noscript"===u||(n=n.replace(//g,"$1").replace(//g,"$1")),Gi(u,n)&&(n=n.slice(1)),t.chars&&t.chars(n),""}));s+=e.length-d.length,e=d,N(u,s-l,s)}else{var p=e.indexOf("<");if(0===p){if(Di.test(e)){var h=e.indexOf("--\x3e");if(h>=0){t.shouldKeepComment&&t.comment(e.substring(4,h),s,s+h+3),E(h+3);continue}}if(Xi.test(e)){var M=e.indexOf("]>");if(M>=0){E(M+2);continue}}var v=e.match(Ii);if(v){E(v[0].length);continue}var b=e.match(Bi);if(b){var m=s;E(b[0].length),N(b[1],m,s);continue}var g=T();if(g){O(g),Gi(g.tagName,e)&&E(1);continue}}var A=void 0,_=void 0,y=void 0;if(p>=0){for(_=e.slice(p);!(Bi.test(_)||Wi.test(_)||Di.test(_)||Xi.test(_)||(y=_.indexOf("<",1))<0);)p+=y,_=e.slice(p);A=e.substring(0,p)}p<0&&(A=e),A&&E(A.length),t.chars&&A&&t.chars(A,s-A.length,s)}if(e===n){t.chars&&t.chars(e);break}}function E(t){s+=t,e=e.substring(t)}function T(){var t=e.match(Wi);if(t){var n,r,o={tagName:t[1],attrs:[],start:s};for(E(t[0].length);!(n=e.match(ki))&&(r=e.match(Ri)||e.match(Si));)r.start=s,E(r[0].length),r.end=s,o.attrs.push(r);if(n)return o.unarySlash=n[1],E(n[0].length),o.end=s,o}}function O(e){var n=e.tagName,s=e.unarySlash;i&&("p"===r&&wi(n)&&N(r),c(n)&&r===n&&N(n));for(var l=a(n)||!!s,u=e.attrs.length,f=new Array(u),d=0;d=0&&o[a].lowerCasedTag!==c;a--);else a=0;if(a>=0){for(var l=o.length-1;l>=a;l--)t.end&&t.end(o[l].tag,n,i);o.length=a,r=a&&o[a-1].tag}else"br"===c?t.start&&t.start(e,[],!0,n,i):"p"===c&&(t.start&&t.start(e,[],!1,n,i),t.end&&t.end(e,n,i))}N()}(e,{warn:Yi,expectHTML:t.expectHTML,isUnaryTag:t.isUnaryTag,canBeLeftOpenTag:t.canBeLeftOpenTag,shouldDecodeNewlines:t.shouldDecodeNewlines,shouldDecodeNewlinesForHref:t.shouldDecodeNewlinesForHref,shouldKeepComment:t.comments,outputSourceRange:t.outputSourceRange,start:function(e,n,a,c,f){var d=o&&o.ns||na(e);Q&&"svg"===d&&(n=function(e){for(var t=[],n=0;ns&&(c.push(i=e.slice(s,o)),a.push(JSON.stringify(i)));var l=xr(r[1].trim());a.push("_s("+l+")"),c.push({"@binding":l}),s=o+r[0].length}return s-1"+("true"===i?":("+t+")":":_q("+t+","+i+")")),jr(e,"change","var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+i+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+o+")":o)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Vr(t,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Vr(t,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Vr(t,"$$c")+"}",null,!0)}(e,r,o);else if("input"===i&&"radio"===a)!function(e,t,n){var r=n&&n.number,o=Ur(e,"value")||"null";Br(e,"checked","_q("+t+","+(o=r?"_n("+o+")":o)+")"),jr(e,"change",Vr(t,o),null,!0)}(e,r,o);else if("input"===i||"textarea"===i)!function(e,t,n){var r=e.attrsMap.type;0;var o=n||{},i=o.lazy,a=o.number,c=o.trim,s=!i&&"range"!==r,l=i?"change":"range"===r?to:"input",u="$event.target.value";c&&(u="$event.target.value.trim()");a&&(u="_n("+u+")");var f=Vr(t,u);s&&(f="if($event.target.composing)return;"+f);Br(e,"value","("+t+")"),jr(e,l,f,null,!0),(c||a)&&jr(e,"blur","$forceUpdate()")}(e,r,o);else{if(!P.isReservedTag(i))return Gr(e,r,o),!1}return!0},text:function(e,t){t.value&&Br(e,"textContent","_s("+t.value+")",t)},html:function(e,t){t.value&&Br(e,"innerHTML","_s("+t.value+")",t)}},xa={expectHTML:!0,modules:Ca,directives:Ra,isPreTag:function(e){return"pre"===e},isUnaryTag:Li,mustUseProp:Xn,canBeLeftOpenTag:Ci,isReservedTag:tr,getTagNamespace:nr,staticKeys:function(e){return e.reduce((function(e,t){return e.concat(t.staticKeys||[])}),[]).join(",")}(Ca)},qa=y((function(e){return v("type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap"+(e?","+e:""))}));function Wa(e,t){e&&(wa=qa(t.staticKeys||""),Sa=t.isReservedTag||x,ka(e),Ba(e,!1))}function ka(e){if(e.static=function(e){if(2===e.type)return!1;if(3===e.type)return!0;return!(!e.pre&&(e.hasBindings||e.if||e.for||b(e.tag)||!Sa(e.tag)||function(e){for(;e.parent;){if("template"!==(e=e.parent).tag)return!1;if(e.for)return!0}return!1}(e)||!Object.keys(e).every(wa)))}(e),1===e.type){if(!Sa(e.tag)&&"slot"!==e.tag&&null==e.attrsMap["inline-template"])return;for(var t=0,n=e.children.length;t|^function(?:\s+[\w$]+)?\s*\(/,Da=/\([^)]*?\);*$/,Xa=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Pa={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},ja={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},Ua=function(e){return"if("+e+")return null;"},Ha={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:Ua("$event.target !== $event.currentTarget"),ctrl:Ua("!$event.ctrlKey"),shift:Ua("!$event.shiftKey"),alt:Ua("!$event.altKey"),meta:Ua("!$event.metaKey"),left:Ua("'button' in $event && $event.button !== 0"),middle:Ua("'button' in $event && $event.button !== 1"),right:Ua("'button' in $event && $event.button !== 2")};function Fa(e,t){var n=t?"nativeOn:":"on:",r="",o="";for(var i in e){var a=$a(e[i]);e[i]&&e[i].dynamic?o+=i+","+a+",":r+='"'+i+'":'+a+","}return r="{"+r.slice(0,-1)+"}",o?n+"_d("+r+",["+o.slice(0,-1)+"])":n+r}function $a(e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map((function(e){return $a(e)})).join(",")+"]";var t=Xa.test(e.value),n=Ia.test(e.value),r=Xa.test(e.value.replace(Da,""));if(e.modifiers){var o="",i="",a=[];for(var c in e.modifiers)if(Ha[c])i+=Ha[c],Pa[c]&&a.push(c);else if("exact"===c){var s=e.modifiers;i+=Ua(["ctrl","shift","alt","meta"].filter((function(e){return!s[e]})).map((function(e){return"$event."+e+"Key"})).join("||"))}else a.push(c);return a.length&&(o+=function(e){return"if(!$event.type.indexOf('key')&&"+e.map(Ga).join("&&")+")return null;"}(a)),i&&(o+=i),"function($event){"+o+(t?"return "+e.value+"($event)":n?"return ("+e.value+")($event)":r?"return "+e.value:e.value)+"}"}return t||n?e.value:"function($event){"+(r?"return "+e.value:e.value)+"}"}function Ga(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=Pa[e],r=ja[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}var Va={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(e,t){e.wrapData=function(n){return"_b("+n+",'"+e.tag+"',"+t.value+","+(t.modifiers&&t.modifiers.prop?"true":"false")+(t.modifiers&&t.modifiers.sync?",true":"")+")"}},cloak:R},Ya=function(e){this.options=e,this.warn=e.warn||Wr,this.transforms=kr(e.modules,"transformCode"),this.dataGenFns=kr(e.modules,"genData"),this.directives=w(w({},Va),e.directives);var t=e.isReservedTag||x;this.maybeComponent=function(e){return!!e.component||!t(e.tag)},this.onceId=0,this.staticRenderFns=[],this.pre=!1};function Ka(e,t){var n=new Ya(t);return{render:"with(this){return "+(e?Za(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function Za(e,t){if(e.parent&&(e.pre=e.pre||e.parent.pre),e.staticRoot&&!e.staticProcessed)return Qa(e,t);if(e.once&&!e.onceProcessed)return Ja(e,t);if(e.for&&!e.forProcessed)return nc(e,t);if(e.if&&!e.ifProcessed)return ec(e,t);if("template"!==e.tag||e.slotTarget||t.pre){if("slot"===e.tag)return function(e,t){var n=e.slotName||'"default"',r=ac(e,t),o="_t("+n+(r?","+r:""),i=e.attrs||e.dynamicAttrs?lc((e.attrs||[]).concat(e.dynamicAttrs||[]).map((function(e){return{name:T(e.name),value:e.value,dynamic:e.dynamic}}))):null,a=e.attrsMap["v-bind"];!i&&!a||r||(o+=",null");i&&(o+=","+i);a&&(o+=(i?"":",null")+","+a);return o+")"}(e,t);var n;if(e.component)n=function(e,t,n){var r=t.inlineTemplate?null:ac(t,n,!0);return"_c("+e+","+rc(t,n)+(r?","+r:"")+")"}(e.component,e,t);else{var r;(!e.plain||e.pre&&t.maybeComponent(e))&&(r=rc(e,t));var o=e.inlineTemplate?null:ac(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(o?","+o:"")+")"}for(var i=0;i>>0}(a):"")+")"}(e,e.scopedSlots,t)+","),e.model&&(n+="model:{value:"+e.model.value+",callback:"+e.model.callback+",expression:"+e.model.expression+"},"),e.inlineTemplate){var i=function(e,t){var n=e.children[0];0;if(n&&1===n.type){var r=Ka(n,t.options);return"inlineTemplate:{render:function(){"+r.render+"},staticRenderFns:["+r.staticRenderFns.map((function(e){return"function(){"+e+"}"})).join(",")+"]}"}}(e,t);i&&(n+=i+",")}return n=n.replace(/,$/,"")+"}",e.dynamicAttrs&&(n="_b("+n+',"'+e.tag+'",'+lc(e.dynamicAttrs)+")"),e.wrapData&&(n=e.wrapData(n)),e.wrapListeners&&(n=e.wrapListeners(n)),n}function oc(e){return 1===e.type&&("slot"===e.tag||e.children.some(oc))}function ic(e,t){var n=e.attrsMap["slot-scope"];if(e.if&&!e.ifProcessed&&!n)return ec(e,t,ic,"null");if(e.for&&!e.forProcessed)return nc(e,t,ic);var r=e.slotScope===va?"":String(e.slotScope),o="function("+r+"){return "+("template"===e.tag?e.if&&n?"("+e.if+")?"+(ac(e,t)||"undefined")+":undefined":ac(e,t)||"undefined":Za(e,t))+"}",i=r?"":",proxy:true";return"{key:"+(e.slotTarget||'"default"')+",fn:"+o+i+"}"}function ac(e,t,n,r,o){var i=e.children;if(i.length){var a=i[0];if(1===i.length&&a.for&&"template"!==a.tag&&"slot"!==a.tag){var c=n?t.maybeComponent(a)?",1":",0":"";return""+(r||Za)(a,t)+c}var s=n?function(e,t){for(var n=0,r=0;r':'
',hc.innerHTML.indexOf(" ")>0}var gc=!!V&&mc(!1),Ac=!!V&&mc(!0),_c=y((function(e){var t=ir(e);return t&&t.innerHTML})),yc=wn.prototype.$mount;wn.prototype.$mount=function(e,t){if((e=e&&ir(e))===document.body||e===document.documentElement)return this;var n=this.$options;if(!n.render){var r=n.template;if(r)if("string"==typeof r)"#"===r.charAt(0)&&(r=_c(r));else{if(!r.nodeType)return this;r=r.innerHTML}else e&&(r=function(e){if(e.outerHTML)return e.outerHTML;var t=document.createElement("div");return t.appendChild(e.cloneNode(!0)),t.innerHTML}(e));if(r){0;var o=bc(r,{outputSourceRange:!1,shouldDecodeNewlines:gc,shouldDecodeNewlinesForHref:Ac,delimiters:n.delimiters,comments:n.comments},this),i=o.render,a=o.staticRenderFns;n.render=i,n.staticRenderFns=a}}return yc.call(this,e,t)},wn.compile=bc;const Ec=wn;var Tc=n(6486),Oc=n.n(Tc),Nc=n(8),zc=n.n(Nc);const Lc={computed:{Telescope:function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}((function(){return Telescope}))},methods:{timeAgo:function(e){zc().updateLocale("en",{relativeTime:{future:"in %s",past:"%s ago",s:function(e){return e+"s ago"},ss:"%ds ago",m:"1m ago",mm:"%dm ago",h:"1h ago",hh:"%dh ago",d:"1d ago",dd:"%dd ago",M:"a month ago",MM:"%d months ago",y:"a year ago",yy:"%d years ago"}});var t=zc()().diff(e,"seconds"),n=zc()("2018-01-01").startOf("day").seconds(t);return t>300?zc()(e).fromNow(!0):t<60?n.format("s")+"s ago":n.format("m:ss")+"m ago"},localTime:function(e){return zc()(e).local().format("MMMM Do YYYY, h:mm:ss A")},truncate:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:70;return Oc().truncate(e,{length:t,separator:/,? +/})},debouncer:Oc().debounce((function(e){return e()}),500),alertError:function(e){this.$root.alert.type="error",this.$root.alert.autoClose=!1,this.$root.alert.message=e},alertSuccess:function(e,t){this.$root.alert.type="success",this.$root.alert.autoClose=t,this.$root.alert.message=e},alertConfirm:function(e,t,n){this.$root.alert.type="confirmation",this.$root.alert.autoClose=!1,this.$root.alert.message=e,this.$root.alert.confirmationProceed=t,this.$root.alert.confirmationCancel=n}}};var Cc=n(9669),wc=n.n(Cc);const Sc=[{path:"/",redirect:"/requests"},{path:"/mail/:id",name:"mail-preview",component:n(5958).Z},{path:"/mail",name:"mail",component:n(3138).Z},{path:"/exceptions/:id",name:"exception-preview",component:n(1417).Z},{path:"/exceptions",name:"exceptions",component:n(2017).Z},{path:"/dumps",name:"dumps",component:n(3610).Z},{path:"/logs/:id",name:"log-preview",component:n(6997).Z},{path:"/logs",name:"logs",component:n(6882).Z},{path:"/notifications/:id",name:"notification-preview",component:n(9469).Z},{path:"/notifications",name:"notifications",component:n(1436).Z},{path:"/jobs/:id",name:"job-preview",component:n(6049).Z},{path:"/jobs",name:"jobs",component:n(7231).Z},{path:"/batches/:id",name:"batch-preview",component:n(6141).Z},{path:"/batches",name:"batches",component:n(771).Z},{path:"/events/:id",name:"event-preview",component:n(8466).Z},{path:"/events",name:"events",component:n(4638).Z},{path:"/cache/:id",name:"cache-preview",component:n(5131).Z},{path:"/cache",name:"cache",component:n(9940).Z},{path:"/queries/:id",name:"query-preview",component:n(7015).Z},{path:"/queries",name:"queries",component:n(3380).Z},{path:"/models/:id",name:"model-preview",component:n(369).Z},{path:"/models",name:"models",component:n(1983).Z},{path:"/requests/:id",name:"request-preview",component:n(5250).Z},{path:"/requests",name:"requests",component:n(8957).Z},{path:"/commands/:id",name:"command-preview",component:n(9112).Z},{path:"/commands",name:"commands",component:n(3917).Z},{path:"/schedule/:id",name:"schedule-preview",component:n(7246).Z},{path:"/schedule",name:"schedule",component:n(3588).Z},{path:"/redis/:id",name:"redis-preview",component:n(8726).Z},{path:"/redis",name:"redis",component:n(4474).Z},{path:"/monitored-tags",name:"monitored-tags",component:n(799).Z},{path:"/gates/:id",name:"gate-preview",component:n(7580).Z},{path:"/gates",name:"gates",component:n(5328).Z},{path:"/views/:id",name:"view-preview",component:n(5653).Z},{path:"/views",name:"views",component:n(4576).Z},{path:"/client-requests/:id",name:"client-request-preview",component:n(7402).Z},{path:"/client-requests",name:"client-requests",component:n(8332).Z}];function Rc(e,t){for(var n in t)e[n]=t[n];return e}var xc=/[!'()*]/g,qc=function(e){return"%"+e.charCodeAt(0).toString(16)},Wc=/%2C/g,kc=function(e){return encodeURIComponent(e).replace(xc,qc).replace(Wc,",")};function Bc(e){try{return decodeURIComponent(e)}catch(e){0}return e}var Ic=function(e){return null==e||"object"==typeof e?e:String(e)};function Dc(e){var t={};return(e=e.trim().replace(/^(\?|#|&)/,""))?(e.split("&").forEach((function(e){var n=e.replace(/\+/g," ").split("="),r=Bc(n.shift()),o=n.length>0?Bc(n.join("=")):null;void 0===t[r]?t[r]=o:Array.isArray(t[r])?t[r].push(o):t[r]=[t[r],o]})),t):t}function Xc(e){var t=e?Object.keys(e).map((function(t){var n=e[t];if(void 0===n)return"";if(null===n)return kc(t);if(Array.isArray(n)){var r=[];return n.forEach((function(e){void 0!==e&&(null===e?r.push(kc(t)):r.push(kc(t)+"="+kc(e)))})),r.join("&")}return kc(t)+"="+kc(n)})).filter((function(e){return e.length>0})).join("&"):null;return t?"?"+t:""}var Pc=/\/?$/;function jc(e,t,n,r){var o=r&&r.options.stringifyQuery,i=t.query||{};try{i=Uc(i)}catch(e){}var a={name:t.name||e&&e.name,meta:e&&e.meta||{},path:t.path||"/",hash:t.hash||"",query:i,params:t.params||{},fullPath:$c(t,o),matched:e?Fc(e):[]};return n&&(a.redirectedFrom=$c(n,o)),Object.freeze(a)}function Uc(e){if(Array.isArray(e))return e.map(Uc);if(e&&"object"==typeof e){var t={};for(var n in e)t[n]=Uc(e[n]);return t}return e}var Hc=jc(null,{path:"/"});function Fc(e){for(var t=[];e;)t.unshift(e),e=e.parent;return t}function $c(e,t){var n=e.path,r=e.query;void 0===r&&(r={});var o=e.hash;return void 0===o&&(o=""),(n||"/")+(t||Xc)(r)+o}function Gc(e,t,n){return t===Hc?e===t:!!t&&(e.path&&t.path?e.path.replace(Pc,"")===t.path.replace(Pc,"")&&(n||e.hash===t.hash&&Vc(e.query,t.query)):!(!e.name||!t.name)&&(e.name===t.name&&(n||e.hash===t.hash&&Vc(e.query,t.query)&&Vc(e.params,t.params))))}function Vc(e,t){if(void 0===e&&(e={}),void 0===t&&(t={}),!e||!t)return e===t;var n=Object.keys(e).sort(),r=Object.keys(t).sort();return n.length===r.length&&n.every((function(n,o){var i=e[n];if(r[o]!==n)return!1;var a=t[n];return null==i||null==a?i===a:"object"==typeof i&&"object"==typeof a?Vc(i,a):String(i)===String(a)}))}function Yc(e){for(var t=0;t=0&&(t=e.slice(r),e=e.slice(0,r));var o=e.indexOf("?");return o>=0&&(n=e.slice(o+1),e=e.slice(0,o)),{path:e,query:n,hash:t}}(o.path||""),l=t&&t.path||"/",u=s.path?Qc(s.path,l,n||o.append):l,f=function(e,t,n){void 0===t&&(t={});var r,o=n||Dc;try{r=o(e||"")}catch(e){r={}}for(var i in t){var a=t[i];r[i]=Array.isArray(a)?a.map(Ic):Ic(a)}return r}(s.query,o.query,r&&r.options.parseQuery),d=o.hash||s.hash;return d&&"#"!==d.charAt(0)&&(d="#"+d),{_normalized:!0,path:u,query:f,hash:d}}var As,_s=function(){},ys={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(e){var t=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,c=o.href,s={},l=n.options.linkActiveClass,u=n.options.linkExactActiveClass,f=null==l?"router-link-active":l,d=null==u?"router-link-exact-active":u,p=null==this.activeClass?f:this.activeClass,h=null==this.exactActiveClass?d:this.exactActiveClass,M=a.redirectedFrom?jc(null,gs(a.redirectedFrom),null,n):a;s[h]=Gc(r,M,this.exactPath),s[p]=this.exact||this.exactPath?s[h]:function(e,t){return 0===e.path.replace(Pc,"/").indexOf(t.path.replace(Pc,"/"))&&(!t.hash||e.hash===t.hash)&&function(e,t){for(var n in t)if(!(n in e))return!1;return!0}(e.query,t.query)}(r,M);var v=s[h]?this.ariaCurrentValue:null,b=function(e){Es(e)&&(t.replace?n.replace(i,_s):n.push(i,_s))},m={click:Es};Array.isArray(this.event)?this.event.forEach((function(e){m[e]=b})):m[this.event]=b;var g={class:s},A=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:a,navigate:b,isActive:s[p],isExactActive:s[h]});if(A){if(1===A.length)return A[0];if(A.length>1||!A.length)return 0===A.length?e():e("span",{},A)}if("a"===this.tag)g.on=m,g.attrs={href:c,"aria-current":v};else{var _=Ts(this.$slots.default);if(_){_.isStatic=!1;var y=_.data=Rc({},_.data);for(var E in y.on=y.on||{},y.on){var T=y.on[E];E in m&&(y.on[E]=Array.isArray(T)?T:[T])}for(var O in m)O in y.on?y.on[O].push(m[O]):y.on[O]=b;var N=_.data.attrs=Rc({},_.data.attrs);N.href=c,N["aria-current"]=v}else g.on=m}return e(this.tag,g,this.$slots.default)}};function Es(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey||e.defaultPrevented||void 0!==e.button&&0!==e.button)){if(e.currentTarget&&e.currentTarget.getAttribute){var t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Ts(e){if(e)for(var t,n=0;n-1&&(c.params[d]=n.params[d]);return c.path=ms(u.path,c.params),s(u,c,a)}if(c.path){c.params={};for(var p=0;p=e.length?n():e[o]?t(e[o],(function(){r(o+1)})):r(o+1)};r(0)}var Zs={redirected:2,aborted:4,cancelled:8,duplicated:16};function Qs(e,t){return el(e,t,Zs.redirected,'Redirected when going from "'+e.fullPath+'" to "'+function(e){if("string"==typeof e)return e;if("path"in e)return e.path;var t={};return tl.forEach((function(n){n in e&&(t[n]=e[n])})),JSON.stringify(t,null,2)}(t)+'" via a navigation guard.')}function Js(e,t){return el(e,t,Zs.cancelled,'Navigation cancelled from "'+e.fullPath+'" to "'+t.fullPath+'" with a new navigation.')}function el(e,t,n,r){var o=new Error(r);return o._isRouter=!0,o.from=e,o.to=t,o.type=n,o}var tl=["params","query","hash"];function nl(e){return Object.prototype.toString.call(e).indexOf("Error")>-1}function rl(e,t){return nl(e)&&e._isRouter&&(null==t||e.type===t)}function ol(e){return function(t,n,r){var o=!1,i=0,a=null;il(e,(function(e,t,n,c){if("function"==typeof e&&void 0===e.cid){o=!0,i++;var s,l=sl((function(t){var o;((o=t).__esModule||cl&&"Module"===o[Symbol.toStringTag])&&(t=t.default),e.resolved="function"==typeof t?t:As.extend(t),n.components[c]=t,--i<=0&&r()})),u=sl((function(e){var t="Failed to resolve async component "+c+": "+e;a||(a=nl(e)?e:new Error(t),r(a))}));try{s=e(l,u)}catch(e){u(e)}if(s)if("function"==typeof s.then)s.then(l,u);else{var f=s.component;f&&"function"==typeof f.then&&f.then(l,u)}}})),o||r()}}function il(e,t){return al(e.map((function(e){return Object.keys(e.components).map((function(n){return t(e.components[n],e.instances[n],e,n)}))})))}function al(e){return Array.prototype.concat.apply([],e)}var cl="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function sl(e){var t=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!t)return t=!0,e.apply(this,n)}}var ll=function(e,t){this.router=e,this.base=function(e){if(!e)if(Os){var t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else e="/";"/"!==e.charAt(0)&&(e="/"+e);return e.replace(/\/$/,"")}(t),this.current=Hc,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function ul(e,t,n,r){var o=il(e,(function(e,r,o,i){var a=function(e,t){"function"!=typeof e&&(e=As.extend(e));return e.options[t]}(e,t);if(a)return Array.isArray(a)?a.map((function(e){return n(e,r,o,i)})):n(a,r,o,i)}));return al(r?o.reverse():o)}function fl(e,t){if(t)return function(){return e.apply(t,arguments)}}ll.prototype.listen=function(e){this.cb=e},ll.prototype.onReady=function(e,t){this.ready?e():(this.readyCbs.push(e),t&&this.readyErrorCbs.push(t))},ll.prototype.onError=function(e){this.errorCbs.push(e)},ll.prototype.transitionTo=function(e,t,n){var r,o=this;try{r=this.router.match(e,this.current)}catch(e){throw this.errorCbs.forEach((function(t){t(e)})),e}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),t&&t(r),o.ensureURL(),o.router.afterHooks.forEach((function(e){e&&e(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(e){e(r)})))}),(function(e){n&&n(e),e&&!o.ready&&(rl(e,Zs.redirected)&&i===Hc||(o.ready=!0,o.readyErrorCbs.forEach((function(t){t(e)}))))}))},ll.prototype.confirmTransition=function(e,t,n){var r=this,o=this.current;this.pending=e;var i,a,c=function(e){!rl(e)&&nl(e)&&r.errorCbs.length&&r.errorCbs.forEach((function(t){t(e)})),n&&n(e)},s=e.matched.length-1,l=o.matched.length-1;if(Gc(e,o)&&s===l&&e.matched[s]===o.matched[l])return this.ensureURL(),c(((a=el(i=o,e,Zs.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var u=function(e,t){var n,r=Math.max(e.length,t.length);for(n=0;n0)){var t=this.router,n=t.options.scrollBehavior,r=Gs&&n;r&&this.listeners.push(Bs());var o=function(){var n=e.current,o=pl(e.base);e.current===Hc&&o===e._startLocation||e.transitionTo(o,(function(e){r&&Is(t,e,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},t.prototype.go=function(e){window.history.go(e)},t.prototype.push=function(e,t,n){var r=this,o=this.current;this.transitionTo(e,(function(e){Vs(Jc(r.base+e.fullPath)),Is(r.router,e,o,!1),t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var r=this,o=this.current;this.transitionTo(e,(function(e){Ys(Jc(r.base+e.fullPath)),Is(r.router,e,o,!1),t&&t(e)}),n)},t.prototype.ensureURL=function(e){if(pl(this.base)!==this.current.fullPath){var t=Jc(this.base+this.current.fullPath);e?Vs(t):Ys(t)}},t.prototype.getCurrentLocation=function(){return pl(this.base)},t}(ll);function pl(e){var t=window.location.pathname;return e&&0===t.toLowerCase().indexOf(e.toLowerCase())&&(t=t.slice(e.length)),(t||"/")+window.location.search+window.location.hash}var hl=function(e){function t(t,n,r){e.call(this,t,n),r&&function(e){var t=pl(e);if(!/^\/#/.test(t))return window.location.replace(Jc(e+"/#"+t)),!0}(this.base)||Ml()}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.setupListeners=function(){var e=this;if(!(this.listeners.length>0)){var t=this.router.options.scrollBehavior,n=Gs&&t;n&&this.listeners.push(Bs());var r=function(){var t=e.current;Ml()&&e.transitionTo(vl(),(function(r){n&&Is(e.router,r,t,!0),Gs||gl(r.fullPath)}))},o=Gs?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},t.prototype.push=function(e,t,n){var r=this,o=this.current;this.transitionTo(e,(function(e){ml(e.fullPath),Is(r.router,e,o,!1),t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var r=this,o=this.current;this.transitionTo(e,(function(e){gl(e.fullPath),Is(r.router,e,o,!1),t&&t(e)}),n)},t.prototype.go=function(e){window.history.go(e)},t.prototype.ensureURL=function(e){var t=this.current.fullPath;vl()!==t&&(e?ml(t):gl(t))},t.prototype.getCurrentLocation=function(){return vl()},t}(ll);function Ml(){var e=vl();return"/"===e.charAt(0)||(gl("/"+e),!1)}function vl(){var e=window.location.href,t=e.indexOf("#");return t<0?"":e=e.slice(t+1)}function bl(e){var t=window.location.href,n=t.indexOf("#");return(n>=0?t.slice(0,n):t)+"#"+e}function ml(e){Gs?Vs(bl(e)):window.location.hash=e}function gl(e){Gs?Ys(bl(e)):window.location.replace(bl(e))}var Al=function(e){function t(t,n){e.call(this,t,n),this.stack=[],this.index=-1}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.push=function(e,t,n){var r=this;this.transitionTo(e,(function(e){r.stack=r.stack.slice(0,r.index+1).concat(e),r.index++,t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var r=this;this.transitionTo(e,(function(e){r.stack=r.stack.slice(0,r.index).concat(e),t&&t(e)}),n)},t.prototype.go=function(e){var t=this,n=this.index+e;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var e=t.current;t.index=n,t.updateRoute(r),t.router.afterHooks.forEach((function(t){t&&t(r,e)}))}),(function(e){rl(e,Zs.duplicated)&&(t.index=n)}))}},t.prototype.getCurrentLocation=function(){var e=this.stack[this.stack.length-1];return e?e.fullPath:"/"},t.prototype.ensureURL=function(){},t}(ll),_l=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Cs(e.routes||[],this);var t=e.mode||"hash";switch(this.fallback="history"===t&&!Gs&&!1!==e.fallback,this.fallback&&(t="hash"),Os||(t="abstract"),this.mode=t,t){case"history":this.history=new dl(this,e.base);break;case"hash":this.history=new hl(this,e.base,this.fallback);break;case"abstract":this.history=new Al(this,e.base)}},yl={currentRoute:{configurable:!0}};function El(e,t){return e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}_l.prototype.match=function(e,t,n){return this.matcher.match(e,t,n)},yl.currentRoute.get=function(){return this.history&&this.history.current},_l.prototype.init=function(e){var t=this;if(this.apps.push(e),e.$once("hook:destroyed",(function(){var n=t.apps.indexOf(e);n>-1&&t.apps.splice(n,1),t.app===e&&(t.app=t.apps[0]||null),t.app||t.history.teardown()})),!this.app){this.app=e;var n=this.history;if(n instanceof dl||n instanceof hl){var r=function(e){n.setupListeners(),function(e){var r=n.current,o=t.options.scrollBehavior;Gs&&o&&"fullPath"in e&&Is(t,e,r,!1)}(e)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(e){t.apps.forEach((function(t){t._route=e}))}))}},_l.prototype.beforeEach=function(e){return El(this.beforeHooks,e)},_l.prototype.beforeResolve=function(e){return El(this.resolveHooks,e)},_l.prototype.afterEach=function(e){return El(this.afterHooks,e)},_l.prototype.onReady=function(e,t){this.history.onReady(e,t)},_l.prototype.onError=function(e){this.history.onError(e)},_l.prototype.push=function(e,t,n){var r=this;if(!t&&!n&&"undefined"!=typeof Promise)return new Promise((function(t,n){r.history.push(e,t,n)}));this.history.push(e,t,n)},_l.prototype.replace=function(e,t,n){var r=this;if(!t&&!n&&"undefined"!=typeof Promise)return new Promise((function(t,n){r.history.replace(e,t,n)}));this.history.replace(e,t,n)},_l.prototype.go=function(e){this.history.go(e)},_l.prototype.back=function(){this.go(-1)},_l.prototype.forward=function(){this.go(1)},_l.prototype.getMatchedComponents=function(e){var t=e?e.matched?e:this.resolve(e).route:this.currentRoute;return t?[].concat.apply([],t.matched.map((function(e){return Object.keys(e.components).map((function(t){return e.components[t]}))}))):[]},_l.prototype.resolve=function(e,t,n){var r=gs(e,t=t||this.history.current,n,this),o=this.match(r,t),i=o.redirectedFrom||o.fullPath,a=function(e,t,n){var r="hash"===n?"#"+t:t;return e?Jc(e+"/"+r):r}(this.history.base,i,this.mode);return{location:r,route:o,href:a,normalizedTo:r,resolved:o}},_l.prototype.getRoutes=function(){return this.matcher.getRoutes()},_l.prototype.addRoute=function(e,t){this.matcher.addRoute(e,t),this.history.current!==Hc&&this.history.transitionTo(this.history.getCurrentLocation())},_l.prototype.addRoutes=function(e){this.matcher.addRoutes(e),this.history.current!==Hc&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(_l.prototype,yl),_l.install=function e(t){if(!e.installed||As!==t){e.installed=!0,As=t;var n=function(e){return void 0!==e},r=function(e,t){var r=e.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(e,t)};t.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),t.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(t.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(t.prototype,"$route",{get:function(){return this._routerRoot._route}}),t.component("RouterView",Kc),t.component("RouterLink",ys);var o=t.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},_l.version="3.5.1",_l.isNavigationFailure=rl,_l.NavigationFailureType=Zs,_l.START_LOCATION=Hc,Os&&window.Vue&&window.Vue.use(_l);const Tl=_l;var Ol=n(4566),Nl=n.n(Ol),zl=n(3379),Ll=n.n(zl),Cl=n(8041),wl={insert:"head",singleton:!1};Ll()(Cl.Z,wl);Cl.Z.locals;n(3734);var Sl=document.head.querySelector('meta[name="csrf-token"]');Sl&&(wc().defaults.headers.common["X-CSRF-TOKEN"]=Sl.content),Ec.use(Tl),window.Popper=n(8981).default,zc().tz.setDefault(Telescope.timezone),window.Telescope.basePath="/"+window.Telescope.path;var Rl=window.Telescope.basePath+"/";""!==window.Telescope.path&&"/"!==window.Telescope.path||(Rl="/",window.Telescope.basePath="");var xl=new Tl({routes:Sc,mode:"history",base:Rl});Ec.component("vue-json-pretty",Nl()),Ec.component("related-entries",n(969).Z),Ec.component("index-screen",n(5264).Z),Ec.component("preview-screen",n(4969).Z),Ec.component("alert",n(318).Z),Ec.mixin(Lc),new Ec({el:"#telescope",router:xl,data:function(){return{alert:{type:null,autoClose:0,message:"",confirmationProceed:null,confirmationCancel:null},autoLoadsNewEntries:"1"===localStorage.autoLoadsNewEntries,recording:Telescope.recording}},methods:{autoLoadNewEntries:function(){this.autoLoadsNewEntries?(this.autoLoadsNewEntries=!1,localStorage.autoLoadsNewEntries=0):(this.autoLoadsNewEntries=!0,localStorage.autoLoadsNewEntries=1)},toggleRecording:function(){wc().post(Telescope.basePath+"/telescope-api/toggle-recording"),window.Telescope.recording=!Telescope.recording,this.recording=!this.recording},clearEntries:function(){confirm("Are you sure you want to delete all Telescope data?")&&wc().delete(Telescope.basePath+"/telescope-api/entries").then((function(e){return location.reload()}))}}})},3064:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={methods:{cacheActionTypeClass:function(e){return"hit"===e?"success":"set"===e?"info":"forget"===e?"warning":"missed"===e?"danger":void 0},composerTypeClass:function(e){return"composer"===e?"info":"creator"===e?"success":void 0},gateResultClass:function(e){return"allowed"===e?"success":"denied"===e?"danger":void 0},jobStatusClass:function(e){return"pending"===e?"secondary":"processed"===e?"success":"failed"===e?"danger":void 0},logLevelClass:function(e){return"debug"===e?"success":"info"===e?"info":"notice"===e?"secondary":"warning"===e?"warning":"error"===e||"critical"===e||"alert"===e||"emergency"===e?"danger":void 0},modelActionClass:function(e){return"created"==e?"success":"updated"==e?"info":"retrieved"==e?"secondary":"deleted"==e||"forceDeleted"==e?"danger":void 0},requestStatusClass:function(e){return e?e<300?"success":e<400?"info":e<500?"warning":e>=500?"danger":void 0:"danger"},requestMethodClass:function(e){return"GET"==e||"OPTIONS"==e?"secondary":"POST"==e||"PATCH"==e||"PUT"==e?"info":"DELETE"==e?"danger":void 0}}}},3734:function(e,t,n){!function(e,t,n){"use strict";function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=r(t),i=r(n);function a(e,t){for(var n=0;n=a)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};b.jQueryDetection(),v();var m="alert",g="4.6.0",A="bs.alert",_="."+A,y=".data-api",E=o.default.fn[m],T='[data-dismiss="alert"]',O="close"+_,N="closed"+_,z="click"+_+y,L="alert",C="fade",w="show",S=function(){function e(e){this._element=e}var t=e.prototype;return t.close=function(e){var t=this._element;e&&(t=this._getRootElement(e)),this._triggerCloseEvent(t).isDefaultPrevented()||this._removeElement(t)},t.dispose=function(){o.default.removeData(this._element,A),this._element=null},t._getRootElement=function(e){var t=b.getSelectorFromElement(e),n=!1;return t&&(n=document.querySelector(t)),n||(n=o.default(e).closest("."+L)[0]),n},t._triggerCloseEvent=function(e){var t=o.default.Event(O);return o.default(e).trigger(t),t},t._removeElement=function(e){var t=this;if(o.default(e).removeClass(w),o.default(e).hasClass(C)){var n=b.getTransitionDurationFromElement(e);o.default(e).one(b.TRANSITION_END,(function(n){return t._destroyElement(e,n)})).emulateTransitionEnd(n)}else this._destroyElement(e)},t._destroyElement=function(e){o.default(e).detach().trigger(N).remove()},e._jQueryInterface=function(t){return this.each((function(){var n=o.default(this),r=n.data(A);r||(r=new e(this),n.data(A,r)),"close"===t&&r[t](this)}))},e._handleDismiss=function(e){return function(t){t&&t.preventDefault(),e.close(this)}},c(e,null,[{key:"VERSION",get:function(){return g}}]),e}();o.default(document).on(z,T,S._handleDismiss(new S)),o.default.fn[m]=S._jQueryInterface,o.default.fn[m].Constructor=S,o.default.fn[m].noConflict=function(){return o.default.fn[m]=E,S._jQueryInterface};var R="button",x="4.6.0",q="bs.button",W="."+q,k=".data-api",B=o.default.fn[R],I="active",D="btn",X="focus",P='[data-toggle^="button"]',j='[data-toggle="buttons"]',U='[data-toggle="button"]',H='[data-toggle="buttons"] .btn',F='input:not([type="hidden"])',$=".active",G=".btn",V="click"+W+k,Y="focus"+W+k+" blur"+W+k,K="load"+W+k,Z=function(){function e(e){this._element=e,this.shouldAvoidTriggerChange=!1}var t=e.prototype;return t.toggle=function(){var e=!0,t=!0,n=o.default(this._element).closest(j)[0];if(n){var r=this._element.querySelector(F);if(r){if("radio"===r.type)if(r.checked&&this._element.classList.contains(I))e=!1;else{var i=n.querySelector($);i&&o.default(i).removeClass(I)}e&&("checkbox"!==r.type&&"radio"!==r.type||(r.checked=!this._element.classList.contains(I)),this.shouldAvoidTriggerChange||o.default(r).trigger("change")),r.focus(),t=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(t&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(I)),e&&o.default(this._element).toggleClass(I))},t.dispose=function(){o.default.removeData(this._element,q),this._element=null},e._jQueryInterface=function(t,n){return this.each((function(){var r=o.default(this),i=r.data(q);i||(i=new e(this),r.data(q,i)),i.shouldAvoidTriggerChange=n,"toggle"===t&&i[t]()}))},c(e,null,[{key:"VERSION",get:function(){return x}}]),e}();o.default(document).on(V,P,(function(e){var t=e.target,n=t;if(o.default(t).hasClass(D)||(t=o.default(t).closest(G)[0]),!t||t.hasAttribute("disabled")||t.classList.contains("disabled"))e.preventDefault();else{var r=t.querySelector(F);if(r&&(r.hasAttribute("disabled")||r.classList.contains("disabled")))return void e.preventDefault();"INPUT"!==n.tagName&&"LABEL"===t.tagName||Z._jQueryInterface.call(o.default(t),"toggle","INPUT"===n.tagName)}})).on(Y,P,(function(e){var t=o.default(e.target).closest(G)[0];o.default(t).toggleClass(X,/^focus(in)?$/.test(e.type))})),o.default(window).on(K,(function(){for(var e=[].slice.call(document.querySelectorAll(H)),t=0,n=e.length;t0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var t=e.prototype;return t.next=function(){this._isSliding||this._slide(ue)},t.nextWhenVisible=function(){var e=o.default(this._element);!document.hidden&&e.is(":visible")&&"hidden"!==e.css("visibility")&&this.next()},t.prev=function(){this._isSliding||this._slide(fe)},t.pause=function(e){e||(this._isPaused=!0),this._element.querySelector(De)&&(b.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},t.cycle=function(e){e||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},t.to=function(e){var t=this;this._activeElement=this._element.querySelector(ke);var n=this._getItemIndex(this._activeElement);if(!(e>this._items.length-1||e<0))if(this._isSliding)o.default(this._element).one(Me,(function(){return t.to(e)}));else{if(n===e)return this.pause(),void this.cycle();var r=e>n?ue:fe;this._slide(r,this._items[e])}},t.dispose=function(){o.default(this._element).off(te),o.default.removeData(this._element,ee),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},t._getConfig=function(e){return e=s({},se,e),b.typeCheckConfig(Q,e,le),e},t._handleSwipe=function(){var e=Math.abs(this.touchDeltaX);if(!(e<=ce)){var t=e/this.touchDeltaX;this.touchDeltaX=0,t>0&&this.prev(),t<0&&this.next()}},t._addEventListeners=function(){var e=this;this._config.keyboard&&o.default(this._element).on(ve,(function(t){return e._keydown(t)})),"hover"===this._config.pause&&o.default(this._element).on(be,(function(t){return e.pause(t)})).on(me,(function(t){return e.cycle(t)})),this._config.touch&&this._addTouchEventListeners()},t._addTouchEventListeners=function(){var e=this;if(this._touchSupported){var t=function(t){e._pointerEvent&&Ue[t.originalEvent.pointerType.toUpperCase()]?e.touchStartX=t.originalEvent.clientX:e._pointerEvent||(e.touchStartX=t.originalEvent.touches[0].clientX)},n=function(t){t.originalEvent.touches&&t.originalEvent.touches.length>1?e.touchDeltaX=0:e.touchDeltaX=t.originalEvent.touches[0].clientX-e.touchStartX},r=function(t){e._pointerEvent&&Ue[t.originalEvent.pointerType.toUpperCase()]&&(e.touchDeltaX=t.originalEvent.clientX-e.touchStartX),e._handleSwipe(),"hover"===e._config.pause&&(e.pause(),e.touchTimeout&&clearTimeout(e.touchTimeout),e.touchTimeout=setTimeout((function(t){return e.cycle(t)}),ae+e._config.interval))};o.default(this._element.querySelectorAll(Ie)).on(Te,(function(e){return e.preventDefault()})),this._pointerEvent?(o.default(this._element).on(ye,(function(e){return t(e)})),o.default(this._element).on(Ee,(function(e){return r(e)})),this._element.classList.add(qe)):(o.default(this._element).on(ge,(function(e){return t(e)})),o.default(this._element).on(Ae,(function(e){return n(e)})),o.default(this._element).on(_e,(function(e){return r(e)})))}},t._keydown=function(e){if(!/input|textarea/i.test(e.target.tagName))switch(e.which){case oe:e.preventDefault(),this.prev();break;case ie:e.preventDefault(),this.next()}},t._getItemIndex=function(e){return this._items=e&&e.parentNode?[].slice.call(e.parentNode.querySelectorAll(Be)):[],this._items.indexOf(e)},t._getItemByDirection=function(e,t){var n=e===ue,r=e===fe,o=this._getItemIndex(t),i=this._items.length-1;if((r&&0===o||n&&o===i)&&!this._config.wrap)return t;var a=(o+(e===fe?-1:1))%this._items.length;return-1===a?this._items[this._items.length-1]:this._items[a]},t._triggerSlideEvent=function(e,t){var n=this._getItemIndex(e),r=this._getItemIndex(this._element.querySelector(ke)),i=o.default.Event(he,{relatedTarget:e,direction:t,from:r,to:n});return o.default(this._element).trigger(i),i},t._setActiveIndicatorElement=function(e){if(this._indicatorsElement){var t=[].slice.call(this._indicatorsElement.querySelectorAll(We));o.default(t).removeClass(Le);var n=this._indicatorsElement.children[this._getItemIndex(e)];n&&o.default(n).addClass(Le)}},t._updateInterval=function(){var e=this._activeElement||this._element.querySelector(ke);if(e){var t=parseInt(e.getAttribute("data-interval"),10);t?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=t):this._config.interval=this._config.defaultInterval||this._config.interval}},t._slide=function(e,t){var n,r,i,a=this,c=this._element.querySelector(ke),s=this._getItemIndex(c),l=t||c&&this._getItemByDirection(e,c),u=this._getItemIndex(l),f=Boolean(this._interval);if(e===ue?(n=Se,r=Re,i=de):(n=we,r=xe,i=pe),l&&o.default(l).hasClass(Le))this._isSliding=!1;else if(!this._triggerSlideEvent(l,i).isDefaultPrevented()&&c&&l){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(l),this._activeElement=l;var d=o.default.Event(Me,{relatedTarget:l,direction:i,from:s,to:u});if(o.default(this._element).hasClass(Ce)){o.default(l).addClass(r),b.reflow(l),o.default(c).addClass(n),o.default(l).addClass(n);var p=b.getTransitionDurationFromElement(c);o.default(c).one(b.TRANSITION_END,(function(){o.default(l).removeClass(n+" "+r).addClass(Le),o.default(c).removeClass(Le+" "+r+" "+n),a._isSliding=!1,setTimeout((function(){return o.default(a._element).trigger(d)}),0)})).emulateTransitionEnd(p)}else o.default(c).removeClass(Le),o.default(l).addClass(Le),this._isSliding=!1,o.default(this._element).trigger(d);f&&this.cycle()}},e._jQueryInterface=function(t){return this.each((function(){var n=o.default(this).data(ee),r=s({},se,o.default(this).data());"object"==typeof t&&(r=s({},r,t));var i="string"==typeof t?t:r.slide;if(n||(n=new e(this,r),o.default(this).data(ee,n)),"number"==typeof t)n.to(t);else if("string"==typeof i){if(void 0===n[i])throw new TypeError('No method named "'+i+'"');n[i]()}else r.interval&&r.ride&&(n.pause(),n.cycle())}))},e._dataApiClickHandler=function(t){var n=b.getSelectorFromElement(this);if(n){var r=o.default(n)[0];if(r&&o.default(r).hasClass(ze)){var i=s({},o.default(r).data(),o.default(this).data()),a=this.getAttribute("data-slide-to");a&&(i.interval=!1),e._jQueryInterface.call(o.default(r),i),a&&o.default(r).data(ee).to(a),t.preventDefault()}}},c(e,null,[{key:"VERSION",get:function(){return J}},{key:"Default",get:function(){return se}}]),e}();o.default(document).on(Ne,Pe,He._dataApiClickHandler),o.default(window).on(Oe,(function(){for(var e=[].slice.call(document.querySelectorAll(je)),t=0,n=e.length;t0&&(this._selector=a,this._triggerArray.push(i))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var t=e.prototype;return t.toggle=function(){o.default(this._element).hasClass(ot)?this.hide():this.show()},t.show=function(){var t,n,r=this;if(!(this._isTransitioning||o.default(this._element).hasClass(ot)||(this._parent&&0===(t=[].slice.call(this._parent.querySelectorAll(ut)).filter((function(e){return"string"==typeof r._config.parent?e.getAttribute("data-parent")===r._config.parent:e.classList.contains(it)}))).length&&(t=null),t&&(n=o.default(t).not(this._selector).data(Ge))&&n._isTransitioning))){var i=o.default.Event(Je);if(o.default(this._element).trigger(i),!i.isDefaultPrevented()){t&&(e._jQueryInterface.call(o.default(t).not(this._selector),"hide"),n||o.default(t).data(Ge,null));var a=this._getDimension();o.default(this._element).removeClass(it).addClass(at),this._element.style[a]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass(ct).attr("aria-expanded",!0),this.setTransitioning(!0);var c=function(){o.default(r._element).removeClass(at).addClass(it+" "+ot),r._element.style[a]="",r.setTransitioning(!1),o.default(r._element).trigger(et)},s="scroll"+(a[0].toUpperCase()+a.slice(1)),l=b.getTransitionDurationFromElement(this._element);o.default(this._element).one(b.TRANSITION_END,c).emulateTransitionEnd(l),this._element.style[a]=this._element[s]+"px"}}},t.hide=function(){var e=this;if(!this._isTransitioning&&o.default(this._element).hasClass(ot)){var t=o.default.Event(tt);if(o.default(this._element).trigger(t),!t.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",b.reflow(this._element),o.default(this._element).addClass(at).removeClass(it+" "+ot);var r=this._triggerArray.length;if(r>0)for(var i=0;i0},t._getOffset=function(){var e=this,t={};return"function"==typeof this._config.offset?t.fn=function(t){return t.offsets=s({},t.offsets,e._config.offset(t.offsets,e._element)||{}),t}:t.offset=this._config.offset,t},t._getPopperConfig=function(){var e={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(e.modifiers.applyStyle={enabled:!1}),s({},e,this._config.popperConfig)},e._jQueryInterface=function(t){return this.each((function(){var n=o.default(this).data(Mt);if(n||(n=new e(this,"object"==typeof t?t:null),o.default(this).data(Mt,n)),"string"==typeof t){if(void 0===n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},e._clearMenus=function(t){if(!t||t.which!==Tt&&("keyup"!==t.type||t.which===_t))for(var n=[].slice.call(document.querySelectorAll(Pt)),r=0,i=n.length;r0&&a--,t.which===Et&&adocument.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn);var r=b.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(b.TRANSITION_END),o.default(this._element).one(b.TRANSITION_END,(function(){e._element.classList.remove(Cn),n||o.default(e._element).one(b.TRANSITION_END,(function(){e._element.style.overflowY=""})).emulateTransitionEnd(e._element,r)})).emulateTransitionEnd(r),this._element.focus()}},t._showElement=function(e){var t=this,n=o.default(this._element).hasClass(zn),r=this._dialog?this._dialog.querySelector(Sn):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass(En)&&r?r.scrollTop=0:this._element.scrollTop=0,n&&b.reflow(this._element),o.default(this._element).addClass(Ln),this._config.focus&&this._enforceFocus();var i=o.default.Event(Mn,{relatedTarget:e}),a=function(){t._config.focus&&t._element.focus(),t._isTransitioning=!1,o.default(t._element).trigger(i)};if(n){var c=b.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(b.TRANSITION_END,a).emulateTransitionEnd(c)}else a()},t._enforceFocus=function(){var e=this;o.default(document).off(vn).on(vn,(function(t){document!==t.target&&e._element!==t.target&&0===o.default(e._element).has(t.target).length&&e._element.focus()}))},t._setEscapeEvent=function(){var e=this;this._isShown?o.default(this._element).on(gn,(function(t){e._config.keyboard&&t.which===sn?(t.preventDefault(),e.hide()):e._config.keyboard||t.which!==sn||e._triggerBackdropTransition()})):this._isShown||o.default(this._element).off(gn)},t._setResizeEvent=function(){var e=this;this._isShown?o.default(window).on(bn,(function(t){return e.handleUpdate(t)})):o.default(window).off(bn)},t._hideModal=function(){var e=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass(Nn),e._resetAdjustments(),e._resetScrollbar(),o.default(e._element).trigger(pn)}))},t._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},t._showBackdrop=function(e){var t=this,n=o.default(this._element).hasClass(zn)?zn:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className=On,n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on(mn,(function(e){t._ignoreBackdropClick?t._ignoreBackdropClick=!1:e.target===e.currentTarget&&("static"===t._config.backdrop?t._triggerBackdropTransition():t.hide())})),n&&b.reflow(this._backdrop),o.default(this._backdrop).addClass(Ln),!e)return;if(!n)return void e();var r=b.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(b.TRANSITION_END,e).emulateTransitionEnd(r)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass(Ln);var i=function(){t._removeBackdrop(),e&&e()};if(o.default(this._element).hasClass(zn)){var a=b.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(b.TRANSITION_END,i).emulateTransitionEnd(a)}else i()}else e&&e()},t._adjustDialog=function(){var e=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(e.left+e.right)
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:In,popperConfig:null},er="show",tr="out",nr={HIDE:"hide"+$n,HIDDEN:"hidden"+$n,SHOW:"show"+$n,SHOWN:"shown"+$n,INSERTED:"inserted"+$n,CLICK:"click"+$n,FOCUSIN:"focusin"+$n,FOCUSOUT:"focusout"+$n,MOUSEENTER:"mouseenter"+$n,MOUSELEAVE:"mouseleave"+$n},rr="fade",or="show",ir=".tooltip-inner",ar=".arrow",cr="hover",sr="focus",lr="click",ur="manual",fr=function(){function e(e,t){if(void 0===i.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var t=e.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=o.default(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),o.default(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass(or))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var t=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(t);var n=b.findShadowRoot(this.element),r=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!r)return;var a=this.getTipElement(),c=b.getUID(this.constructor.NAME);a.setAttribute("id",c),this.element.setAttribute("aria-describedby",c),this.setContent(),this.config.animation&&o.default(a).addClass(rr);var s="function"==typeof this.config.placement?this.config.placement.call(this,a,this.element):this.config.placement,l=this._getAttachment(s);this.addAttachmentClass(l);var u=this._getContainer();o.default(a).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(a).appendTo(u),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new i.default(this.element,a,this._getPopperConfig(l)),o.default(a).addClass(or),o.default(a).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var f=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,o.default(e.element).trigger(e.constructor.Event.SHOWN),t===tr&&e._leave(null,e)};if(o.default(this.tip).hasClass(rr)){var d=b.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(b.TRANSITION_END,f).emulateTransitionEnd(d)}else f()}},t.hide=function(e){var t=this,n=this.getTipElement(),r=o.default.Event(this.constructor.Event.HIDE),i=function(){t._hoverState!==er&&n.parentNode&&n.parentNode.removeChild(n),t._cleanTipClass(),t.element.removeAttribute("aria-describedby"),o.default(t.element).trigger(t.constructor.Event.HIDDEN),null!==t._popper&&t._popper.destroy(),e&&e()};if(o.default(this.element).trigger(r),!r.isDefaultPrevented()){if(o.default(n).removeClass(or),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger[lr]=!1,this._activeTrigger[sr]=!1,this._activeTrigger[cr]=!1,o.default(this.tip).hasClass(rr)){var a=b.getTransitionDurationFromElement(n);o.default(n).one(b.TRANSITION_END,i).emulateTransitionEnd(a)}else i();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(e){o.default(this.getTipElement()).addClass(Vn+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},t.setContent=function(){var e=this.getTipElement();this.setElementContent(o.default(e.querySelectorAll(ir)),this.getTitle()),o.default(e).removeClass(rr+" "+or)},t.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=jn(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?o.default(t).parent().is(e)||e.empty().append(t):e.text(o.default(t).text())},t.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e||(e="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),e},t._getPopperConfig=function(e){var t=this;return s({},{placement:e,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:ar},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}},this.config.popperConfig)},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=s({},t.offsets,e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:b.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},t._getAttachment=function(e){return Qn[e.toUpperCase()]},t._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach((function(t){if("click"===t)o.default(e.element).on(e.constructor.Event.CLICK,e.config.selector,(function(t){return e.toggle(t)}));else if(t!==ur){var n=t===cr?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,r=t===cr?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;o.default(e.element).on(n,e.config.selector,(function(t){return e._enter(t)})).on(r,e.config.selector,(function(t){return e._leave(t)}))}})),this._hideModalHandler=function(){e.element&&e.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==e)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||o.default(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),o.default(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?sr:cr]=!0),o.default(t.getTipElement()).hasClass(or)||t._hoverState===er?t._hoverState=er:(clearTimeout(t._timeout),t._hoverState=er,t.config.delay&&t.config.delay.show?t._timeout=setTimeout((function(){t._hoverState===er&&t.show()}),t.config.delay.show):t.show())},t._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||o.default(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),o.default(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?sr:cr]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=tr,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout((function(){t._hoverState===tr&&t.hide()}),t.config.delay.hide):t.hide())},t._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},t._getConfig=function(e){var t=o.default(this.element).data();return Object.keys(t).forEach((function(e){-1!==Kn.indexOf(e)&&delete t[e]})),"number"==typeof(e=s({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),b.typeCheckConfig(Un,e,this.constructor.DefaultType),e.sanitize&&(e.template=jn(e.template,e.whiteList,e.sanitizeFn)),e},t._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},t._cleanTipClass=function(){var e=o.default(this.getTipElement()),t=e.attr("class").match(Yn);null!==t&&t.length&&e.removeClass(t.join(""))},t._handlePopperPlacementChange=function(e){this.tip=e.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},t._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(o.default(e).removeClass(rr),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},e._jQueryInterface=function(t){return this.each((function(){var n=o.default(this),r=n.data(Fn),i="object"==typeof t&&t;if((r||!/dispose|hide/.test(t))&&(r||(r=new e(this,i),n.data(Fn,r)),"string"==typeof t)){if(void 0===r[t])throw new TypeError('No method named "'+t+'"');r[t]()}}))},c(e,null,[{key:"VERSION",get:function(){return Hn}},{key:"Default",get:function(){return Jn}},{key:"NAME",get:function(){return Un}},{key:"DATA_KEY",get:function(){return Fn}},{key:"Event",get:function(){return nr}},{key:"EVENT_KEY",get:function(){return $n}},{key:"DefaultType",get:function(){return Zn}}]),e}();o.default.fn[Un]=fr._jQueryInterface,o.default.fn[Un].Constructor=fr,o.default.fn[Un].noConflict=function(){return o.default.fn[Un]=Gn,fr._jQueryInterface};var dr="popover",pr="4.6.0",hr="bs.popover",Mr="."+hr,vr=o.default.fn[dr],br="bs-popover",mr=new RegExp("(^|\\s)"+br+"\\S+","g"),gr=s({},fr.Default,{placement:"right",trigger:"click",content:"",template:''}),Ar=s({},fr.DefaultType,{content:"(string|element|function)"}),_r="fade",yr="show",Er=".popover-header",Tr=".popover-body",Or={HIDE:"hide"+Mr,HIDDEN:"hidden"+Mr,SHOW:"show"+Mr,SHOWN:"shown"+Mr,INSERTED:"inserted"+Mr,CLICK:"click"+Mr,FOCUSIN:"focusin"+Mr,FOCUSOUT:"focusout"+Mr,MOUSEENTER:"mouseenter"+Mr,MOUSELEAVE:"mouseleave"+Mr},Nr=function(e){function t(){return e.apply(this,arguments)||this}l(t,e);var n=t.prototype;return n.isWithContent=function(){return this.getTitle()||this._getContent()},n.addAttachmentClass=function(e){o.default(this.getTipElement()).addClass(br+"-"+e)},n.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},n.setContent=function(){var e=o.default(this.getTipElement());this.setElementContent(e.find(Er),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(Tr),t),e.removeClass(_r+" "+yr)},n._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},n._cleanTipClass=function(){var e=o.default(this.getTipElement()),t=e.attr("class").match(mr);null!==t&&t.length>0&&e.removeClass(t.join(""))},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(hr),r="object"==typeof e?e:null;if((n||!/dispose|hide/.test(e))&&(n||(n=new t(this,r),o.default(this).data(hr,n)),"string"==typeof e)){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},c(t,null,[{key:"VERSION",get:function(){return pr}},{key:"Default",get:function(){return gr}},{key:"NAME",get:function(){return dr}},{key:"DATA_KEY",get:function(){return hr}},{key:"Event",get:function(){return Or}},{key:"EVENT_KEY",get:function(){return Mr}},{key:"DefaultType",get:function(){return Ar}}]),t}(fr);o.default.fn[dr]=Nr._jQueryInterface,o.default.fn[dr].Constructor=Nr,o.default.fn[dr].noConflict=function(){return o.default.fn[dr]=vr,Nr._jQueryInterface};var zr="scrollspy",Lr="4.6.0",Cr="bs.scrollspy",wr="."+Cr,Sr=".data-api",Rr=o.default.fn[zr],xr={offset:10,method:"auto",target:""},qr={offset:"number",method:"string",target:"(string|element)"},Wr="activate"+wr,kr="scroll"+wr,Br="load"+wr+Sr,Ir="dropdown-item",Dr="active",Xr='[data-spy="scroll"]',Pr=".nav, .list-group",jr=".nav-link",Ur=".nav-item",Hr=".list-group-item",Fr=".dropdown",$r=".dropdown-item",Gr=".dropdown-toggle",Vr="offset",Yr="position",Kr=function(){function e(e,t){var n=this;this._element=e,this._scrollElement="BODY"===e.tagName?window:e,this._config=this._getConfig(t),this._selector=this._config.target+" "+jr+","+this._config.target+" "+Hr+","+this._config.target+" "+$r,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on(kr,(function(e){return n._process(e)})),this.refresh(),this._process()}var t=e.prototype;return t.refresh=function(){var e=this,t=this._scrollElement===this._scrollElement.window?Vr:Yr,n="auto"===this._config.method?t:this._config.method,r=n===Yr?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(e){var t,i=b.getSelectorFromElement(e);if(i&&(t=document.querySelector(i)),t){var a=t.getBoundingClientRect();if(a.width||a.height)return[o.default(t)[n]().top+r,i]}return null})).filter((function(e){return e})).sort((function(e,t){return e[0]-t[0]})).forEach((function(t){e._offsets.push(t[0]),e._targets.push(t[1])}))},t.dispose=function(){o.default.removeData(this._element,Cr),o.default(this._scrollElement).off(wr),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},t._getConfig=function(e){if("string"!=typeof(e=s({},xr,"object"==typeof e&&e?e:{})).target&&b.isElement(e.target)){var t=o.default(e.target).attr("id");t||(t=b.getUID(zr),o.default(e.target).attr("id",t)),e.target="#"+t}return b.typeCheckConfig(zr,e,qr),e},t._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},t._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},t._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},t._process=function(){var e=this._getScrollTop()+this._config.offset,t=this._getScrollHeight(),n=this._config.offset+t-this._getOffsetHeight();if(this._scrollHeight!==t&&this.refresh(),e>=n){var r=this._targets[this._targets.length-1];this._activeTarget!==r&&this._activate(r)}else{if(this._activeTarget&&e0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&e>=this._offsets[o]&&(void 0===this._offsets[o+1]||e{"use strict";n.d(t,{Z:()=>i});var r=n(3645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,'.vjs-checkbox{color:#1f2d3d;left:-30px;position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vjs-checkbox.is-checked .vjs-checkbox__inner{background-color:#1890ff;border-color:#0076e4}.vjs-checkbox.is-checked .vjs-checkbox__inner:after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.vjs-checkbox .vjs-checkbox__inner{background-color:#fff;border:1px solid #bfcbd9;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer;display:inline-block;height:16px;position:relative;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);-o-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);vertical-align:middle;width:16px;z-index:1}.vjs-checkbox .vjs-checkbox__inner:after{border:2px solid #fff;border-left:0;border-top:0;-webkit-box-sizing:content-box;box-sizing:content-box;content:"";height:8px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);-webkit-transform-origin:center;transform-origin:center;-webkit-transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;-o-transition:transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) .05s,-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;width:4px}.vjs-checkbox .vjs-checkbox__original{bottom:0;left:0;margin:0;opacity:0;outline:none;position:absolute;right:0;top:0;z-index:-1}.vjs-radio{color:#1f2d3d;left:-30px;position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vjs-radio.is-checked .vjs-radio__inner{background-color:#1890ff;border-color:#0076e4}.vjs-radio.is-checked .vjs-radio__inner:after{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.vjs-radio .vjs-radio__inner{background-color:#fff;border:1px solid #bfcbd9;border-radius:100%;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer;display:inline-block;height:16px;position:relative;vertical-align:middle;width:16px}.vjs-radio .vjs-radio__inner:after{background-color:#fff;border-radius:100%;content:"";height:4px;left:50%;position:absolute;top:50%;-webkit-transform:translate(-50%,-50%) scale(0);transform:translate(-50%,-50%) scale(0);-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;-o-transition:transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in;width:4px}.vjs-radio .vjs-radio__original{bottom:0;left:0;margin:0;opacity:0;outline:none;position:absolute;right:0;top:0;z-index:-1}.vjs-tree{font-family:Monaco,Menlo,Consolas,Bitstream Vera Sans Mono,monospace;font-size:14px}.vjs-tree.is-root{position:relative}.vjs-tree.is-root.has-selectable-control{margin-left:30px}.vjs-tree.is-mouseover{background-color:#e6f7ff}.vjs-tree.is-highlight-selected{background-color:#ccefff}.vjs-tree .vjs-tree__content{padding-left:1em}.vjs-tree .vjs-tree__content.has-line{border-left:1px dotted #bfcbd9}.vjs-tree .vjs-tree__brackets{cursor:pointer}.vjs-tree .vjs-tree__brackets:hover{color:#1890ff}.vjs-tree .vjs-comment{color:#bfcbd9}.vjs-tree .vjs-value__null{color:#ff4949}.vjs-tree .vjs-value__boolean,.vjs-tree .vjs-value__number{color:#1d8ce0}.vjs-tree .vjs-value__string{color:#13ce66}',""]);const i=o},7543:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,"#alertModal{background:rgba(0,0,0,.5);z-index:99999}",""]);const i=o},361:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,".highlight[data-v-71bb8c56]{background-color:#ff647a}",""]);const i=o},2002:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,"td[data-v-401b7eee]{vertical-align:middle!important}",""]);const i=o},1776:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,"pre.sf-dump,pre.sf-dump .sf-dump-default{background:none!important}pre.sf-dump{margin-bottom:0!important;padding-left:0!important}.entryPointDescription a{color:#fff;font:12px Menlo,Monaco,Consolas,monospace;text-decoration:underline}",""]);const i=o},2830:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,"iframe[data-v-aee1481a]{border:none}",""]);const i=o},3645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=e(t);return t[2]?"@media ".concat(t[2]," {").concat(n,"}"):n})).join("")},t.i=function(e,n,r){"string"==typeof e&&(e=[[null,e,""]]);var o={};if(r)for(var i=0;i0&&t-1 in e)}T.fn=T.prototype={jquery:E,constructor:T,length:0,toArray:function(){return c.call(this)},get:function(e){return null==e?c.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=T.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return T.each(this,e)},map:function(e){return this.pushStack(T.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(T.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(T.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|[\\x20\\t\\r\\n\\f])[\\x20\\t\\r\\n\\f]*"),F=new RegExp(B+"|>"),$=new RegExp(X),G=new RegExp("^"+I+"$"),V={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+D),PSEUDO:new RegExp("^"+X),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\([\\x20\\t\\r\\n\\f]*(even|odd|(([+-]|)(\\d*)n|)[\\x20\\t\\r\\n\\f]*(?:([+-]|)[\\x20\\t\\r\\n\\f]*(\\d+)|))[\\x20\\t\\r\\n\\f]*\\)|)","i"),bool:new RegExp("^(?:"+k+")$","i"),needsContext:new RegExp("^[\\x20\\t\\r\\n\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\([\\x20\\t\\r\\n\\f]*((?:-\\d)?\\d*)[\\x20\\t\\r\\n\\f]*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,K=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}[\\x20\\t\\r\\n\\f]?|\\\\([^\\r\\n\\f])","g"),ne=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))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,oe=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},ie=function(){d()},ae=Ae((function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{x.apply(w=q.call(_.childNodes),_.childNodes),w[_.childNodes.length].nodeType}catch(e){x={apply:w.length?function(e,t){R.apply(e,q.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function ce(e,t,r,o){var i,c,l,u,f,h,b,m=t&&t.ownerDocument,_=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==_&&9!==_&&11!==_)return r;if(!o&&(d(t),t=t||p,M)){if(11!==_&&(f=J.exec(e)))if(i=f[1]){if(9===_){if(!(l=t.getElementById(i)))return r;if(l.id===i)return r.push(l),r}else if(m&&(l=m.getElementById(i))&&g(t,l)&&l.id===i)return r.push(l),r}else{if(f[2])return x.apply(r,t.getElementsByTagName(e)),r;if((i=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return x.apply(r,t.getElementsByClassName(i)),r}if(n.qsa&&!z[e+" "]&&(!v||!v.test(e))&&(1!==_||"object"!==t.nodeName.toLowerCase())){if(b=e,m=t,1===_&&(F.test(e)||H.test(e))){for((m=ee.test(e)&&be(t.parentNode)||t)===t&&n.scope||((u=t.getAttribute("id"))?u=u.replace(re,oe):t.setAttribute("id",u=A)),c=(h=a(e)).length;c--;)h[c]=(u?"#"+u:":scope")+" "+ge(h[c]);b=h.join(",")}try{return x.apply(r,m.querySelectorAll(b)),r}catch(t){z(e,!0)}finally{u===A&&t.removeAttribute("id")}}}return s(e.replace(j,"$1"),t,r,o)}function se(){var e=[];return function t(n,o){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=o}}function le(e){return e[A]=!0,e}function ue(e){var t=p.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){for(var n=e.split("|"),o=n.length;o--;)r.attrHandle[n[o]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function pe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function he(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function Me(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function ve(e){return le((function(t){return t=+t,le((function(n,r){for(var o,i=e([],n.length,t),a=i.length;a--;)n[o=i[a]]&&(n[o]=!(r[o]=n[o]))}))}))}function be(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=ce.support={},i=ce.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},d=ce.setDocument=function(e){var t,o,a=e?e.ownerDocument||e:_;return a!=p&&9===a.nodeType&&a.documentElement?(h=(p=a).documentElement,M=!i(p),_!=p&&(o=p.defaultView)&&o.top!==o&&(o.addEventListener?o.addEventListener("unload",ie,!1):o.attachEvent&&o.attachEvent("onunload",ie)),n.scope=ue((function(e){return h.appendChild(e).appendChild(p.createElement("div")),void 0!==e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length})),n.attributes=ue((function(e){return e.className="i",!e.getAttribute("className")})),n.getElementsByTagName=ue((function(e){return e.appendChild(p.createComment("")),!e.getElementsByTagName("*").length})),n.getElementsByClassName=Q.test(p.getElementsByClassName),n.getById=ue((function(e){return h.appendChild(e).id=A,!p.getElementsByName||!p.getElementsByName(A).length})),n.getById?(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&M){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&M){var n,r,o,i=t.getElementById(e);if(i){if((n=i.getAttributeNode("id"))&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if((n=i.getAttributeNode("id"))&&n.value===e)return[i]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if("*"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&M)return t.getElementsByClassName(e)},b=[],v=[],(n.qsa=Q.test(p.querySelectorAll))&&(ue((function(e){var t;h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\[[\\x20\\t\\r\\n\\f]*(?:value|"+k+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=p.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\[[\\x20\\t\\r\\n\\f]*name[\\x20\\t\\r\\n\\f]*=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")})),ue((function(e){e.innerHTML="";var t=p.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name[\\x20\\t\\r\\n\\f]*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")}))),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue((function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),b.push("!=",X)})),v=v.length&&new RegExp(v.join("|")),b=b.length&&new RegExp(b.join("|")),t=Q.test(h.compareDocumentPosition),g=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},L=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e==p||e.ownerDocument==_&&g(_,e)?-1:t==p||t.ownerDocument==_&&g(_,t)?1:u?W(u,e)-W(u,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],c=[t];if(!o||!i)return e==p?-1:t==p?1:o?-1:i?1:u?W(u,e)-W(u,t):0;if(o===i)return de(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)c.unshift(n);for(;a[r]===c[r];)r++;return r?de(a[r],c[r]):a[r]==_?-1:c[r]==_?1:0},p):p},ce.matches=function(e,t){return ce(e,null,null,t)},ce.matchesSelector=function(e,t){if(d(e),n.matchesSelector&&M&&!z[t+" "]&&(!b||!b.test(t))&&(!v||!v.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){z(t,!0)}return ce(t,p,null,[e]).length>0},ce.contains=function(e,t){return(e.ownerDocument||e)!=p&&d(e),g(e,t)},ce.attr=function(e,t){(e.ownerDocument||e)!=p&&d(e);var o=r.attrHandle[t.toLowerCase()],i=o&&C.call(r.attrHandle,t.toLowerCase())?o(e,t,!M):void 0;return void 0!==i?i:n.attributes||!M?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null},ce.escape=function(e){return(e+"").replace(re,oe)},ce.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},ce.uniqueSort=function(e){var t,r=[],o=0,i=0;if(f=!n.detectDuplicates,u=!n.sortStable&&e.slice(0),e.sort(L),f){for(;t=e[i++];)t===e[i]&&(o=r.push(i));for(;o--;)e.splice(r[o],1)}return u=null,e},o=ce.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=o(t);return n},r=ce.selectors={cacheLength:50,createPseudo:le,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===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]||ce.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]&&ce.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&$.test(n)&&(t=a(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(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=T[e+" "];return t||(t=new RegExp("(^|[\\x20\\t\\r\\n\\f])"+e+"("+B+"|$)"))&&T(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,n){return function(r){var o=ce.attr(r,e);return null==o?"!="===t:!t||(o+="","="===t?o===n:"!="===t?o!==n:"^="===t?n&&0===o.indexOf(n):"*="===t?n&&o.indexOf(n)>-1:"$="===t?n&&o.slice(-n.length)===n:"~="===t?(" "+o.replace(P," ")+" ").indexOf(n)>-1:"|="===t&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,o){var i="nth"!==e.slice(0,3),a="last"!==e.slice(-4),c="of-type"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,s){var l,u,f,d,p,h,M=i!==a?"nextSibling":"previousSibling",v=t.parentNode,b=c&&t.nodeName.toLowerCase(),m=!s&&!c,g=!1;if(v){if(i){for(;M;){for(d=t;d=d[M];)if(c?d.nodeName.toLowerCase()===b:1===d.nodeType)return!1;h=M="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?v.firstChild:v.lastChild],a&&m){for(g=(p=(l=(u=(f=(d=v)[A]||(d[A]={}))[d.uniqueID]||(f[d.uniqueID]={}))[e]||[])[0]===y&&l[1])&&l[2],d=p&&v.childNodes[p];d=++p&&d&&d[M]||(g=p=0)||h.pop();)if(1===d.nodeType&&++g&&d===t){u[e]=[y,p,g];break}}else if(m&&(g=p=(l=(u=(f=(d=t)[A]||(d[A]={}))[d.uniqueID]||(f[d.uniqueID]={}))[e]||[])[0]===y&&l[1]),!1===g)for(;(d=++p&&d&&d[M]||(g=p=0)||h.pop())&&((c?d.nodeName.toLowerCase()!==b:1!==d.nodeType)||!++g||(m&&((u=(f=d[A]||(d[A]={}))[d.uniqueID]||(f[d.uniqueID]={}))[e]=[y,g]),d!==t)););return(g-=o)===r||g%r==0&&g/r>=0}}},PSEUDO:function(e,t){var n,o=r.pseudos[e]||r.setFilters[e.toLowerCase()]||ce.error("unsupported pseudo: "+e);return o[A]?o(t):o.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?le((function(e,n){for(var r,i=o(e,t),a=i.length;a--;)e[r=W(e,i[a])]=!(n[r]=i[a])})):function(e){return o(e,0,n)}):o}},pseudos:{not:le((function(e){var t=[],n=[],r=c(e.replace(j,"$1"));return r[A]?le((function(e,t,n,o){for(var i,a=r(e,null,o,[]),c=e.length;c--;)(i=a[c])&&(e[c]=!(t[c]=i))})):function(e,o,i){return t[0]=e,r(t,null,i,n),t[0]=null,!n.pop()}})),has:le((function(e){return function(t){return ce(e,t).length>0}})),contains:le((function(e){return e=e.replace(te,ne),function(t){return(t.textContent||o(t)).indexOf(e)>-1}})),lang:le((function(e){return G.test(e||"")||ce.error("unsupported lang: "+e),e=e.replace(te,ne).toLowerCase(),function(t){var n;do{if(n=M?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:Me(!1),disabled:Me(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Z.test(e.nodeName)},input:function(e){return K.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve((function(){return[0]})),last:ve((function(e,t){return[t-1]})),eq:ve((function(e,t,n){return[n<0?n+t:n]})),even:ve((function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e})),gt:ve((function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function ye(e,t,n,r,o){for(var i,a=[],c=0,s=e.length,l=null!=t;c-1&&(i[l]=!(a[l]=f))}}else b=ye(b===a?b.splice(h,b.length):b),o?o(null,a,b,s):x.apply(a,b)}))}function Te(e){for(var t,n,o,i=e.length,a=r.relative[e[0].type],c=a||r.relative[" "],s=a?1:0,u=Ae((function(e){return e===t}),c,!0),f=Ae((function(e){return W(t,e)>-1}),c,!0),d=[function(e,n,r){var o=!a&&(r||n!==l)||((t=n).nodeType?u(e,n,r):f(e,n,r));return t=null,o}];s1&&_e(d),s>1&&ge(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(j,"$1"),n,s0,o=e.length>0,i=function(i,a,c,s,u){var f,h,v,b=0,m="0",g=i&&[],A=[],_=l,E=i||o&&r.find.TAG("*",u),T=y+=null==_?1:Math.random()||.1,O=E.length;for(u&&(l=a==p||a||u);m!==O&&null!=(f=E[m]);m++){if(o&&f){for(h=0,a||f.ownerDocument==p||(d(f),c=!M);v=e[h++];)if(v(f,a||p,c)){s.push(f);break}u&&(y=T)}n&&((f=!v&&f)&&b--,i&&g.push(f))}if(b+=m,n&&m!==b){for(h=0;v=t[h++];)v(g,A,a,c);if(i){if(b>0)for(;m--;)g[m]||A[m]||(A[m]=S.call(s));A=ye(A)}x.apply(s,A),u&&!i&&A.length>0&&b+t.length>1&&ce.uniqueSort(s)}return u&&(y=T,l=_),g};return n?le(i):i}(i,o)),c.selector=e}return c},s=ce.select=function(e,t,n,o){var i,s,l,u,f,d="function"==typeof e&&e,p=!o&&a(e=d.selector||e);if(n=n||[],1===p.length){if((s=p[0]=p[0].slice(0)).length>2&&"ID"===(l=s[0]).type&&9===t.nodeType&&M&&r.relative[s[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(te,ne),t)||[])[0]))return n;d&&(t=t.parentNode),e=e.slice(s.shift().value.length)}for(i=V.needsContext.test(e)?0:s.length;i--&&(l=s[i],!r.relative[u=l.type]);)if((f=r.find[u])&&(o=f(l.matches[0].replace(te,ne),ee.test(s[0].type)&&be(t.parentNode)||t))){if(s.splice(i,1),!(e=o.length&&ge(s)))return x.apply(n,o),n;break}}return(d||c(e,p))(o,t,!M,n,!t||ee.test(e)&&be(t.parentNode)||t),n},n.sortStable=A.split("").sort(L).join("")===A,n.detectDuplicates=!!f,d(),n.sortDetached=ue((function(e){return 1&e.compareDocumentPosition(p.createElement("fieldset"))})),ue((function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")}))||fe("type|href|height|width",(function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)})),n.attributes&&ue((function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}))||fe("value",(function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue})),ue((function(e){return null==e.getAttribute("disabled")}))||fe(k,(function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null})),ce}(r);T.find=N,T.expr=N.selectors,T.expr[":"]=T.expr.pseudos,T.uniqueSort=T.unique=N.uniqueSort,T.text=N.getText,T.isXMLDoc=N.isXML,T.contains=N.contains,T.escapeSelector=N.escape;var z=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&T(e).is(n))break;r.push(e)}return r},L=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},C=T.expr.match.needsContext;function w(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var S=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function R(e,t,n){return b(t)?T.grep(e,(function(e,r){return!!t.call(e,r,e)!==n})):t.nodeType?T.grep(e,(function(e){return e===t!==n})):"string"!=typeof t?T.grep(e,(function(e){return u.call(t,e)>-1!==n})):T.filter(t,e,n)}T.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?T.find.matchesSelector(r,e)?[r]:[]:T.find.matches(e,T.grep(t,(function(e){return 1===e.nodeType})))},T.fn.extend({find:function(e){var t,n,r=this.length,o=this;if("string"!=typeof e)return this.pushStack(T(e).filter((function(){for(t=0;t1?T.uniqueSort(n):n},filter:function(e){return this.pushStack(R(this,e||[],!1))},not:function(e){return this.pushStack(R(this,e||[],!0))},is:function(e){return!!R(this,"string"==typeof e&&C.test(e)?T(e):e||[],!1).length}});var x,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||x,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:q.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 T?t[0]:t,T.merge(this,T.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:g,!0)),S.test(r[1])&&T.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(o=g.getElementById(r[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(T):T.makeArray(e,this)}).prototype=T.fn,x=T(g);var W=/^(?:parents|prev(?:Until|All))/,k={children:!0,contents:!0,next:!0,prev:!0};function B(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&T.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?T.uniqueSort(i):i)},index:function(e){return e?"string"==typeof e?u.call(T(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(T.uniqueSort(T.merge(this.get(),T(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),T.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return z(e,"parentNode")},parentsUntil:function(e,t,n){return z(e,"parentNode",n)},next:function(e){return B(e,"nextSibling")},prev:function(e){return B(e,"previousSibling")},nextAll:function(e){return z(e,"nextSibling")},prevAll:function(e){return z(e,"previousSibling")},nextUntil:function(e,t,n){return z(e,"nextSibling",n)},prevUntil:function(e,t,n){return z(e,"previousSibling",n)},siblings:function(e){return L((e.parentNode||{}).firstChild,e)},children:function(e){return L(e.firstChild)},contents:function(e){return null!=e.contentDocument&&a(e.contentDocument)?e.contentDocument:(w(e,"template")&&(e=e.content||e),T.merge([],e.childNodes))}},(function(e,t){T.fn[e]=function(n,r){var o=T.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=T.filter(r,o)),this.length>1&&(k[e]||T.uniqueSort(o),W.test(e)&&o.reverse()),this.pushStack(o)}}));var I=/[^\x20\t\r\n\f]+/g;function D(e){return e}function X(e){throw e}function P(e,t,n,r){var o;try{e&&b(o=e.promise)?o.call(e).done(t).fail(n):e&&b(o=e.then)?o.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}T.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return T.each(e.match(I)||[],(function(e,n){t[n]=!0})),t}(e):T.extend({},e);var t,n,r,o,i=[],a=[],c=-1,s=function(){for(o=o||e.once,r=t=!0;a.length;c=-1)for(n=a.shift();++c-1;)i.splice(n,1),n<=c&&c--})),this},has:function(e){return e?T.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=a=[],n||t||(i=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||s()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},T.extend({Deferred:function(e){var t=[["notify","progress",T.Callbacks("memory"),T.Callbacks("memory"),2],["resolve","done",T.Callbacks("once memory"),T.Callbacks("once memory"),0,"resolved"],["reject","fail",T.Callbacks("once memory"),T.Callbacks("once memory"),1,"rejected"]],n="pending",o={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return T.Deferred((function(n){T.each(t,(function(t,r){var o=b(e[r[4]])&&e[r[4]];i[r[1]]((function(){var e=o&&o.apply(this,arguments);e&&b(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,o?[e]:arguments)}))})),e=null})).promise()},then:function(e,n,o){var i=0;function a(e,t,n,o){return function(){var c=this,s=arguments,l=function(){var r,l;if(!(e=i&&(n!==X&&(c=void 0,s=[r]),t.rejectWith(c,s))}};e?u():(T.Deferred.getStackHook&&(u.stackTrace=T.Deferred.getStackHook()),r.setTimeout(u))}}return T.Deferred((function(r){t[0][3].add(a(0,r,b(o)?o:D,r.notifyWith)),t[1][3].add(a(0,r,b(e)?e:D)),t[2][3].add(a(0,r,b(n)?n:X))})).promise()},promise:function(e){return null!=e?T.extend(e,o):o}},i={};return T.each(t,(function(e,r){var a=r[2],c=r[5];o[r[1]]=a.add,c&&a.add((function(){n=c}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(r[3].fire),i[r[0]]=function(){return i[r[0]+"With"](this===i?void 0:this,arguments),this},i[r[0]+"With"]=a.fireWith})),o.promise(i),e&&e.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=c.call(arguments),i=T.Deferred(),a=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?c.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(P(e,i.done(a(n)).resolve,i.reject,!t),"pending"===i.state()||b(o[n]&&o[n].then)))return i.then();for(;n--;)P(o[n],a(n),i.reject);return i.promise()}});var j=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;T.Deferred.exceptionHook=function(e,t){r.console&&r.console.warn&&e&&j.test(e.name)&&r.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},T.readyException=function(e){r.setTimeout((function(){throw e}))};var U=T.Deferred();function H(){g.removeEventListener("DOMContentLoaded",H),r.removeEventListener("load",H),T.ready()}T.fn.ready=function(e){return U.then(e).catch((function(e){T.readyException(e)})),this},T.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--T.readyWait:T.isReady)||(T.isReady=!0,!0!==e&&--T.readyWait>0||U.resolveWith(g,[T]))}}),T.ready.then=U.then,"complete"===g.readyState||"loading"!==g.readyState&&!g.documentElement.doScroll?r.setTimeout(T.ready):(g.addEventListener("DOMContentLoaded",H),r.addEventListener("load",H));var F=function(e,t,n,r,o,i,a){var c=0,s=e.length,l=null==n;if("object"===y(n))for(c in o=!0,n)F(e,t,c,n[c],!0,i,a);else if(void 0!==r&&(o=!0,b(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(T(e),n)})),t))for(;c1,null,!0)},removeData:function(e){return this.each((function(){J.remove(this,e)}))}}),T.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,T.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=T.queue(e,t),r=n.length,o=n.shift(),i=T._queueHooks(e,t);"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===t&&n.unshift("inprogress"),delete i.stop,o.call(e,(function(){T.dequeue(e,t)}),i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:T.Callbacks("once memory").add((function(){Q.remove(e,[t+"queue",n])}))})}}),T.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,me=/^$|^module$|\/(?:java|ecma)script/i;he=g.createDocumentFragment().appendChild(g.createElement("div")),(Me=g.createElement("input")).setAttribute("type","radio"),Me.setAttribute("checked","checked"),Me.setAttribute("name","t"),he.appendChild(Me),v.checkClone=he.cloneNode(!0).cloneNode(!0).lastChild.checked,he.innerHTML="",v.noCloneChecked=!!he.cloneNode(!0).lastChild.defaultValue,he.innerHTML="",v.option=!!he.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Ae(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&w(e,t)?T.merge([e],n):n}function _e(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|&#?\w+;/;function Ee(e,t,n,r,o){for(var i,a,c,s,l,u,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p-1)o&&o.push(i);else if(l=ce(i),a=Ae(f.appendChild(i),"script"),l&&_e(a),n)for(u=0;i=a[u++];)me.test(i.type||"")&&n.push(i);return f}var Te=/^([^.]*)(?:\.(.+)|)/;function Oe(){return!0}function Ne(){return!1}function ze(e,t){return e===function(){try{return g.activeElement}catch(e){}}()==("focus"===t)}function Le(e,t,n,r,o,i){var a,c;if("object"==typeof t){for(c in"string"!=typeof n&&(r=r||n,n=void 0),t)Le(e,c,n,r,t[c],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),!1===o)o=Ne;else if(!o)return e;return 1===i&&(a=o,o=function(e){return T().off(e),a.apply(this,arguments)},o.guid=a.guid||(a.guid=T.guid++)),e.each((function(){T.event.add(this,t,o,r,n)}))}function Ce(e,t,n){n?(Q.set(e,t,!1),T.event.add(e,t,{namespace:!1,handler:function(e){var r,o,i=Q.get(this,t);if(1&e.isTrigger&&this[t]){if(i.length)(T.event.special[t]||{}).delegateType&&e.stopPropagation();else if(i=c.call(arguments),Q.set(this,t,i),r=n(this,t),this[t](),i!==(o=Q.get(this,t))||r?Q.set(this,t,!1):o={},i!==o)return e.stopImmediatePropagation(),e.preventDefault(),o&&o.value}else i.length&&(Q.set(this,t,{value:T.event.trigger(T.extend(i[0],T.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,t)&&T.event.add(e,t,Oe)}T.event={global:{},add:function(e,t,n,r,o){var i,a,c,s,l,u,f,d,p,h,M,v=Q.get(e);if(K(e))for(n.handler&&(n=(i=n).handler,o=i.selector),o&&T.find.matchesSelector(ae,o),n.guid||(n.guid=T.guid++),(s=v.events)||(s=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(t){return void 0!==T&&T.event.triggered!==t.type?T.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(I)||[""]).length;l--;)p=M=(c=Te.exec(t[l])||[])[1],h=(c[2]||"").split(".").sort(),p&&(f=T.event.special[p]||{},p=(o?f.delegateType:f.bindType)||p,f=T.event.special[p]||{},u=T.extend({type:p,origType:M,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&T.expr.match.needsContext.test(o),namespace:h.join(".")},i),(d=s[p])||((d=s[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(p,a)),f.add&&(f.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,u):d.push(u),T.event.global[p]=!0)},remove:function(e,t,n,r,o){var i,a,c,s,l,u,f,d,p,h,M,v=Q.hasData(e)&&Q.get(e);if(v&&(s=v.events)){for(l=(t=(t||"").match(I)||[""]).length;l--;)if(p=M=(c=Te.exec(t[l])||[])[1],h=(c[2]||"").split(".").sort(),p){for(f=T.event.special[p]||{},d=s[p=(r?f.delegateType:f.bindType)||p]||[],c=c[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=i=d.length;i--;)u=d[i],!o&&M!==u.origType||n&&n.guid!==u.guid||c&&!c.test(u.namespace)||r&&r!==u.selector&&("**"!==r||!u.selector)||(d.splice(i,1),u.selector&&d.delegateCount--,f.remove&&f.remove.call(e,u));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||T.removeEvent(e,p,v.handle),delete s[p])}else for(p in s)T.event.remove(e,p+t[l],n,r,!0);T.isEmptyObject(s)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,o,i,a,c=new Array(arguments.length),s=T.event.fix(e),l=(Q.get(this,"events")||Object.create(null))[s.type]||[],u=T.event.special[s.type]||{};for(c[0]=s,t=1;t=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(i=[],a={},n=0;n-1:T.find(o,this,null,[l]).length),a[o]&&i.push(r);i.length&&c.push({elem:l,handlers:i})}return l=this,s\s*$/g;function xe(e,t){return w(e,"table")&&w(11!==t.nodeType?t:t.firstChild,"tr")&&T(e).children("tbody")[0]||e}function qe(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 ke(e,t){var n,r,o,i,a,c;if(1===t.nodeType){if(Q.hasData(e)&&(c=Q.get(e).events))for(o in Q.remove(t,"handle events"),c)for(n=0,r=c[o].length;n1&&"string"==typeof h&&!v.checkClone&&Se.test(h))return e.each((function(o){var i=e.eq(o);M&&(t[0]=h.call(this,o,i.html())),Ie(i,t,n,r)}));if(d&&(i=(o=Ee(t,e[0].ownerDocument,!1,e,r)).firstChild,1===o.childNodes.length&&(o=i),i||r)){for(c=(a=T.map(Ae(o,"script"),qe)).length;f0&&_e(a,!s&&Ae(e,"script")),c},cleanData:function(e){for(var t,n,r,o=T.event.special,i=0;void 0!==(n=e[i]);i++)if(K(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)o[r]?T.event.remove(n,r):T.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),T.fn.extend({detach:function(e){return De(this,e,!0)},remove:function(e){return De(this,e)},text:function(e){return F(this,(function(e){return void 0===e?T.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Ie(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||xe(this,e).appendChild(e)}))},prepend:function(){return Ie(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=xe(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Ie(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Ie(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(T.cleanData(Ae(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return T.clone(this,e,t)}))},html:function(e){return F(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!we.test(e)&&!ge[(be.exec(e)||["",""])[1].toLowerCase()]){e=T.htmlPrefilter(e);try{for(;n=0&&(s+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-i-s-c-.5))||0),s}function nt(e,t,n){var r=Pe(e),o=(!v.boxSizingReliable()||n)&&"border-box"===T.css(e,"boxSizing",!1,r),i=o,a=He(e,t,r),c="offset"+t[0].toUpperCase()+t.slice(1);if(Xe.test(a)){if(!n)return a;a="auto"}return(!v.boxSizingReliable()&&o||!v.reliableTrDimensions()&&w(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===T.css(e,"display",!1,r))&&e.getClientRects().length&&(o="border-box"===T.css(e,"boxSizing",!1,r),(i=c in e)&&(a=e[c])),(a=parseFloat(a)||0)+tt(e,t,n||(o?"border":"content"),i,r,a)+"px"}function rt(e,t,n,r,o){return new rt.prototype.init(e,t,n,r,o)}T.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=He(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,i,a,c=Y(t),s=Ze.test(t),l=e.style;if(s||(t=Ye(c)),a=T.cssHooks[t]||T.cssHooks[c],void 0===n)return a&&"get"in a&&void 0!==(o=a.get(e,!1,r))?o:l[t];"string"===(i=typeof n)&&(o=oe.exec(n))&&o[1]&&(n=ue(e,t,o),i="number"),null!=n&&n==n&&("number"!==i||s||(n+=o&&o[3]||(T.cssNumber[c]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(s?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var o,i,a,c=Y(t);return Ze.test(t)||(t=Ye(c)),(a=T.cssHooks[t]||T.cssHooks[c])&&"get"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=He(e,t,r)),"normal"===o&&t in Je&&(o=Je[t]),""===n||n?(i=parseFloat(o),!0===n||isFinite(i)?i||0:o):o}}),T.each(["height","width"],(function(e,t){T.cssHooks[t]={get:function(e,n,r){if(n)return!Ke.test(T.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?nt(e,t,r):je(e,Qe,(function(){return nt(e,t,r)}))},set:function(e,n,r){var o,i=Pe(e),a=!v.scrollboxSize()&&"absolute"===i.position,c=(a||r)&&"border-box"===T.css(e,"boxSizing",!1,i),s=r?tt(e,t,r,c,i):0;return c&&a&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(i[t])-tt(e,t,"border",!1,i)-.5)),s&&(o=oe.exec(n))&&"px"!==(o[3]||"px")&&(e.style[t]=n,n=T.css(e,t)),et(0,n,s)}}})),T.cssHooks.marginLeft=Fe(v.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(He(e,"marginLeft"))||e.getBoundingClientRect().left-je(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),T.each({margin:"",padding:"",border:"Width"},(function(e,t){T.cssHooks[e+t]={expand:function(n){for(var r=0,o={},i="string"==typeof n?n.split(" "):[n];r<4;r++)o[e+ie[r]+t]=i[r]||i[r-2]||i[0];return o}},"margin"!==e&&(T.cssHooks[e+t].set=et)})),T.fn.extend({css:function(e,t){return F(this,(function(e,t,n){var r,o,i={},a=0;if(Array.isArray(t)){for(r=Pe(e),o=t.length;a1)}}),T.Tween=rt,rt.prototype={constructor:rt,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||T.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(T.cssNumber[n]?"":"px")},cur:function(){var e=rt.propHooks[this.prop];return e&&e.get?e.get(this):rt.propHooks._default.get(this)},run:function(e){var t,n=rt.propHooks[this.prop];return this.options.duration?this.pos=t=T.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rt.propHooks._default.set(this),this}},rt.prototype.init.prototype=rt.prototype,rt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=T.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){T.fx.step[e.prop]?T.fx.step[e.prop](e):1!==e.elem.nodeType||!T.cssHooks[e.prop]&&null==e.elem.style[Ye(e.prop)]?e.elem[e.prop]=e.now:T.style(e.elem,e.prop,e.now+e.unit)}}},rt.propHooks.scrollTop=rt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},T.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},T.fx=rt.prototype.init,T.fx.step={};var ot,it,at=/^(?:toggle|show|hide)$/,ct=/queueHooks$/;function st(){it&&(!1===g.hidden&&r.requestAnimationFrame?r.requestAnimationFrame(st):r.setTimeout(st,T.fx.interval),T.fx.tick())}function lt(){return r.setTimeout((function(){ot=void 0})),ot=Date.now()}function ut(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)o["margin"+(n=ie[r])]=o["padding"+n]=e;return t&&(o.opacity=o.width=e),o}function ft(e,t,n){for(var r,o=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),i=0,a=o.length;i1)},removeAttr:function(e){return this.each((function(){T.removeAttr(this,e)}))}}),T.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return void 0===e.getAttribute?T.prop(e,t,n):(1===i&&T.isXMLDoc(e)||(o=T.attrHooks[t.toLowerCase()]||(T.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void T.removeAttr(e,t):o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+""),n):o&&"get"in o&&null!==(r=o.get(e,t))?r:null==(r=T.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&w(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(I);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?T.removeAttr(e,n):e.setAttribute(n,n),n}},T.each(T.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=ht[t]||T.find.attr;ht[t]=function(e,t,r){var o,i,a=t.toLowerCase();return r||(i=ht[a],ht[a]=o,o=null!=n(e,t,r)?a:null,ht[a]=i),o}}));var Mt=/^(?:input|select|textarea|button)$/i,vt=/^(?:a|area)$/i;function bt(e){return(e.match(I)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function gt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(I)||[]}T.fn.extend({prop:function(e,t){return F(this,T.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[T.propFix[e]||e]}))}}),T.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&T.isXMLDoc(e)||(t=T.propFix[t]||t,o=T.propHooks[t]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&"get"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=T.find.attr(e,"tabindex");return t?parseInt(t,10):Mt.test(e.nodeName)||vt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(T.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),T.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){T.propFix[this.toLowerCase()]=this})),T.fn.extend({addClass:function(e){var t,n,r,o,i,a,c,s=0;if(b(e))return this.each((function(t){T(this).addClass(e.call(this,t,mt(this)))}));if((t=gt(e)).length)for(;n=this[s++];)if(o=mt(n),r=1===n.nodeType&&" "+bt(o)+" "){for(a=0;i=t[a++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");o!==(c=bt(r))&&n.setAttribute("class",c)}return this},removeClass:function(e){var t,n,r,o,i,a,c,s=0;if(b(e))return this.each((function(t){T(this).removeClass(e.call(this,t,mt(this)))}));if(!arguments.length)return this.attr("class","");if((t=gt(e)).length)for(;n=this[s++];)if(o=mt(n),r=1===n.nodeType&&" "+bt(o)+" "){for(a=0;i=t[a++];)for(;r.indexOf(" "+i+" ")>-1;)r=r.replace(" "+i+" "," ");o!==(c=bt(r))&&n.setAttribute("class",c)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):b(e)?this.each((function(n){T(this).toggleClass(e.call(this,n,mt(this),t),t)})):this.each((function(){var t,o,i,a;if(r)for(o=0,i=T(this),a=gt(e);t=a[o++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&"boolean"!==n||((t=mt(this))&&Q.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":Q.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+bt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var At=/\r/g;T.fn.extend({val:function(e){var t,n,r,o=this[0];return arguments.length?(r=b(e),this.each((function(n){var o;1===this.nodeType&&(null==(o=r?e.call(this,n,T(this).val()):e)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=T.map(o,(function(e){return null==e?"":e+""}))),(t=T.valHooks[this.type]||T.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))}))):o?(t=T.valHooks[o.type]||T.valHooks[o.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(At,""):null==n?"":n:void 0}}),T.extend({valHooks:{option:{get:function(e){var t=T.find.attr(e,"value");return null!=t?t:bt(T.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,a="select-one"===e.type,c=a?null:[],s=a?i+1:o.length;for(r=i<0?s:a?i:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),T.each(["radio","checkbox"],(function(){T.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=T.inArray(T(e).val(),t)>-1}},v.checkOn||(T.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),v.focusin="onfocusin"in r;var _t=/^(?:focusinfocus|focusoutblur)$/,yt=function(e){e.stopPropagation()};T.extend(T.event,{trigger:function(e,t,n,o){var i,a,c,s,l,u,f,d,h=[n||g],M=p.call(e,"type")?e.type:e,v=p.call(e,"namespace")?e.namespace.split("."):[];if(a=d=c=n=n||g,3!==n.nodeType&&8!==n.nodeType&&!_t.test(M+T.event.triggered)&&(M.indexOf(".")>-1&&(v=M.split("."),M=v.shift(),v.sort()),l=M.indexOf(":")<0&&"on"+M,(e=e[T.expando]?e:new T.Event(M,"object"==typeof e&&e)).isTrigger=o?2:3,e.namespace=v.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:T.makeArray(t,[e]),f=T.event.special[M]||{},o||!f.trigger||!1!==f.trigger.apply(n,t))){if(!o&&!f.noBubble&&!m(n)){for(s=f.delegateType||M,_t.test(s+M)||(a=a.parentNode);a;a=a.parentNode)h.push(a),c=a;c===(n.ownerDocument||g)&&h.push(c.defaultView||c.parentWindow||r)}for(i=0;(a=h[i++])&&!e.isPropagationStopped();)d=a,e.type=i>1?s:f.bindType||M,(u=(Q.get(a,"events")||Object.create(null))[e.type]&&Q.get(a,"handle"))&&u.apply(a,t),(u=l&&a[l])&&u.apply&&K(a)&&(e.result=u.apply(a,t),!1===e.result&&e.preventDefault());return e.type=M,o||e.isDefaultPrevented()||f._default&&!1!==f._default.apply(h.pop(),t)||!K(n)||l&&b(n[M])&&!m(n)&&((c=n[l])&&(n[l]=null),T.event.triggered=M,e.isPropagationStopped()&&d.addEventListener(M,yt),n[M](),e.isPropagationStopped()&&d.removeEventListener(M,yt),T.event.triggered=void 0,c&&(n[l]=c)),e.result}},simulate:function(e,t,n){var r=T.extend(new T.Event,n,{type:e,isSimulated:!0});T.event.trigger(r,null,t)}}),T.fn.extend({trigger:function(e,t){return this.each((function(){T.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return T.event.trigger(e,t,n,!0)}}),v.focusin||T.each({focus:"focusin",blur:"focusout"},(function(e,t){var n=function(e){T.event.simulate(t,e.target,T.event.fix(e))};T.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,o=Q.access(r,t);o||r.addEventListener(e,n,!0),Q.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,o=Q.access(r,t)-1;o?Q.access(r,t,o):(r.removeEventListener(e,n,!0),Q.remove(r,t))}}}));var Et=r.location,Tt={guid:Date.now()},Ot=/\?/;T.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new r.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||T.error("Invalid XML: "+(n?T.map(n.childNodes,(function(e){return e.textContent})).join("\n"):e)),t};var Nt=/\[\]$/,zt=/\r?\n/g,Lt=/^(?:submit|button|image|reset|file)$/i,Ct=/^(?:input|select|textarea|keygen)/i;function wt(e,t,n,r){var o;if(Array.isArray(t))T.each(t,(function(t,o){n||Nt.test(e)?r(e,o):wt(e+"["+("object"==typeof o&&null!=o?t:"")+"]",o,n,r)}));else if(n||"object"!==y(t))r(e,t);else for(o in t)wt(e+"["+o+"]",t[o],n,r)}T.param=function(e,t){var n,r=[],o=function(e,t){var n=b(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!T.isPlainObject(e))T.each(e,(function(){o(this.name,this.value)}));else for(n in e)wt(n,e[n],t,o);return r.join("&")},T.fn.extend({serialize:function(){return T.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=T.prop(this,"elements");return e?T.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!T(this).is(":disabled")&&Ct.test(this.nodeName)&&!Lt.test(e)&&(this.checked||!ve.test(e))})).map((function(e,t){var n=T(this).val();return null==n?null:Array.isArray(n)?T.map(n,(function(e){return{name:t.name,value:e.replace(zt,"\r\n")}})):{name:t.name,value:n.replace(zt,"\r\n")}})).get()}});var St=/%20/g,Rt=/#.*$/,xt=/([?&])_=[^&]*/,qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Wt=/^(?:GET|HEAD)$/,kt=/^\/\//,Bt={},It={},Dt="*/".concat("*"),Xt=g.createElement("a");function Pt(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,o=0,i=t.toLowerCase().match(I)||[];if(b(n))for(;r=i[o++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function jt(e,t,n,r){var o={},i=e===It;function a(c){var s;return o[c]=!0,T.each(e[c]||[],(function(e,c){var l=c(t,n,r);return"string"!=typeof l||i||o[l]?i?!(s=l):void 0:(t.dataTypes.unshift(l),a(l),!1)})),s}return a(t.dataTypes[0])||!o["*"]&&a("*")}function Ut(e,t){var n,r,o=T.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((o[n]?e:r||(r={}))[n]=t[n]);return r&&T.extend(!0,e,r),e}Xt.href=Et.href,T.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":T.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ut(Ut(e,T.ajaxSettings),t):Ut(T.ajaxSettings,e)},ajaxPrefilter:Pt(Bt),ajaxTransport:Pt(It),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var n,o,i,a,c,s,l,u,f,d,p=T.ajaxSetup({},t),h=p.context||p,M=p.context&&(h.nodeType||h.jquery)?T(h):T.event,v=T.Deferred(),b=T.Callbacks("once memory"),m=p.statusCode||{},A={},_={},y="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=qt.exec(i);)a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return l?i:null},setRequestHeader:function(e,t){return null==l&&(e=_[e.toLowerCase()]=_[e.toLowerCase()]||e,A[e]=t),this},overrideMimeType:function(e){return null==l&&(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)E.always(e[E.status]);else for(t in e)m[t]=[m[t],e[t]];return this},abort:function(e){var t=e||y;return n&&n.abort(t),O(0,t),this}};if(v.promise(E),p.url=((e||p.url||Et.href)+"").replace(kt,Et.protocol+"//"),p.type=t.method||t.type||p.method||p.type,p.dataTypes=(p.dataType||"*").toLowerCase().match(I)||[""],null==p.crossDomain){s=g.createElement("a");try{s.href=p.url,s.href=s.href,p.crossDomain=Xt.protocol+"//"+Xt.host!=s.protocol+"//"+s.host}catch(e){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=T.param(p.data,p.traditional)),jt(Bt,p,t,E),l)return E;for(f in(u=T.event&&p.global)&&0==T.active++&&T.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Wt.test(p.type),o=p.url.replace(Rt,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(St,"+")):(d=p.url.slice(o.length),p.data&&(p.processData||"string"==typeof p.data)&&(o+=(Ot.test(o)?"&":"?")+p.data,delete p.data),!1===p.cache&&(o=o.replace(xt,"$1"),d=(Ot.test(o)?"&":"?")+"_="+Tt.guid+++d),p.url=o+d),p.ifModified&&(T.lastModified[o]&&E.setRequestHeader("If-Modified-Since",T.lastModified[o]),T.etag[o]&&E.setRequestHeader("If-None-Match",T.etag[o])),(p.data&&p.hasContent&&!1!==p.contentType||t.contentType)&&E.setRequestHeader("Content-Type",p.contentType),E.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dt+"; q=0.01":""):p.accepts["*"]),p.headers)E.setRequestHeader(f,p.headers[f]);if(p.beforeSend&&(!1===p.beforeSend.call(h,E,p)||l))return E.abort();if(y="abort",b.add(p.complete),E.done(p.success),E.fail(p.error),n=jt(It,p,t,E)){if(E.readyState=1,u&&M.trigger("ajaxSend",[E,p]),l)return E;p.async&&p.timeout>0&&(c=r.setTimeout((function(){E.abort("timeout")}),p.timeout));try{l=!1,n.send(A,O)}catch(e){if(l)throw e;O(-1,e)}}else O(-1,"No Transport");function O(e,t,a,s){var f,d,g,A,_,y=t;l||(l=!0,c&&r.clearTimeout(c),n=void 0,i=s||"",E.readyState=e>0?4:0,f=e>=200&&e<300||304===e,a&&(A=function(e,t,n){for(var r,o,i,a,c=e.contents,s=e.dataTypes;"*"===s[0];)s.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(o in c)if(c[o]&&c[o].test(r)){s.unshift(o);break}if(s[0]in n)i=s[0];else{for(o in n){if(!s[0]||e.converters[o+" "+s[0]]){i=o;break}a||(a=o)}i=i||a}if(i)return i!==s[0]&&s.unshift(i),n[i]}(p,E,a)),!f&&T.inArray("script",p.dataTypes)>-1&&T.inArray("json",p.dataTypes)<0&&(p.converters["text script"]=function(){}),A=function(e,t,n,r){var o,i,a,c,s,l={},u=e.dataTypes.slice();if(u[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(i=u.shift();i;)if(e.responseFields[i]&&(n[e.responseFields[i]]=t),!s&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),s=i,i=u.shift())if("*"===i)i=s;else if("*"!==s&&s!==i){if(!(a=l[s+" "+i]||l["* "+i]))for(o in l)if((c=o.split(" "))[1]===i&&(a=l[s+" "+c[0]]||l["* "+c[0]])){!0===a?a=l[o]:!0!==l[o]&&(i=c[0],u.unshift(c[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+s+" to "+i}}}return{state:"success",data:t}}(p,A,E,f),f?(p.ifModified&&((_=E.getResponseHeader("Last-Modified"))&&(T.lastModified[o]=_),(_=E.getResponseHeader("etag"))&&(T.etag[o]=_)),204===e||"HEAD"===p.type?y="nocontent":304===e?y="notmodified":(y=A.state,d=A.data,f=!(g=A.error))):(g=y,!e&&y||(y="error",e<0&&(e=0))),E.status=e,E.statusText=(t||y)+"",f?v.resolveWith(h,[d,y,E]):v.rejectWith(h,[E,y,g]),E.statusCode(m),m=void 0,u&&M.trigger(f?"ajaxSuccess":"ajaxError",[E,p,f?d:g]),b.fireWith(h,[E,y]),u&&(M.trigger("ajaxComplete",[E,p]),--T.active||T.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return T.get(e,t,n,"json")},getScript:function(e,t){return T.get(e,void 0,t,"script")}}),T.each(["get","post"],(function(e,t){T[t]=function(e,n,r,o){return b(n)&&(o=o||r,r=n,n=void 0),T.ajax(T.extend({url:e,type:t,dataType:o,data:n,success:r},T.isPlainObject(e)&&e))}})),T.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),T._evalUrl=function(e,t,n){return T.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){T.globalEval(e,t,n)}})},T.fn.extend({wrapAll:function(e){var t;return this[0]&&(b(e)&&(e=e.call(this[0])),t=T(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return b(e)?this.each((function(t){T(this).wrapInner(e.call(this,t))})):this.each((function(){var t=T(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=b(e);return this.each((function(n){T(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){T(this).replaceWith(this.childNodes)})),this}}),T.expr.pseudos.hidden=function(e){return!T.expr.pseudos.visible(e)},T.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},T.ajaxSettings.xhr=function(){try{return new r.XMLHttpRequest}catch(e){}};var Ht={0:200,1223:204},Ft=T.ajaxSettings.xhr();v.cors=!!Ft&&"withCredentials"in Ft,v.ajax=Ft=!!Ft,T.ajaxTransport((function(e){var t,n;if(v.cors||Ft&&!e.crossDomain)return{send:function(o,i){var a,c=e.xhr();if(c.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)c[a]=e.xhrFields[a];for(a in e.mimeType&&c.overrideMimeType&&c.overrideMimeType(e.mimeType),e.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)c.setRequestHeader(a,o[a]);t=function(e){return function(){t&&(t=n=c.onload=c.onerror=c.onabort=c.ontimeout=c.onreadystatechange=null,"abort"===e?c.abort():"error"===e?"number"!=typeof c.status?i(0,"error"):i(c.status,c.statusText):i(Ht[c.status]||c.status,c.statusText,"text"!==(c.responseType||"text")||"string"!=typeof c.responseText?{binary:c.response}:{text:c.responseText},c.getAllResponseHeaders()))}},c.onload=t(),n=c.onerror=c.ontimeout=t("error"),void 0!==c.onabort?c.onabort=n:c.onreadystatechange=function(){4===c.readyState&&r.setTimeout((function(){t&&n()}))},t=t("abort");try{c.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),T.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),T.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return T.globalEval(e),e}}}),T.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),T.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,o){t=T(" + @if(session()->has('toast.type') && session()->has('toast.message')) + + @endif + diff --git a/resources/views/cronjobs/index.blade.php b/resources/views/cronjobs/index.blade.php new file mode 100644 index 0000000..264d64a --- /dev/null +++ b/resources/views/cronjobs/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Cronjobs") }} + + + diff --git a/resources/views/daemons/index.blade.php b/resources/views/daemons/index.blade.php new file mode 100644 index 0000000..0e6bcda --- /dev/null +++ b/resources/views/daemons/index.blade.php @@ -0,0 +1,4 @@ + + {{ __("Daemons") }} + + diff --git a/resources/views/databases/index.blade.php b/resources/views/databases/index.blade.php new file mode 100644 index 0000000..7495598 --- /dev/null +++ b/resources/views/databases/index.blade.php @@ -0,0 +1,9 @@ + + {{ __("Databases") }} + +
+ + + +
+
diff --git a/resources/views/firewall/index.blade.php b/resources/views/firewall/index.blade.php new file mode 100644 index 0000000..64abb6a --- /dev/null +++ b/resources/views/firewall/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Firewall") }} + + + diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php new file mode 100644 index 0000000..5701b26 --- /dev/null +++ b/resources/views/layouts/app.blade.php @@ -0,0 +1,57 @@ + + + + + + + + + @if(isset($pageTitle)) + {{ $pageTitle }} - + @endif + {{ config('app.name', 'Laravel') }} + + + + + + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + @livewireStyles + + + + + + + +
+ @include('layouts.navigation') + + + @if (isset($header)) +
+
+ {{ $header }} +
+
+ @endif + + +
+ {{ $slot }} +
+
+ + @livewireScripts + + + diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php new file mode 100644 index 0000000..bdae743 --- /dev/null +++ b/resources/views/layouts/guest.blade.php @@ -0,0 +1,30 @@ + + + + + + + + {{ config('app.name', 'Laravel') }} + + + + + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + +
+
+ + + +
+ +
+ {{ $slot }} +
+
+ + diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php new file mode 100644 index 0000000..b2fcc39 --- /dev/null +++ b/resources/views/layouts/navigation.blade.php @@ -0,0 +1,63 @@ + diff --git a/resources/views/layouts/profile.blade.php b/resources/views/layouts/profile.blade.php new file mode 100644 index 0000000..ba4660d --- /dev/null +++ b/resources/views/layouts/profile.blade.php @@ -0,0 +1,34 @@ + + @if(isset($pageTitle)) + {{ $pageTitle }} + @endif + + + + +
+ {{ $slot }} +
+
+
diff --git a/resources/views/layouts/server.blade.php b/resources/views/layouts/server.blade.php new file mode 100644 index 0000000..427f706 --- /dev/null +++ b/resources/views/layouts/server.blade.php @@ -0,0 +1,60 @@ + + @if(isset($pageTitle)) + {{ $pageTitle }} - {{ $server->name }} + @endif + + + @if(in_array($server->status, [\App\Enums\ServerStatus::READY, \App\Enums\ServerStatus::DISCONNECTED])) + + @endif + +
+ {{ $slot }} +
+
+
diff --git a/resources/views/layouts/site.blade.php b/resources/views/layouts/site.blade.php new file mode 100644 index 0000000..2f7d8b3 --- /dev/null +++ b/resources/views/layouts/site.blade.php @@ -0,0 +1,44 @@ + + @if(isset($pageTitle)) + {{ $site->domain }} - {{ $pageTitle }} + @endif + + + @if($site->status == \App\Enums\SiteStatus::READY) + + @endif + +
+ {{ $slot }} +
+
+
diff --git a/resources/views/livewire/application/change-branch.blade.php b/resources/views/livewire/application/change-branch.blade.php new file mode 100644 index 0000000..0e49a51 --- /dev/null +++ b/resources/views/livewire/application/change-branch.blade.php @@ -0,0 +1,32 @@ +
+ {{ __("Branch") }} + +
+

+ {{ __('Change Branch') }} +

+ +
+ + + @error('branch') + + @enderror +
+ +
+ @if (session('status') === 'updating-branch') +

{{ __('Updating branch...') }}

+ @endif + + + {{ __('Cancel') }} + + + + {{ __('Save') }} + +
+
+
+
diff --git a/resources/views/livewire/application/deploy.blade.php b/resources/views/livewire/application/deploy.blade.php new file mode 100644 index 0000000..5c313e3 --- /dev/null +++ b/resources/views/livewire/application/deploy.blade.php @@ -0,0 +1,5 @@ +
+ @if($site->deploymentScript && $site->deploymentScript->content) + {{ __("Deploy") }} + @endif +
diff --git a/resources/views/livewire/application/deployment-script.blade.php b/resources/views/livewire/application/deployment-script.blade.php new file mode 100644 index 0000000..1a08ef6 --- /dev/null +++ b/resources/views/livewire/application/deployment-script.blade.php @@ -0,0 +1,32 @@ +
+ {{ __("Deployment Script") }} + +
+

+ {{ __('Deployment Script') }} +

+ +
+ + + @error('script') + + @enderror +
+ +
+ @if (session('status') === 'script-updated') +

{{ __('Saved') }}

+ @endif + + + {{ __('Cancel') }} + + + + {{ __('Save') }} + +
+
+
+
diff --git a/resources/views/livewire/application/deployments-list.blade.php b/resources/views/livewire/application/deployments-list.blade.php new file mode 100644 index 0000000..e7b8b67 --- /dev/null +++ b/resources/views/livewire/application/deployments-list.blade.php @@ -0,0 +1,51 @@ +
+ + {{ __("Deployments") }} + + + + {{ __("Commit") }} + {{ __("Date") }} + {{ __("Status") }} + + + @foreach($deployments as $deployment) + + + {{ $deployment->commit_data['message'] }} + + + + + +
+ @include('livewire.application.partials.deployment-status', ['status' => $deployment->status]) +
+
+ + @if($deployment->status != \App\Enums\DeploymentStatus::DEPLOYING) + + + + @endif + + + @endforeach +
+
+ {{ $deployments->withQueryString()->links() }} +
+ +
+

+ {{ __('View Log') }} +

+ {{ $logContent }} +
+ + {{ __('Close') }} + +
+
+
+
diff --git a/resources/views/livewire/application/laravel-app.blade.php b/resources/views/livewire/application/laravel-app.blade.php new file mode 100644 index 0000000..2567bab --- /dev/null +++ b/resources/views/livewire/application/laravel-app.blade.php @@ -0,0 +1,21 @@ +
+ + {{ __("Application") }} + {{ __("Here you can manage your application") }} + +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
diff --git a/resources/views/livewire/application/partials/deployment-status.blade.php b/resources/views/livewire/application/partials/deployment-status.blade.php new file mode 100644 index 0000000..d520b49 --- /dev/null +++ b/resources/views/livewire/application/partials/deployment-status.blade.php @@ -0,0 +1,9 @@ +@if($status == \App\Enums\DeploymentStatus::DEPLOYING) + {{ $status }} +@endif +@if($status == \App\Enums\DeploymentStatus::FINISHED) + {{ $status }} +@endif +@if($status == \App\Enums\DeploymentStatus::FAILED) + {{ $status }} +@endif diff --git a/resources/views/livewire/application/php-app.blade.php b/resources/views/livewire/application/php-app.blade.php new file mode 100644 index 0000000..b80e6e0 --- /dev/null +++ b/resources/views/livewire/application/php-app.blade.php @@ -0,0 +1,3 @@ +
+ +
diff --git a/resources/views/livewire/application/wordpress-app.blade.php b/resources/views/livewire/application/wordpress-app.blade.php new file mode 100644 index 0000000..b80e6e0 --- /dev/null +++ b/resources/views/livewire/application/wordpress-app.blade.php @@ -0,0 +1,3 @@ +
+ +
diff --git a/resources/views/livewire/cronjobs/create-cronjob.blade.php b/resources/views/livewire/cronjobs/create-cronjob.blade.php new file mode 100644 index 0000000..ef291a5 --- /dev/null +++ b/resources/views/livewire/cronjobs/create-cronjob.blade.php @@ -0,0 +1,69 @@ +
+ + {{ __('Create Cronjob') }} + + + +
+

+ {{ __('Create Cronjob') }} +

+ +
+ + + @error('command') + + @enderror +
+ +
+ + + + + + + @error('user') + + @enderror +
+ +
+ + + + + + + + + + + @error('frequency') + + @enderror +
+ + @if($frequency === 'custom') +
+ + + @error('custom') + + @enderror +
+ @endif + +
+ + {{ __('Cancel') }} + + + + {{ __('Create') }} + +
+
+
+
diff --git a/resources/views/livewire/cronjobs/cronjobs-list.blade.php b/resources/views/livewire/cronjobs/cronjobs-list.blade.php new file mode 100644 index 0000000..4ac48d3 --- /dev/null +++ b/resources/views/livewire/cronjobs/cronjobs-list.blade.php @@ -0,0 +1,45 @@ +
+ + {{ __("Cronjobs") }} + {{ __("Your server's Cronjobs are here. You can manage them") }} + + + + +
+ @if(count($cronjobs) > 0) + @foreach($cronjobs as $cronjob) + +
+ + {{ $cronjob->command }} + + + {{ $cronjob->frequency_label }} + +
+
+ @include('livewire.cronjobs.partials.status', ['status' => $cronjob->status]) +
+ + + +
+
+
+ @endforeach + + @else + +
+ {{ __("You haven't connected to any server providers yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/cronjobs/partials/status.blade.php b/resources/views/livewire/cronjobs/partials/status.blade.php new file mode 100644 index 0000000..0d55e87 --- /dev/null +++ b/resources/views/livewire/cronjobs/partials/status.blade.php @@ -0,0 +1,9 @@ +@if($status == \App\Enums\CronjobStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\CronjobStatus::CREATING) + {{ $status }} +@endif +@if($status == \App\Enums\CronjobStatus::DELETING) + {{ $status }} +@endif diff --git a/resources/views/livewire/databases/database-list.blade.php b/resources/views/livewire/databases/database-list.blade.php new file mode 100644 index 0000000..3d0e04e --- /dev/null +++ b/resources/views/livewire/databases/database-list.blade.php @@ -0,0 +1,46 @@ +
+ + {{ __("Databases") }} + {{ __("You can see and manage your databases here") }} + +
+ + {{ __('Create Database') }} + + + @include('livewire.databases.partials.create-database-modal') +
+
+
+ @if(count($databases) > 0) + + + {{ __("Name") }} + {{ __("Created") }} + {{ __("Status") }} + + + @foreach($databases as $database) + + {{ $database->name }} + + + + +
+ @include('livewire.databases.partials.database-status', ['status' => $database->status]) +
+
+ + + + + + + @endforeach +
+ @include('livewire.databases.partials.delete-database-modal') + @else + {{ __("You don't have any databases yet") }} + @endif +
diff --git a/resources/views/livewire/databases/database-user-list.blade.php b/resources/views/livewire/databases/database-user-list.blade.php new file mode 100644 index 0000000..8240d0d --- /dev/null +++ b/resources/views/livewire/databases/database-user-list.blade.php @@ -0,0 +1,56 @@ +
+ + {{ __("Database Users") }} + {{ __("You can see and manage your database users here") }} + +
+ + {{ __('Create Database User') }} + + + @include('livewire.databases.partials.create-database-user-modal') +
+
+
+ @if(count($databaseUsers) > 0) + + + {{ __("Username") }} + {{ __("Created") }} + {{ __("Linked Databases") }} + {{ __("Status") }} + + + @foreach($databaseUsers as $databaseUser) + + {{ $databaseUser->username }} + + + + [{{ $databaseUser->databases ? implode(', ', $databaseUser->databases) : '-' }}] + +
+ @include('livewire.databases.partials.database-user-status', ['status' => $databaseUser->status]) +
+
+ + + + + + + + + + + + + @endforeach +
+ @include('livewire.databases.partials.delete-database-user-modal') + @include('livewire.databases.partials.database-user-password-modal') + @include('livewire.databases.partials.link-database-user-modal') + @else + {{ __("You don't have any database users yet") }} + @endif +
diff --git a/resources/views/livewire/databases/partials/create-database-modal.blade.php b/resources/views/livewire/databases/partials/create-database-modal.blade.php new file mode 100644 index 0000000..516082a --- /dev/null +++ b/resources/views/livewire/databases/partials/create-database-modal.blade.php @@ -0,0 +1,68 @@ + +
+

+ {{ __('Create Database') }} +

+ +
+ + + @error('name') + + @enderror +
+ +
+ +
+ +
+
+ + + @error('username') + + @enderror +
+ +
+ + + @error('password') + + @enderror +
+ +
+ +
+ +
+
+ + + + @error('host') + + @enderror +
+
+
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Create') }} + +
+
+
diff --git a/resources/views/livewire/databases/partials/create-database-user-modal.blade.php b/resources/views/livewire/databases/partials/create-database-user-modal.blade.php new file mode 100644 index 0000000..d9815ea --- /dev/null +++ b/resources/views/livewire/databases/partials/create-database-user-modal.blade.php @@ -0,0 +1,51 @@ + +
+

+ {{ __('Create Database User') }} +

+ +
+ + + @error('username') + + @enderror +
+ +
+ + + @error('password') + + @enderror +
+ +
+ +
+ +
+
+ + + + @error('host') + + @enderror +
+
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Create') }} + +
+
+
diff --git a/resources/views/livewire/databases/partials/database-status.blade.php b/resources/views/livewire/databases/partials/database-status.blade.php new file mode 100644 index 0000000..f3f4397 --- /dev/null +++ b/resources/views/livewire/databases/partials/database-status.blade.php @@ -0,0 +1,12 @@ +@if($status == \App\Enums\DatabaseStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\DatabaseStatus::CREATING) + {{ $status }} +@endif +@if($status == \App\Enums\DatabaseStatus::DELETING) + {{ $status }} +@endif +@if($status == \App\Enums\DatabaseStatus::FAILED) + {{ $status }} +@endif diff --git a/resources/views/livewire/databases/partials/database-user-password-modal.blade.php b/resources/views/livewire/databases/partials/database-user-password-modal.blade.php new file mode 100644 index 0000000..8db55b0 --- /dev/null +++ b/resources/views/livewire/databases/partials/database-user-password-modal.blade.php @@ -0,0 +1,23 @@ + +
+

+ {{ __('View Password') }} +

+ +
+ + +
+ +
+ + {{ __('Close') }} + + + +
{{ __("Copied") }}
+
{{ __("Copy") }}
+
+
+
+
diff --git a/resources/views/livewire/databases/partials/database-user-status.blade.php b/resources/views/livewire/databases/partials/database-user-status.blade.php new file mode 100644 index 0000000..efb9afc --- /dev/null +++ b/resources/views/livewire/databases/partials/database-user-status.blade.php @@ -0,0 +1,12 @@ +@if($status == \App\Enums\DatabaseUserStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\DatabaseUserStatus::CREATING) + {{ $status }} +@endif +@if($status == \App\Enums\DatabaseUserStatus::DELETING) + {{ $status }} +@endif +@if($status == \App\Enums\DatabaseUserStatus::FAILED) + {{ $status }} +@endif diff --git a/resources/views/livewire/databases/partials/delete-database-modal.blade.php b/resources/views/livewire/databases/partials/delete-database-modal.blade.php new file mode 100644 index 0000000..d2cf5d2 --- /dev/null +++ b/resources/views/livewire/databases/partials/delete-database-modal.blade.php @@ -0,0 +1,6 @@ + diff --git a/resources/views/livewire/databases/partials/delete-database-user-modal.blade.php b/resources/views/livewire/databases/partials/delete-database-user-modal.blade.php new file mode 100644 index 0000000..9ec5fc7 --- /dev/null +++ b/resources/views/livewire/databases/partials/delete-database-user-modal.blade.php @@ -0,0 +1,6 @@ + diff --git a/resources/views/livewire/databases/partials/link-database-user-modal.blade.php b/resources/views/livewire/databases/partials/link-database-user-modal.blade.php new file mode 100644 index 0000000..68abdb7 --- /dev/null +++ b/resources/views/livewire/databases/partials/link-database-user-modal.blade.php @@ -0,0 +1,28 @@ + +
+

+ {{ __('Link User to Databases') }} +

+ +
+ @foreach($databases as $database) +
+ +
+ @endforeach +
+ +
+ + {{ __('Close') }} + + + + {{ __('Save') }} + +
+
+
diff --git a/resources/views/livewire/firewall/create-firewall-rule.blade.php b/resources/views/livewire/firewall/create-firewall-rule.blade.php new file mode 100644 index 0000000..1854891 --- /dev/null +++ b/resources/views/livewire/firewall/create-firewall-rule.blade.php @@ -0,0 +1,72 @@ +
+ + {{ __('Create new Rule') }} + + + +
+

+ {{ __('Create new Rule') }} +

+ +
+ + + + + + @error('type') + + @enderror +
+ +
+
+ + + @foreach(config('core.firewall_protocols_port') as $key => $value) + + @endforeach + + @error('protocol') + + @enderror +
+ +
+ + + @error('port') + + @enderror +
+ +
+ + + @error('source') + + @enderror +
+ +
+ + + @error('mask') + + @enderror +
+
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Create') }} + +
+
+
+
diff --git a/resources/views/livewire/firewall/firewall-rules-list.blade.php b/resources/views/livewire/firewall/firewall-rules-list.blade.php new file mode 100644 index 0000000..6d148dc --- /dev/null +++ b/resources/views/livewire/firewall/firewall-rules-list.blade.php @@ -0,0 +1,52 @@ +
+ + {{ __("Firewall Rules") }} + {{ __("Your server's firewall rules are here. You can manage them") }} + + + + +
+ @foreach($rules as $rule) + +
+ + {{ $rule->protocol }} + {{ $rule->type }} + + + {{ __("From") }} {{ $rule->source }}/{{ $rule->mask }} {{ __("Port") }} {{ $rule->port }} + +
+
+ @include('livewire.firewall.partials.status', ['status' => $rule->status]) +
+ + + +
+
+
+ @endforeach + +
+ + {{ __("All") }} + {{ __("Deny") }} + + + {{ __("From") }} 0.0.0.0/0 + +
+
+ {{ __("Default") }} +
+
+ +
+
diff --git a/resources/views/livewire/firewall/partials/status.blade.php b/resources/views/livewire/firewall/partials/status.blade.php new file mode 100644 index 0000000..1214734 --- /dev/null +++ b/resources/views/livewire/firewall/partials/status.blade.php @@ -0,0 +1,9 @@ +@if($status == \App\Enums\FirewallRuleStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\FirewallRuleStatus::CREATING) + {{ $status }} +@endif +@if($status == \App\Enums\FirewallRuleStatus::DELETING) + {{ $status }} +@endif diff --git a/resources/views/livewire/notification-channels/add-channel.blade.php b/resources/views/livewire/notification-channels/add-channel.blade.php new file mode 100644 index 0000000..71e82ac --- /dev/null +++ b/resources/views/livewire/notification-channels/add-channel.blade.php @@ -0,0 +1,66 @@ +
+ + {{ __('Add new Channel') }} + + + +
+

+ {{ __('Add new Channel') }} +

+ +
+ + + + @foreach(config('core.notification_channels_providers') as $p) + @if($p !== 'custom') + + @endif + @endforeach + + @error('provider') + + @enderror +
+ +
+ + + @error('label') + + @enderror +
+ + @if($provider == \App\Enums\NotificationChannel::EMAIL) +
+ + + @error('email') + + @enderror +
+ @endif + + @if(in_array($provider, [\App\Enums\NotificationChannel::SLACK, \App\Enums\NotificationChannel::DISCORD])) +
+ + + @error('webhook_url') + + @enderror +
+ @endif + +
+ + {{ __('Cancel') }} + + + + {{ __('Add') }} + +
+
+
+
diff --git a/resources/views/livewire/notification-channels/channels-list.blade.php b/resources/views/livewire/notification-channels/channels-list.blade.php new file mode 100644 index 0000000..335f894 --- /dev/null +++ b/resources/views/livewire/notification-channels/channels-list.blade.php @@ -0,0 +1,45 @@ +
+ + {{ __("Notification Channels") }} + {{ __("Add or modify your notification channels") }} + + + + +
+ @if(count($channels) > 0) + @foreach($channels as $channel) + +
+ +
+
+ {{ $channel->label }} + + + +
+
+
+ + + +
+
+
+ @endforeach + + @else + +
+ {{ __("You haven't connected to any channels yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/partials/pagination.blade.php b/resources/views/livewire/partials/pagination.blade.php new file mode 100644 index 0000000..d7afbb8 --- /dev/null +++ b/resources/views/livewire/partials/pagination.blade.php @@ -0,0 +1,43 @@ +
+ @if ($paginator->hasPages()) + + @endif +
diff --git a/resources/views/livewire/php/default-cli.blade.php b/resources/views/livewire/php/default-cli.blade.php new file mode 100644 index 0000000..04f24d1 --- /dev/null +++ b/resources/views/livewire/php/default-cli.blade.php @@ -0,0 +1,41 @@ + diff --git a/resources/views/livewire/php/installed-versions.blade.php b/resources/views/livewire/php/installed-versions.blade.php new file mode 100644 index 0000000..63b2a01 --- /dev/null +++ b/resources/views/livewire/php/installed-versions.blade.php @@ -0,0 +1,61 @@ +
+ + {{ __("Installed PHPs") }} + {{ __("You can see and manage your PHP installations") }} + + @include('livewire.php.partials.install-new-php') + + + + @if(count($phps) > 0) + + @include('livewire.php.partials.uninstall-php') + @include('livewire.php.partials.update-php-ini') + @else + +
+ {{ __("You don't have any PHP version installed!") }} +
+
+ @endif +
diff --git a/resources/views/livewire/php/partials/install-new-php.blade.php b/resources/views/livewire/php/partials/install-new-php.blade.php new file mode 100644 index 0000000..f1f9b50 --- /dev/null +++ b/resources/views/livewire/php/partials/install-new-php.blade.php @@ -0,0 +1,18 @@ + + + + {{ __("Install") }} + + + + + + @foreach(config('core.php_versions') as $php) + @if(!$phps->whereIn('version', $php)->first() && $php !== 'none') + + PHP {{ $php }} + + @endif + @endforeach + + diff --git a/resources/views/livewire/php/partials/uninstall-php.blade.php b/resources/views/livewire/php/partials/uninstall-php.blade.php new file mode 100644 index 0000000..0461832 --- /dev/null +++ b/resources/views/livewire/php/partials/uninstall-php.blade.php @@ -0,0 +1,6 @@ + diff --git a/resources/views/livewire/php/partials/update-php-ini.blade.php b/resources/views/livewire/php/partials/update-php-ini.blade.php new file mode 100644 index 0000000..d30da9c --- /dev/null +++ b/resources/views/livewire/php/partials/update-php-ini.blade.php @@ -0,0 +1,25 @@ + +
+

+ {{ __('Update php.ini') }} +

+ +
+ + + @error('ini') + + @enderror +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Save') }} + +
+
+
diff --git a/resources/views/livewire/profile/update-password.blade.php b/resources/views/livewire/profile/update-password.blade.php new file mode 100644 index 0000000..628eb88 --- /dev/null +++ b/resources/views/livewire/profile/update-password.blade.php @@ -0,0 +1,45 @@ + + + {{ __('Update Password') }} + + + + {{ __('Ensure your account is using a long, random password to stay secure.') }} + + +
+ @csrf + @method('put') + +
+ + + @error('current_password') + + @enderror +
+ +
+ + + @error('password') + + @enderror +
+ +
+ + + @error('password_confirmation') + + @enderror +
+ +
+ + @if (session('status') === 'password-updated') +

{{ __('Saved') }}

+ @endif + {{ __('Save') }} +
+
diff --git a/resources/views/livewire/profile/update-profile-information.blade.php b/resources/views/livewire/profile/update-profile-information.blade.php new file mode 100644 index 0000000..fd2e4f2 --- /dev/null +++ b/resources/views/livewire/profile/update-profile-information.blade.php @@ -0,0 +1,56 @@ +@php + $user = auth()->user(); +@endphp + + + {{ __('Profile Information') }} + + + + {{ __("Update your account's profile information and email address.") }} + + +
+
+ +
+
+ + + @error('name') + + @enderror +
+ +
+ + + @error('email') + + @enderror + + @if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail()) +
+

+ {{ __('Your email address is unverified.') }} + +

+ @if (session('status') === 'verification-link-sent') +

+ {{ __('A new verification link has been sent to your email address.') }} +

+ @endif +
+ @endif +
+
+ + + @if (session('status') === 'profile-updated') +

{{ __('Saved') }}

+ @endif + {{ __('Save') }} +
+
diff --git a/resources/views/livewire/queues/create-queue.blade.php b/resources/views/livewire/queues/create-queue.blade.php new file mode 100644 index 0000000..508f29f --- /dev/null +++ b/resources/views/livewire/queues/create-queue.blade.php @@ -0,0 +1,75 @@ +
+ + {{ __('Create Queue') }} + + + +
+

+ {{ __('Create Queue') }} +

+ +
+ + + @error('command') + + @enderror +
+ +
+ + + + + + + @error('user') + + @enderror +
+ +
+ + + + + + + @error('auto_start') + + @enderror +
+ +
+ + + + + + + @error('auto_restart') + + @enderror +
+ +
+ + + @error('numprocs') + + @enderror +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Create') }} + +
+
+
+
diff --git a/resources/views/livewire/queues/partials/status.blade.php b/resources/views/livewire/queues/partials/status.blade.php new file mode 100644 index 0000000..b967136 --- /dev/null +++ b/resources/views/livewire/queues/partials/status.blade.php @@ -0,0 +1,27 @@ +@if($status == \App\Enums\QueueStatus::RUNNING) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::CREATING) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::FAILED) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::RESTARTING) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::STARTING) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::STOPPING) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::STOPPED) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::FAILED) + {{ $status }} +@endif +@if($status == \App\Enums\QueueStatus::DELETING) + {{ $status }} +@endif diff --git a/resources/views/livewire/queues/queues-list.blade.php b/resources/views/livewire/queues/queues-list.blade.php new file mode 100644 index 0000000..344b8c9 --- /dev/null +++ b/resources/views/livewire/queues/queues-list.blade.php @@ -0,0 +1,54 @@ +
+ + {{ __("Queues") }} + {{ __("You can manage and create queues for your site") }} + + + + +
+ @if(count($queues) > 0) + @foreach($queues as $queue) + +
+ + {{ $queue->command }} + + + {{ __("User:") }} {{ $queue->user }} + +
+
+ @include('livewire.queues.partials.status', ['status' => $queue->status]) +
+ + + + + + + + + + + + +
+
+
+ @endforeach + + @else + +
+ {{ __("You don't have any queues yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/server-logs/logs-list.blade.php b/resources/views/livewire/server-logs/logs-list.blade.php new file mode 100644 index 0000000..74d3193 --- /dev/null +++ b/resources/views/livewire/server-logs/logs-list.blade.php @@ -0,0 +1,43 @@ +
+ + {{ __("Logs") }} + + + + {{ __("Event") }} + {{ __("Date") }} + + + @foreach($logs as $log) + + {{ $log->type }} + + + + + + + + + + @endforeach + + @if(is_null($count)) +
+ {{ $logs->withQueryString()->links() }} +
+ @endif + +
+

+ {{ __('View Log') }} +

+ {{ $logContent }} +
+ + {{ __('Close') }} + +
+
+
+
diff --git a/resources/views/livewire/server-providers/connect-provider.blade.php b/resources/views/livewire/server-providers/connect-provider.blade.php new file mode 100644 index 0000000..b8bfb0e --- /dev/null +++ b/resources/views/livewire/server-providers/connect-provider.blade.php @@ -0,0 +1,74 @@ +
+ + {{ __('Connect') }} + + + +
+

+ {{ __('Connect to a Server Provider') }} +

+ +
+ + + + @foreach(config('core.server_providers') as $p) + @if($p !== 'custom') + + @endif + @endforeach + + @error('provider') + + @enderror +
+ +
+ + + @error('name') + + @enderror +
+ + @if($provider === 'aws') +
+ + + @error('key') + + @enderror +
+ +
+ + + @error('secret') + + @enderror +
+ @endif + + @if(in_array($provider, ['hetzner', 'digitalocean', 'vultr', 'linode'])) +
+ + + @error('token') + + @enderror +
+ @endif + +
+ + {{ __('Cancel') }} + + + + {{ __('Connect') }} + +
+
+
+
diff --git a/resources/views/livewire/server-providers/providers-list.blade.php b/resources/views/livewire/server-providers/providers-list.blade.php new file mode 100644 index 0000000..13cbcf3 --- /dev/null +++ b/resources/views/livewire/server-providers/providers-list.blade.php @@ -0,0 +1,45 @@ +
+ + Server Providers + You can connect to your server providers to create servers using their APIs + + + + +
+ @if(count($providers) > 0) + @foreach($providers as $provider) + +
+ +
+
+ {{ $provider->profile }} + + + +
+
+
+ + + +
+
+
+ @endforeach + + @else + +
+ {{ __("You haven't connected to any server providers yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/server-settings/check-connection.blade.php b/resources/views/livewire/server-settings/check-connection.blade.php new file mode 100644 index 0000000..3a17687 --- /dev/null +++ b/resources/views/livewire/server-settings/check-connection.blade.php @@ -0,0 +1 @@ +{{ __("Check Connection") }} diff --git a/resources/views/livewire/server-settings/edit-server.blade.php b/resources/views/livewire/server-settings/edit-server.blade.php new file mode 100644 index 0000000..0343197 --- /dev/null +++ b/resources/views/livewire/server-settings/edit-server.blade.php @@ -0,0 +1,38 @@ + + {{ __("Edit Server") }} + + {{ __("You can edit your server's some of fields") }} + +
+
+ + + @error('name') + + @enderror +
+ +
+ + + @error('ip') + + @enderror +
+ +
+ + + @error('port') + + @enderror +
+
+ + + @if (session('status') === 'server-updated') +

{{ __('Saved') }}

+ @endif + {{ __('Save') }} +
+
diff --git a/resources/views/livewire/server-settings/reboot-server.blade.php b/resources/views/livewire/server-settings/reboot-server.blade.php new file mode 100644 index 0000000..475652b --- /dev/null +++ b/resources/views/livewire/server-settings/reboot-server.blade.php @@ -0,0 +1 @@ +{{ __("Reboot") }} diff --git a/resources/views/livewire/server-settings/server-details.blade.php b/resources/views/livewire/server-settings/server-details.blade.php new file mode 100644 index 0000000..a00d1ae --- /dev/null +++ b/resources/views/livewire/server-settings/server-details.blade.php @@ -0,0 +1,58 @@ + + {{ __("Details") }} + {{ __("More details about your server") }} +
+
{{ __("Created At") }}
+
+ +
+
+
+
+
+
+
+
+
{{ __("Provider") }}
+
{{ $server->provider }}
+
+
+
+
+
+
+ {{--
--}} + {{--
{{ __("Server ID") }}
--}} + {{--
--}} + {{-- {{ $server->id }}--}} + {{-- {{ __("You will need this when you use the API") }}--}} + {{--
--}} + {{--
--}} + {{--
--}} + {{--
--}} + {{--
--}} + {{--
--}} + {{--
--}} +
+
{{ __("Status") }}
+
+ @include('livewire.servers.partials.status', ['status' => $server->status]) +
+ +
+
+
+
+
+
+
+
+
+
{{ __("Reboot Server") }}
+
+
+ +
+
+
+
diff --git a/resources/views/livewire/server-ssh-keys/add-existing-key.blade.php b/resources/views/livewire/server-ssh-keys/add-existing-key.blade.php new file mode 100644 index 0000000..b451c1a --- /dev/null +++ b/resources/views/livewire/server-ssh-keys/add-existing-key.blade.php @@ -0,0 +1,36 @@ +
+ + {{ __('Add existing Key') }} + + + +
+

+ {{ __('Add existing Key') }} +

+ +
+ + + + @foreach($keys as $key) + + @endforeach + + @error('key_id') + + @enderror +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Add') }} + +
+
+
+
diff --git a/resources/views/livewire/server-ssh-keys/add-new-key.blade.php b/resources/views/livewire/server-ssh-keys/add-new-key.blade.php new file mode 100644 index 0000000..29f42ca --- /dev/null +++ b/resources/views/livewire/server-ssh-keys/add-new-key.blade.php @@ -0,0 +1,39 @@ +
+ + {{ __('Add new Key') }} + + + +
+

+ {{ __('Add new Key') }} +

+ +
+ + + @error('name') + + @enderror +
+ +
+ + + @error('public_key') + + @enderror +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Add') }} + +
+
+
+
diff --git a/resources/views/livewire/server-ssh-keys/partials/status.blade.php b/resources/views/livewire/server-ssh-keys/partials/status.blade.php new file mode 100644 index 0000000..d462c33 --- /dev/null +++ b/resources/views/livewire/server-ssh-keys/partials/status.blade.php @@ -0,0 +1,9 @@ +@if($status == \App\Enums\SshKeyStatus::ADDED) + {{ $status }} +@endif +@if($status == \App\Enums\SshKeyStatus::ADDING) + {{ $status }} +@endif +@if($status == \App\Enums\SshKeyStatus::DELETING) + {{ $status }} +@endif diff --git a/resources/views/livewire/server-ssh-keys/server-keys-list.blade.php b/resources/views/livewire/server-ssh-keys/server-keys-list.blade.php new file mode 100644 index 0000000..9809f01 --- /dev/null +++ b/resources/views/livewire/server-ssh-keys/server-keys-list.blade.php @@ -0,0 +1,50 @@ +
+ + {{ __("SSH Keys") }} + {{ __("Add or modify your ssh keys") }} + +
+
+ +
+
+ +
+
+
+
+
+ @if(count($keys) > 0) + @foreach($keys as $key) + +
+ {{ $key->name }} + + + +
+
+ @include('livewire.server-ssh-keys.partials.status', ['status' => $key->pivot->status]) +
+ + + +
+
+
+ @endforeach + + @else + +
+ {{ __("You haven't connected to any keys yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/servers/create-server.blade.php b/resources/views/livewire/servers/create-server.blade.php new file mode 100644 index 0000000..b9a08e7 --- /dev/null +++ b/resources/views/livewire/servers/create-server.blade.php @@ -0,0 +1,158 @@ + + + {{ __("Create new Server") }} + {{ __("Use this form to create a new server") }} +
+
+ {{ __("Select a server provider") }} +
+ @foreach(config('core.server_providers') as $p) + +
+ Server + +
+
+ @endforeach +
+ @error('provider') + + @enderror +
+ + @if($provider === 'custom') + @include('livewire.servers.partials.public-key') + @else +
+ +
+ + + @foreach($serverProviders as $sp) + + @endforeach + + {{ __('Connect') }} +
+ @error('server_provider') + + @enderror + @if(count($serverProviders) == 0) + + @endif +
+ @endif + +
+ + + @error('name') + + @enderror +
+ + @if($provider !== 'custom') +
+
+ + + + @foreach(config('serverproviders')[$provider]['plans'] as $value) + + @endforeach + + @error('plan') + + @enderror +
+
+ + + + @foreach(config('serverproviders')[$provider]['regions'] as $key => $value) + + @endforeach + + @error('region') + + @enderror +
+
+ @endif + + @if($provider === 'custom') +
+
+ + + @error('ip') + + @enderror +
+
+ + + @error('port') + + @enderror +
+
+ @endif + +
+ + + @foreach(config('core.operating_systems') as $operatingSystem) + + @endforeach + + @error('os') + + @enderror +
+ +
+
+ + + @foreach(config('core.webservers') as $ws) + + @endforeach + + @error('webserver') + + @enderror +
+
+ + + @foreach(config('core.databases') as $db) + + @endforeach + + @error('database') + + @enderror +
+
+ + + @foreach(config('core.php_versions') as $p) + + @endforeach + + @error('php') + + @enderror +
+
+
+ + {{ __('Create') }} + +
+
diff --git a/resources/views/livewire/servers/delete-server.blade.php b/resources/views/livewire/servers/delete-server.blade.php new file mode 100644 index 0000000..55d4a15 --- /dev/null +++ b/resources/views/livewire/servers/delete-server.blade.php @@ -0,0 +1,9 @@ +
+ {{ __("Delete Server") }} + +
diff --git a/resources/views/livewire/servers/partials/installation-failed.blade.php b/resources/views/livewire/servers/partials/installation-failed.blade.php new file mode 100644 index 0000000..49eff38 --- /dev/null +++ b/resources/views/livewire/servers/partials/installation-failed.blade.php @@ -0,0 +1,14 @@ + + + {{ __("Installation Failed!") }} + + {{ __("Your server installation failed") }} +
+ {{ __("The installation has been failed on step:") }} + {{ $server->progress_step }} ({{ $server->progress }}%) +
+
+ {{ __("View Logs") }} + +
+
diff --git a/resources/views/livewire/servers/partials/installing.blade.php b/resources/views/livewire/servers/partials/installing.blade.php new file mode 100644 index 0000000..0505f53 --- /dev/null +++ b/resources/views/livewire/servers/partials/installing.blade.php @@ -0,0 +1,16 @@ + + {{ __("Installing") }} + {{ __("The server is being installed") }} +
+
+ + {{ $server->progress }}% + +
+
+ {{ $server->progress_step }} +
+
diff --git a/resources/views/livewire/servers/partials/public-key.blade.php b/resources/views/livewire/servers/partials/public-key.blade.php new file mode 100644 index 0000000..795e685 --- /dev/null +++ b/resources/views/livewire/servers/partials/public-key.blade.php @@ -0,0 +1,24 @@ +
+
+
+ Your server needs to have a new unused installation of supported operation systems and must have a root + user. To get started, add our public key to /root/.ssh/authorized_keys file by running the bellow command on + your server as root. +
+
+
+
+
+ + {{ __("Run this command on your server as root user") }} + + +
+ {{ __("Copied") }} + +
+
{{ __("Copy") }}
+
+
+ {{ config('core.ssh_public_key') }} +
diff --git a/resources/views/livewire/servers/partials/server-overview.blade.php b/resources/views/livewire/servers/partials/server-overview.blade.php new file mode 100644 index 0000000..b0215da --- /dev/null +++ b/resources/views/livewire/servers/partials/server-overview.blade.php @@ -0,0 +1,34 @@ +
+ + + {{ __("Server Overview") }} + + {{ __("You can see an overview about your server here") }} + + @include('livewire.servers.partials.status', ['status' => $server->status]) + + +
+
+
+ + +
+
{{ $server->sites()->count() }}
+
+
+
+ + +
+
{{ $server->databases()->count() }}
+
+
+
+ + +
+
{{ $server->cronJobs()->count() }}
+
+
+
diff --git a/resources/views/livewire/servers/partials/status.blade.php b/resources/views/livewire/servers/partials/status.blade.php new file mode 100644 index 0000000..0483181 --- /dev/null +++ b/resources/views/livewire/servers/partials/status.blade.php @@ -0,0 +1,12 @@ +@if($status == \App\Enums\ServerStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\ServerStatus::INSTALLING) + {{ $status }} +@endif +@if($status == \App\Enums\ServerStatus::DISCONNECTED) + {{ $status }} +@endif +@if($status == \App\Enums\ServerStatus::INSTALLATION_FAILED) + {{ $status }} +@endif diff --git a/resources/views/livewire/servers/servers-list.blade.php b/resources/views/livewire/servers/servers-list.blade.php new file mode 100644 index 0000000..1453bac --- /dev/null +++ b/resources/views/livewire/servers/servers-list.blade.php @@ -0,0 +1,42 @@ + + + Servers + Here you can see your servers list and manage them + + + {{ __('Create a Server') }} + + + + + @if(count($servers) > 0) + + @else + +
+ {{ __("You don't have any servers yet!") }} +
+
+ @endif +
diff --git a/resources/views/livewire/servers/show-server.blade.php b/resources/views/livewire/servers/show-server.blade.php new file mode 100644 index 0000000..b71df2a --- /dev/null +++ b/resources/views/livewire/servers/show-server.blade.php @@ -0,0 +1,16 @@ +
+ @if($server->status === \App\Enums\ServerStatus::INSTALLING) + @include('livewire.servers.partials.installing', ['server' => $server]) + + @endif + @if($server->status === \App\Enums\ServerStatus::INSTALLATION_FAILED) + @include('livewire.servers.partials.installation-failed', ['server' => $server]) + + @endif + @if(in_array($server->status, [\App\Enums\ServerStatus::READY, \App\Enums\ServerStatus::DISCONNECTED])) +
+ @include('livewire.servers.partials.server-overview', ['server' => $server]) + +
+ @endif +
diff --git a/resources/views/livewire/services/partials/status.blade.php b/resources/views/livewire/services/partials/status.blade.php new file mode 100644 index 0000000..a69ec74 --- /dev/null +++ b/resources/views/livewire/services/partials/status.blade.php @@ -0,0 +1,27 @@ +@if($status == \App\Enums\ServiceStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::INSTALLING) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::INSTALLATION_FAILED) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::UNINSTALLING) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::FAILED) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::RESTARTING) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::STARTING) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::STOPPING) + {{ $status }} +@endif +@if($status == \App\Enums\ServiceStatus::STOPPED) + {{ $status }} +@endif diff --git a/resources/views/livewire/services/services-list.blade.php b/resources/views/livewire/services/services-list.blade.php new file mode 100644 index 0000000..239c2bd --- /dev/null +++ b/resources/views/livewire/services/services-list.blade.php @@ -0,0 +1,48 @@ +
+ + {{ __("Services") }} + {{ __("All services that we installed on your server are here") }} + + +
+ @foreach($services as $service) + +
+ +
+
+
+
{{ $service->name }}:{{ $service->version }}
+ @include('livewire.services.partials.status', ['status' => $service->status]) +
+
+
+ + + + {{ __("Actions") }} + + + + + + @if($service->status == \App\Enums\ServiceStatus::STOPPED) + + {{ __("Start") }} + + @endif + @if($service->status == \App\Enums\ServiceStatus::READY) + + {{ __("Stop") }} + + @endif + + {{ __("Restart") }} + + + +
+
+ @endforeach +
+
diff --git a/resources/views/livewire/sites/change-php-version.blade.php b/resources/views/livewire/sites/change-php-version.blade.php new file mode 100644 index 0000000..10579d8 --- /dev/null +++ b/resources/views/livewire/sites/change-php-version.blade.php @@ -0,0 +1,33 @@ + + {{ __("Change PHP Version") }} + + {{ __("You can change your site's PHP version here") }} + +
+
+ + + + @foreach($site->server->installedPHPVersions() as $php) + + @endforeach + + @error('version') + + @enderror +
+
+ + + @if (session('status') === 'changing-php-version') +

{{ __('Updating...') }}

+ @endif + @if (session('status') === 'change-site-php-finished') +

{{ __('Updated!') }}

+ @endif + @if (session('status') === 'change-site-php-failed') +

{{ __('Failed!') }}

+ @endif + {{ __('Save') }} +
+
diff --git a/resources/views/livewire/sites/create-site.blade.php b/resources/views/livewire/sites/create-site.blade.php new file mode 100644 index 0000000..237ac4f --- /dev/null +++ b/resources/views/livewire/sites/create-site.blade.php @@ -0,0 +1,104 @@ +
+ + {{ __("Create new site") }} + {{ __("Use this form to create a new site") }} +
+
+ {{ __("Select site type") }} +
+ @foreach(config('core.site_types') as $t) + +
+ Server + +
+
+ @endforeach +
+ @error('type') + + @enderror +
+ +
+ + + @error('domain') + + @enderror +
+ +
+ + + @error('alias') + + @enderror +
+ +
+ + + + @foreach($server->installedPHPVersions() as $version) + + @endforeach + + @error('php_version') + + @enderror +
+ +
+ + + @error('web_directory') + + @enderror +
+ +
+ + + + @foreach($sourceControls as $sourceControl) + + @endforeach + + @error('source_control') + + @enderror +
+ +
+ + + @error('repository') + + @enderror +
+ +
+ + + @error('branch') + + @enderror +
+ +
+ +
+
+ + {{ __('Create') }} + +
+
diff --git a/resources/views/livewire/sites/delete-site.blade.php b/resources/views/livewire/sites/delete-site.blade.php new file mode 100644 index 0000000..06b4cef --- /dev/null +++ b/resources/views/livewire/sites/delete-site.blade.php @@ -0,0 +1,9 @@ +
+ {{ __("Delete Site") }} + +
diff --git a/resources/views/livewire/sites/partials/installation-failed.blade.php b/resources/views/livewire/sites/partials/installation-failed.blade.php new file mode 100644 index 0000000..9e6b478 --- /dev/null +++ b/resources/views/livewire/sites/partials/installation-failed.blade.php @@ -0,0 +1,10 @@ + + + {{ __("Installation Failed!") }} + + {{ __("Your site's installation failed") }} +
+ {{ __("View Logs") }} + +
+
diff --git a/resources/views/livewire/sites/partials/installing.blade.php b/resources/views/livewire/sites/partials/installing.blade.php new file mode 100644 index 0000000..f6efd0b --- /dev/null +++ b/resources/views/livewire/sites/partials/installing.blade.php @@ -0,0 +1,13 @@ + + {{ __("Installing") }} + {{ __("The site is being installed") }} +
+
+ + {{ $site->progress }}% + +
+
diff --git a/resources/views/livewire/sites/partials/site-overview.blade.php b/resources/views/livewire/sites/partials/site-overview.blade.php new file mode 100644 index 0000000..e21c6e1 --- /dev/null +++ b/resources/views/livewire/sites/partials/site-overview.blade.php @@ -0,0 +1,38 @@ +
+ + + {{ __("Site Overview") }} + + + {{ $site->domain }} + + + @include('livewire.sites.partials.status', ['status' => $site->status]) + + +
+
+
+ + +
+
+ {{ $site->activeSsl ? __("Yes") : __("No") }} +
+
+
+
+ + +
+
{{ $site->queues()->count() }}
+
+
+
+ + +
+
{{ $site->php_version }}
+
+
+
diff --git a/resources/views/livewire/sites/partials/status.blade.php b/resources/views/livewire/sites/partials/status.blade.php new file mode 100644 index 0000000..3733b45 --- /dev/null +++ b/resources/views/livewire/sites/partials/status.blade.php @@ -0,0 +1,12 @@ +@if($status == \App\Enums\SiteStatus::READY) + {{ $status }} +@endif +@if($status == \App\Enums\SiteStatus::INSTALLING) + {{ $status }} +@endif +@if($status == \App\Enums\SiteStatus::INSTALLATION_FAILED) + {{ $status }} +@endif +@if($status == \App\Enums\SiteStatus::DELETING) + {{ $status }} +@endif diff --git a/resources/views/livewire/sites/show-site.blade.php b/resources/views/livewire/sites/show-site.blade.php new file mode 100644 index 0000000..7822af0 --- /dev/null +++ b/resources/views/livewire/sites/show-site.blade.php @@ -0,0 +1,13 @@ +
+ @if($site->status === \App\Enums\SiteStatus::INSTALLING) + @include('livewire.sites.partials.installing', ['site' => $site]) + @endif + @if($site->status === \App\Enums\SiteStatus::INSTALLATION_FAILED) + @include('livewire.sites.partials.installation-failed', ['site' => $site]) + @endif + @if($site->status === \App\Enums\SiteStatus::READY) +
+ @include('livewire.sites.partials.site-overview', ['site' => $site]) +
+ @endif +
diff --git a/resources/views/livewire/sites/sites-list.blade.php b/resources/views/livewire/sites/sites-list.blade.php new file mode 100644 index 0000000..ccb49fa --- /dev/null +++ b/resources/views/livewire/sites/sites-list.blade.php @@ -0,0 +1,42 @@ +
+ + Sites + Your sites will appear here. You can see the details and manage them + + + {{ __('Create Site') }} + + + + + @if(count($sites) > 0) + + @else + +
+ {{ __("You don't have any sites yet!") }} +
+
+ @endif +
diff --git a/resources/views/livewire/source-controls/bitbucket.blade.php b/resources/views/livewire/source-controls/bitbucket.blade.php new file mode 100644 index 0000000..375cf01 --- /dev/null +++ b/resources/views/livewire/source-controls/bitbucket.blade.php @@ -0,0 +1,48 @@ +
+ +
+ @include('livewire.source-controls.partials.bitbucket-icon') +
+
+ {{ __("Bitbucket") }} +
+
+
+ @if($sourceControl) + {{ __("Modify") }} + @else + {{ __("Connect") }} + @endif +
+
+
+ +
+

+ {{ __('Connect to Bitbucket') }} +

+ +
+ + + @error('token') + + @enderror +
+ +
+ @if (session('status') === 'bitbucket-updated') +

{{ __('Updated') }}

+ @endif + + + {{ __('Cancel') }} + + + + {{ __('Connect') }} + +
+
+
+
diff --git a/resources/views/livewire/source-controls/github.blade.php b/resources/views/livewire/source-controls/github.blade.php new file mode 100644 index 0000000..7f52ab0 --- /dev/null +++ b/resources/views/livewire/source-controls/github.blade.php @@ -0,0 +1,48 @@ +
+ +
+ @include('livewire.source-controls.partials.github-icon') +
+
+ {{ __("Github") }} +
+
+
+ @if($sourceControl) + {{ __("Modify") }} + @else + {{ __("Connect") }} + @endif +
+
+
+ +
+

+ {{ __('Connect to Github') }} +

+ +
+ + + @error('token') + + @enderror +
+ +
+ @if (session('status') === 'github-updated') +

{{ __('Updated') }}

+ @endif + + + {{ __('Cancel') }} + + + + {{ __('Connect') }} + +
+
+
+
diff --git a/resources/views/livewire/source-controls/gitlab.blade.php b/resources/views/livewire/source-controls/gitlab.blade.php new file mode 100644 index 0000000..63cf4ce --- /dev/null +++ b/resources/views/livewire/source-controls/gitlab.blade.php @@ -0,0 +1,48 @@ +
+ +
+ @include('livewire.source-controls.partials.gitlab-icon') +
+
+ {{ __("Gitlab") }} +
+
+
+ @if($sourceControl) + {{ __("Modify") }} + @else + {{ __("Connect") }} + @endif +
+
+
+ +
+

+ {{ __('Connect to Gitlab') }} +

+ +
+ + + @error('token') + + @enderror +
+ +
+ @if (session('status') === 'gitlab-updated') +

{{ __('Updated') }}

+ @endif + + + {{ __('Cancel') }} + + + + {{ __('Connect') }} + +
+
+
+
diff --git a/resources/views/livewire/source-controls/partials/bitbucket-icon.blade.php b/resources/views/livewire/source-controls/partials/bitbucket-icon.blade.php new file mode 100644 index 0000000..c0686c9 --- /dev/null +++ b/resources/views/livewire/source-controls/partials/bitbucket-icon.blade.php @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/resources/views/livewire/source-controls/partials/github-icon.blade.php b/resources/views/livewire/source-controls/partials/github-icon.blade.php new file mode 100644 index 0000000..b10ec75 --- /dev/null +++ b/resources/views/livewire/source-controls/partials/github-icon.blade.php @@ -0,0 +1,3 @@ + + + diff --git a/resources/views/livewire/source-controls/partials/gitlab-icon.blade.php b/resources/views/livewire/source-controls/partials/gitlab-icon.blade.php new file mode 100644 index 0000000..f724eea --- /dev/null +++ b/resources/views/livewire/source-controls/partials/gitlab-icon.blade.php @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/views/livewire/ssh-keys/add-key.blade.php b/resources/views/livewire/ssh-keys/add-key.blade.php new file mode 100644 index 0000000..29f42ca --- /dev/null +++ b/resources/views/livewire/ssh-keys/add-key.blade.php @@ -0,0 +1,39 @@ +
+ + {{ __('Add new Key') }} + + + +
+

+ {{ __('Add new Key') }} +

+ +
+ + + @error('name') + + @enderror +
+ +
+ + + @error('public_key') + + @enderror +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Add') }} + +
+
+
+
diff --git a/resources/views/livewire/ssh-keys/keys-list.blade.php b/resources/views/livewire/ssh-keys/keys-list.blade.php new file mode 100644 index 0000000..94e715f --- /dev/null +++ b/resources/views/livewire/ssh-keys/keys-list.blade.php @@ -0,0 +1,42 @@ +
+ + {{ __("SSH Keys") }} + {{ __("Add or modify your ssh keys") }} + + + + +
+ @if(count($keys) > 0) + @foreach($keys as $key) + +
+ {{ $key->name }} + + + +
+
+
+ + + +
+
+
+ @endforeach + + @else + +
+ {{ __("You haven't connected to any keys yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/ssl/create-ssl.blade.php b/resources/views/livewire/ssl/create-ssl.blade.php new file mode 100644 index 0000000..c8feabf --- /dev/null +++ b/resources/views/livewire/ssl/create-ssl.blade.php @@ -0,0 +1,54 @@ +
+ + {{ __('Create SSL') }} + + + +
+

+ {{ __('Create SSL') }} +

+ +
+ + + + @foreach(\App\Enums\SslType::getValues() as $t) + + @endforeach + + @error('type') + + @enderror +
+ + @if($type === \App\Enums\SslType::CUSTOM) +
+ + + @error('certificate') + + @enderror +
+ +
+ + + @error('private') + + @enderror +
+ @endif + +
+ + {{ __('Cancel') }} + + + + {{ __('Create') }} + +
+
+
+
diff --git a/resources/views/livewire/ssl/partials/status.blade.php b/resources/views/livewire/ssl/partials/status.blade.php new file mode 100644 index 0000000..3deff63 --- /dev/null +++ b/resources/views/livewire/ssl/partials/status.blade.php @@ -0,0 +1,12 @@ +@if($status == \App\Enums\SslStatus::CREATED) + {{ $status }} +@endif +@if($status == \App\Enums\SslStatus::CREATING) + {{ $status }} +@endif +@if($status == \App\Enums\SslStatus::DELETING) + {{ $status }} +@endif +@if($status == \App\Enums\SslStatus::FAILED) + {{ $status }} +@endif diff --git a/resources/views/livewire/ssl/ssls-list.blade.php b/resources/views/livewire/ssl/ssls-list.blade.php new file mode 100644 index 0000000..3c1e816 --- /dev/null +++ b/resources/views/livewire/ssl/ssls-list.blade.php @@ -0,0 +1,54 @@ +
+ + {{ __("SSLs") }} + {{ __("Here you can manage your site's SSL certificates") }} + + + + +
+ @if(count($ssls) > 0) + + + {{ __("Type") }} + {{ __("Created") }} + {{ __("Expires at") }} + + + @foreach($ssls as $ssl) + + {{ $ssl->type }} + + + + + + + +
+ @include('livewire.ssl.partials.status', ['status' => $ssl->status]) +
+ + + +
+
+
+ + @endforeach +
+ + @else + +
+ {{ __("You don't have any SSL certificates yet!") }} +
+
+ @endif +
+
diff --git a/resources/views/livewire/user-dropdown.blade.php b/resources/views/livewire/user-dropdown.blade.php new file mode 100644 index 0000000..e63f24c --- /dev/null +++ b/resources/views/livewire/user-dropdown.blade.php @@ -0,0 +1,31 @@ + diff --git a/resources/views/notification-channels/index.blade.php b/resources/views/notification-channels/index.blade.php new file mode 100644 index 0000000..547a0f3 --- /dev/null +++ b/resources/views/notification-channels/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Notification Channels") }} + + + diff --git a/resources/views/php/index.blade.php b/resources/views/php/index.blade.php new file mode 100644 index 0000000..7740a32 --- /dev/null +++ b/resources/views/php/index.blade.php @@ -0,0 +1,9 @@ + + {{ __("PHP") }} + + + + @if($server->defaultService('php')) + + @endif + diff --git a/resources/views/profile/index.blade.php b/resources/views/profile/index.blade.php new file mode 100644 index 0000000..9684daf --- /dev/null +++ b/resources/views/profile/index.blade.php @@ -0,0 +1,7 @@ + + {{ __("Profile") }} + + + + + diff --git a/resources/views/server-providers/index.blade.php b/resources/views/server-providers/index.blade.php new file mode 100644 index 0000000..f089020 --- /dev/null +++ b/resources/views/server-providers/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Server Providers") }} + + + diff --git a/resources/views/server-settings/index.blade.php b/resources/views/server-settings/index.blade.php new file mode 100644 index 0000000..741a7c1 --- /dev/null +++ b/resources/views/server-settings/index.blade.php @@ -0,0 +1,38 @@ + + {{ __("Settings") }} + + + + + {{ __("Public Key") }} + {{ __("Your server's public key is here") }} +
+
+
+ + {{ __("Public Key") }} + + +
+ {{ __("Copied") }} + +
+
{{ __("Copy") }}
+
+
+ {{ $server->public_key }} +
+
+
+ + + + + {{ __("Delete Server") }} + {{ __("Permanently delete the server.") }} +

{{ __("Once your server is deleted, all of its resources and data will be permanently deleted and can't be restored") }}

+
+ +
+
+
diff --git a/resources/views/server-ssh-keys/index.blade.php b/resources/views/server-ssh-keys/index.blade.php new file mode 100644 index 0000000..98ecf39 --- /dev/null +++ b/resources/views/server-ssh-keys/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("SSH Keys") }} + + + diff --git a/resources/views/servers/create.blade.php b/resources/views/servers/create.blade.php new file mode 100644 index 0000000..795cf16 --- /dev/null +++ b/resources/views/servers/create.blade.php @@ -0,0 +1,5 @@ + + {{ __("Create Server") }} + + + diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php new file mode 100644 index 0000000..470c0a1 --- /dev/null +++ b/resources/views/servers/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Servers") }} + + + diff --git a/resources/views/servers/logs.blade.php b/resources/views/servers/logs.blade.php new file mode 100644 index 0000000..c5d3608 --- /dev/null +++ b/resources/views/servers/logs.blade.php @@ -0,0 +1,5 @@ + + {{ $server->name }} Logs + + + diff --git a/resources/views/servers/show.blade.php b/resources/views/servers/show.blade.php new file mode 100644 index 0000000..d7dc2fc --- /dev/null +++ b/resources/views/servers/show.blade.php @@ -0,0 +1,5 @@ + + {{ $server->name }} + + + diff --git a/resources/views/services/index.blade.php b/resources/views/services/index.blade.php new file mode 100644 index 0000000..08ea0fe --- /dev/null +++ b/resources/views/services/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Services") }} + + + diff --git a/resources/views/sites/application.blade.php b/resources/views/sites/application.blade.php new file mode 100644 index 0000000..7b34418 --- /dev/null +++ b/resources/views/sites/application.blade.php @@ -0,0 +1,15 @@ + + {{ __("Application") }} + + @if($site->type == \App\Enums\SiteType::LARAVEL) + + @endif + + @if($site->type == \App\Enums\SiteType::PHP) + + @endif + + @if($site->type == \App\Enums\SiteType::WORDPRESS) + + @endif + diff --git a/resources/views/sites/create.blade.php b/resources/views/sites/create.blade.php new file mode 100644 index 0000000..8c85b9c --- /dev/null +++ b/resources/views/sites/create.blade.php @@ -0,0 +1,5 @@ + + {{ __("Create Site") }} + + + diff --git a/resources/views/sites/index.blade.php b/resources/views/sites/index.blade.php new file mode 100644 index 0000000..1f0f475 --- /dev/null +++ b/resources/views/sites/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("Sites") }} + + + diff --git a/resources/views/sites/logs.blade.php b/resources/views/sites/logs.blade.php new file mode 100644 index 0000000..16b11e3 --- /dev/null +++ b/resources/views/sites/logs.blade.php @@ -0,0 +1,5 @@ + + {{ __("Logs") }} + + + diff --git a/resources/views/sites/queues.blade.php b/resources/views/sites/queues.blade.php new file mode 100644 index 0000000..e4f518b --- /dev/null +++ b/resources/views/sites/queues.blade.php @@ -0,0 +1,5 @@ + + {{ __("Queues") }} + + + diff --git a/resources/views/sites/settings.blade.php b/resources/views/sites/settings.blade.php new file mode 100644 index 0000000..4e1d5e5 --- /dev/null +++ b/resources/views/sites/settings.blade.php @@ -0,0 +1,14 @@ + + {{ __("Settings") }} + + + + + {{ __("Delete Site") }} + {{ __("Permanently delete the site from server") }} +

{{ __("Once your site is deleted, all of its files will be deleted from the server.") }}

+
+ +
+
+
diff --git a/resources/views/sites/show.blade.php b/resources/views/sites/show.blade.php new file mode 100644 index 0000000..5e7354e --- /dev/null +++ b/resources/views/sites/show.blade.php @@ -0,0 +1,7 @@ + + {{ $site->domain }} + + + + + diff --git a/resources/views/sites/ssl.blade.php b/resources/views/sites/ssl.blade.php new file mode 100644 index 0000000..94f6ce2 --- /dev/null +++ b/resources/views/sites/ssl.blade.php @@ -0,0 +1,5 @@ + + {{ __("SSL") }} + + + diff --git a/resources/views/source-controls/index.blade.php b/resources/views/source-controls/index.blade.php new file mode 100644 index 0000000..7b9aa94 --- /dev/null +++ b/resources/views/source-controls/index.blade.php @@ -0,0 +1,20 @@ + + {{ __("Source Controls") }} + +
+ + Source Controls + You can connect your source controls via API Tokens + + +
+ @if(session('status') == 'not-connected') +
{{ session('message') }}
+ @endif + + + +
+
+ +
diff --git a/resources/views/ssh-keys/index.blade.php b/resources/views/ssh-keys/index.blade.php new file mode 100644 index 0000000..8eb54bd --- /dev/null +++ b/resources/views/ssh-keys/index.blade.php @@ -0,0 +1,5 @@ + + {{ __("SSH Keys") }} + + + diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..889937e --- /dev/null +++ b/routes/api.php @@ -0,0 +1,19 @@ +get('/user', function (Request $request) { + return $request->user(); +}); diff --git a/routes/auth.php b/routes/auth.php new file mode 100644 index 0000000..e7f7c46 --- /dev/null +++ b/routes/auth.php @@ -0,0 +1,24 @@ +group(function () { + Route::get('login', [AuthenticatedSessionController::class, 'create'])->name('login'); + Route::post('login', [AuthenticatedSessionController::class, 'store']); + Route::get('forgot-password', [PasswordResetLinkController::class, 'create'])->name('password.request'); + Route::post('forgot-password', [PasswordResetLinkController::class, 'store'])->name('password.email'); + Route::get('reset-password/{token}', [NewPasswordController::class, 'create'])->name('password.reset'); + Route::post('reset-password', [NewPasswordController::class, 'store'])->name('password.store'); +}); + +Route::middleware('auth')->group(function () { + Route::get('confirm-password', [ConfirmablePasswordController::class, 'show'])->name('password.confirm'); + Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']); + Route::put('password', [PasswordController::class, 'update'])->name('password.update'); + Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])->name('logout'); +}); diff --git a/routes/channels.php b/routes/channels.php new file mode 100644 index 0000000..d811fa4 --- /dev/null +++ b/routes/channels.php @@ -0,0 +1,8 @@ +id; +}); diff --git a/routes/console.php b/routes/console.php new file mode 100644 index 0000000..e05f4c9 --- /dev/null +++ b/routes/console.php @@ -0,0 +1,19 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote'); diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..5ef0a17 --- /dev/null +++ b/routes/web.php @@ -0,0 +1,53 @@ +route('login'); +}); + +Route::middleware('auth')->group(function () { + Route::prefix('/settings')->group(function () { + Route::view('/profile', 'profile.index')->name('profile'); + Route::view('/server-providers', 'server-providers.index')->name('server-providers'); + Route::view('/source-controls', 'source-controls.index')->name('source-controls'); + Route::view('/notification-channels', 'notification-channels.index')->name('notification-channels'); + Route::view('/ssh-keys', 'ssh-keys.index')->name('ssh-keys'); + }); + Route::prefix('/servers')->group(function () { + Route::get('/', [ServerController::class, 'index'])->name('servers'); + Route::get('/create', [ServerController::class, 'create'])->name('servers.create'); + Route::get('/{server}', [ServerController::class, 'show'])->name('servers.show'); + Route::get('/{server}/logs', [ServerController::class, 'logs'])->name('servers.logs'); + Route::get('/{server}/settings', [ServerSettingController::class, 'index'])->name('servers.settings'); + Route::get('/{server}/databases', [DatabaseController::class, 'index'])->name('servers.databases'); + Route::prefix('/{server}/sites')->group(function () { + Route::get('/', [SiteController::class, 'index'])->name('servers.sites'); + Route::get('/create', [SiteController::class, 'create'])->name('servers.sites.create'); + Route::get('/{site}', [SiteController::class, 'show'])->name('servers.sites.show'); + Route::get('/{site}/application', [SiteController::class, 'application'])->name('servers.sites.application'); + Route::get('/{site}/ssl', [SiteController::class, 'ssl'])->name('servers.sites.ssl'); + Route::get('/{site}/queues', [SiteController::class, 'queues'])->name('servers.sites.queues'); + Route::get('/{site}/settings', [SiteController::class, 'settings'])->name('servers.sites.settings'); + Route::get('/{site}/logs', [SiteController::class, 'logs'])->name('servers.sites.logs'); + }); + Route::get('/{server}/php', [PHPController::class, 'index'])->name('servers.php'); + Route::get('/{server}/firewall', [FirewallController::class, 'index'])->name('servers.firewall'); + Route::get('/{server}/cronjobs', [CronjobController::class, 'index'])->name('servers.cronjobs'); + Route::get('/{server}/daemons', [DaemonController::class, 'index'])->name('servers.daemons'); + Route::get('/{server}/services', [ServiceController::class, 'index'])->name('servers.services'); + Route::get('/{server}/ssh-keys', [SSHKeyController::class, 'index'])->name('servers.ssh-keys'); + }); +}); + +require __DIR__.'/auth.php'; diff --git a/sail b/sail new file mode 100755 index 0000000..af31cc0 --- /dev/null +++ b/sail @@ -0,0 +1,486 @@ +#!/usr/bin/env bash + +UNAMEOUT="$(uname -s)" + +# Verify operating system is supported... +case "${UNAMEOUT}" in + Linux*) MACHINE=linux;; + Darwin*) MACHINE=mac;; + *) MACHINE="UNKNOWN" +esac + +if [ "$MACHINE" == "UNKNOWN" ]; then + echo "Unsupported operating system [$(uname -s)]. Laravel Sail supports macOS, Linux, and Windows (WSL2)." >&2 + + exit 1 +fi + +# Determine if stdout is a terminal... +if test -t 1; then + # Determine if colors are supported... + ncolors=$(tput colors) + + if test -n "$ncolors" && test "$ncolors" -ge 8; then + BOLD="$(tput bold)" + YELLOW="$(tput setaf 3)" + GREEN="$(tput setaf 2)" + NC="$(tput sgr0)" + fi +fi + +# Function that prints the available commands... +function display_help { + echo "Laravel Sail" + echo + echo "${YELLOW}Usage:${NC}" >&2 + echo " sail COMMAND [options] [arguments]" + echo + echo "Unknown commands are passed to the docker-compose binary." + echo + echo "${YELLOW}docker-compose Commands:${NC}" + echo " ${GREEN}sail up${NC} Start the application" + echo " ${GREEN}sail up -d${NC} Start the application in the background" + echo " ${GREEN}sail stop${NC} Stop the application" + echo " ${GREEN}sail restart${NC} Restart the application" + echo " ${GREEN}sail ps${NC} Display the status of all containers" + echo + echo "${YELLOW}Artisan Commands:${NC}" + echo " ${GREEN}sail artisan ...${NC} Run an Artisan command" + echo " ${GREEN}sail artisan queue:work${NC}" + echo + echo "${YELLOW}PHP Commands:${NC}" + echo " ${GREEN}sail php ...${NC} Run a snippet of PHP code" + echo " ${GREEN}sail php -v${NC}" + echo + echo "${YELLOW}Composer Commands:${NC}" + echo " ${GREEN}sail composer ...${NC} Run a Composer command" + echo " ${GREEN}sail composer require laravel/sanctum${NC}" + echo + echo "${YELLOW}Node Commands:${NC}" + echo " ${GREEN}sail node ...${NC} Run a Node command" + echo " ${GREEN}sail node --version${NC}" + echo + echo "${YELLOW}NPM Commands:${NC}" + echo " ${GREEN}sail npm ...${NC} Run a npm command" + echo " ${GREEN}sail npx${NC} Run a npx command" + echo " ${GREEN}sail npm run prod${NC}" + echo + echo "${YELLOW}Yarn Commands:${NC}" + echo " ${GREEN}sail yarn ...${NC} Run a Yarn command" + echo " ${GREEN}sail yarn run prod${NC}" + echo + echo "${YELLOW}Database Commands:${NC}" + echo " ${GREEN}sail mysql${NC} Start a MySQL CLI session within the 'mysql' container" + echo " ${GREEN}sail mariadb${NC} Start a MySQL CLI session within the 'mariadb' container" + echo " ${GREEN}sail psql${NC} Start a PostgreSQL CLI session within the 'pgsql' container" + echo " ${GREEN}sail redis${NC} Start a Redis CLI session within the 'redis' container" + echo + echo "${YELLOW}Debugging:${NC}" + echo " ${GREEN}sail debug ...${NC} Run an Artisan command in debug mode" + echo " ${GREEN}sail debug queue:work${NC}" + echo + echo "${YELLOW}Running Tests:${NC}" + echo " ${GREEN}sail test${NC} Run the PHPUnit tests via the Artisan test command" + echo " ${GREEN}sail phpunit ...${NC} Run PHPUnit" + echo " ${GREEN}sail pint ...${NC} Run Pint" + echo " ${GREEN}sail dusk${NC} Run the Dusk tests (Requires the laravel/dusk package)" + echo " ${GREEN}sail dusk:fails${NC} Re-run previously failed Dusk tests (Requires the laravel/dusk package)" + echo + echo "${YELLOW}Container CLI:${NC}" + echo " ${GREEN}sail shell${NC} Start a shell session within the application container" + echo " ${GREEN}sail bash${NC} Alias for 'sail shell'" + echo " ${GREEN}sail root-shell${NC} Start a root shell session within the application container" + echo " ${GREEN}sail root-bash${NC} Alias for 'sail root-shell'" + echo " ${GREEN}sail tinker${NC} Start a new Laravel Tinker session" + echo + echo "${YELLOW}Sharing:${NC}" + echo " ${GREEN}sail share${NC} Share the application publicly via a temporary URL" + echo + echo "${YELLOW}Binaries:${NC}" + echo " ${GREEN}sail bin ...${NC} Run Composer binary scripts from the vendor/bin directory" + echo + echo "${YELLOW}Customization:${NC}" + echo " ${GREEN}sail artisan sail:publish${NC} Publish the Sail configuration files" + echo " ${GREEN}sail build --no-cache${NC} Rebuild all of the Sail containers" + + exit 1 +} + +# Proxy the "help" command... +if [ $# -gt 0 ]; then + if [ "$1" == "help" ] || [ "$1" == "-h" ] || [ "$1" == "-help" ] || [ "$1" == "--help" ]; then + display_help + fi +else + display_help +fi + +# Source the ".env" file so Laravel's environment variables are available... +if [ -f ./.env ]; then + source ./.env +fi + +# Define environment variables... +export APP_PORT=${APP_PORT:-80} +export APP_SERVICE=${APP_SERVICE:-"laravel.test"} +export DB_PORT=${DB_PORT:-3306} +export WWWUSER=${WWWUSER:-$UID} +export WWWGROUP=${WWWGROUP:-$(id -g)} + +export SAIL_FILES=${SAIL_FILES:-""} +export SAIL_SHARE_DASHBOARD=${SAIL_SHARE_DASHBOARD:-4040} +export SAIL_SHARE_SERVER_HOST=${SAIL_SHARE_SERVER_HOST:-"laravel-sail.site"} +export SAIL_SHARE_SERVER_PORT=${SAIL_SHARE_SERVER_PORT:-8080} +export SAIL_SHARE_SUBDOMAIN=${SAIL_SHARE_SUBDOMAIN:-""} + +# Function that outputs Sail is not running... +function sail_is_not_running { + echo "${BOLD}Sail is not running.${NC}" >&2 + echo "" >&2 + echo "${BOLD}You may Sail using the following commands:${NC} './vendor/bin/sail up' or './vendor/bin/sail up -d'" >&2 + + exit 1 +} + +# Define Docker Compose command prefix... +docker compose &> /dev/null +if [ $? == 0 ]; then + DOCKER_COMPOSE=(docker compose) +else + DOCKER_COMPOSE=(docker-compose) +fi + +if [ -n "$SAIL_FILES" ]; then + # Convert SAIL_FILES to an array... + IFS=':' read -ra SAIL_FILES <<< "$SAIL_FILES" + + for FILE in "${SAIL_FILES[@]}"; do + if [ -f "$FILE" ]; then + DOCKER_COMPOSE+=(-f "$FILE") + else + echo "${BOLD}Unable to find Docker Compose file: '${FILE}'${NC}" >&2 + + exit 1 + fi + done +fi + +EXEC="yes" + +if [ -z "$SAIL_SKIP_CHECKS" ]; then + # Ensure that Docker is running... + if ! docker info > /dev/null 2>&1; then + echo "${BOLD}Docker is not running.${NC}" >&2 + + exit 1 + fi + + # Determine if Sail is currently up... + if "${DOCKER_COMPOSE[@]}" ps "$APP_SERVICE" 2>&1 | grep 'Exit\|exited'; then + echo "${BOLD}Shutting down old Sail processes...${NC}" >&2 + + "${DOCKER_COMPOSE[@]}" down > /dev/null 2>&1 + + EXEC="no" + elif [ -z "$("${DOCKER_COMPOSE[@]}" ps -q)" ]; then + EXEC="no" + fi +fi + +ARGS=() + +# Proxy PHP commands to the "php" binary on the application container... +if [ "$1" == "php" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" "php" "$@") + else + sail_is_not_running + fi + +# Proxy vendor binary commands on the application container... +elif [ "$1" == "bin" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" ./vendor/bin/"$@") + else + sail_is_not_running + fi + +# Proxy docker-compose commands to the docker-compose binary on the application container... +elif [ "$1" == "docker-compose" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" "${DOCKER_COMPOSE[@]}") + else + sail_is_not_running + fi + +# Proxy Composer commands to the "composer" binary on the application container... +elif [ "$1" == "composer" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" "composer" "$@") + else + sail_is_not_running + fi + +# Proxy Artisan commands to the "artisan" binary on the application container... +elif [ "$1" == "artisan" ] || [ "$1" == "art" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" php artisan "$@") + else + sail_is_not_running + fi + +# Proxy the "debug" command to the "php artisan" binary on the application container with xdebug enabled... +elif [ "$1" == "debug" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail -e XDEBUG_SESSION=1) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" php artisan "$@") + else + sail_is_not_running + fi + +# Proxy the "test" command to the "php artisan test" Artisan command... +elif [ "$1" == "test" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" php artisan test "$@") + else + sail_is_not_running + fi + +# Proxy the "phpunit" command to "php vendor/bin/phpunit"... +elif [ "$1" == "phpunit" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" php vendor/bin/phpunit "$@") + else + sail_is_not_running + fi + +# Proxy the "pint" command to "php vendor/bin/pint"... +elif [ "$1" == "pint" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" php vendor/bin/pint "$@") + else + sail_is_not_running + fi + +# Proxy the "dusk" command to the "php artisan dusk" Artisan command... +elif [ "$1" == "dusk" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=(-e "APP_URL=http://${APP_SERVICE}") + ARGS+=(-e "DUSK_DRIVER_URL=http://selenium:4444/wd/hub") + ARGS+=("$APP_SERVICE" php artisan dusk "$@") + else + sail_is_not_running + fi + +# Proxy the "dusk:fails" command to the "php artisan dusk:fails" Artisan command... +elif [ "$1" == "dusk:fails" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=(-e "APP_URL=http://${APP_SERVICE}") + ARGS+=(-e "DUSK_DRIVER_URL=http://selenium:4444/wd/hub") + ARGS+=("$APP_SERVICE" php artisan dusk:fails "$@") + else + sail_is_not_running + fi + +# Initiate a Laravel Tinker session within the application container... +elif [ "$1" == "tinker" ] ; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" php artisan tinker) + else + sail_is_not_running + fi + +# Proxy Node commands to the "node" binary on the application container... +elif [ "$1" == "node" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" node "$@") + else + sail_is_not_running + fi + +# Proxy NPM commands to the "npm" binary on the application container... +elif [ "$1" == "npm" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" npm "$@") + else + sail_is_not_running + fi + +# Proxy NPX commands to the "npx" binary on the application container... +elif [ "$1" == "npx" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" npx "$@") + else + sail_is_not_running + fi + +# Proxy YARN commands to the "yarn" binary on the application container... +elif [ "$1" == "yarn" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" yarn "$@") + else + sail_is_not_running + fi + +# Initiate a MySQL CLI terminal session within the "mysql" container... +elif [ "$1" == "mysql" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=(mysql bash -c) + ARGS+=("MYSQL_PWD=\${MYSQL_PASSWORD} mysql -u \${MYSQL_USER} \${MYSQL_DATABASE}") + else + sail_is_not_running + fi + +# Initiate a MySQL CLI terminal session within the "mariadb" container... +elif [ "$1" == "mariadb" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=(mariadb bash -c) + ARGS+=("MYSQL_PWD=\${MYSQL_PASSWORD} mysql -u \${MYSQL_USER} \${MYSQL_DATABASE}") + else + sail_is_not_running + fi + +# Initiate a PostgreSQL CLI terminal session within the "pgsql" container... +elif [ "$1" == "psql" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=(pgsql bash -c) + ARGS+=("PGPASSWORD=\${PGPASSWORD} psql -U \${POSTGRES_USER} \${POSTGRES_DB}") + else + sail_is_not_running + fi + +# Initiate a Bash shell within the application container... +elif [ "$1" == "shell" ] || [ "$1" == "bash" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec -u sail) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" bash "$@") + else + sail_is_not_running + fi + +# Initiate a root user Bash shell within the application container... +elif [ "$1" == "root-shell" ] || [ "$1" == "root-bash" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=("$APP_SERVICE" bash "$@") + else + sail_is_not_running + fi + +# Initiate a Redis CLI terminal session within the "redis" container... +elif [ "$1" == "redis" ] ; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + ARGS+=(exec) + [ ! -t 0 ] && ARGS+=(-T) + ARGS+=(redis redis-cli) + else + sail_is_not_running + fi + +# Share the site... +elif [ "$1" == "share" ]; then + shift 1 + + if [ "$EXEC" == "yes" ]; then + docker run --init --rm -p "$SAIL_SHARE_DASHBOARD":4040 -t beyondcodegmbh/expose-server:latest share http://host.docker.internal:"$APP_PORT" \ + --server-host="$SAIL_SHARE_SERVER_HOST" \ + --server-port="$SAIL_SHARE_SERVER_PORT" \ + --auth="$SAIL_SHARE_TOKEN" \ + --subdomain="$SAIL_SHARE_SUBDOMAIN" \ + "$@" + + exit + else + sail_is_not_running + fi + +# Pass unknown commands to the "docker-compose" binary... +else + ARGS+=("$@") +fi + +# Run Docker Compose with the defined arguments... +"${DOCKER_COMPOSE[@]}" "${ARGS[@]}" diff --git a/storage/app/.gitignore b/storage/app/.gitignore new file mode 100644 index 0000000..8f4803c --- /dev/null +++ b/storage/app/.gitignore @@ -0,0 +1,3 @@ +* +!public/ +!.gitignore diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/public/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/.gitignore b/storage/framework/.gitignore new file mode 100644 index 0000000..05c4471 --- /dev/null +++ b/storage/framework/.gitignore @@ -0,0 +1,9 @@ +compiled.php +config.php +down +events.scanned.php +maintenance.php +routes.php +routes.scanned.php +schedule-* +services.json diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore new file mode 100644 index 0000000..01e4a6c --- /dev/null +++ b/storage/framework/cache/.gitignore @@ -0,0 +1,3 @@ +* +!data/ +!.gitignore diff --git a/storage/framework/cache/data/.gitignore b/storage/framework/cache/data/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/cache/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/sessions/.gitignore b/storage/framework/sessions/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/sessions/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/testing/.gitignore b/storage/framework/testing/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/testing/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/views/.gitignore b/storage/framework/views/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/views/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/logs/.gitignore b/storage/logs/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/system/command-templates/nginx/nginx.conf b/system/command-templates/nginx/nginx.conf new file mode 100755 index 0000000..1e3046b --- /dev/null +++ b/system/command-templates/nginx/nginx.conf @@ -0,0 +1,85 @@ +user __user__; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} + + +#mail { +# # See sample authentication script at: +# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript +# +# # auth_http localhost/auth.php; +# # pop3_capabilities "TOP" "USER"; +# # imap_capabilities "IMAP4rev1" "UIDPLUS"; +# +# server { +# listen localhost:110; +# protocol pop3; +# proxy on; +# } +# +# server { +# listen localhost:143; +# protocol imap; +# proxy on; +# } +#} diff --git a/system/command-templates/nginx/php-vhost-ssl.conf b/system/command-templates/nginx/php-vhost-ssl.conf new file mode 100755 index 0000000..64c741f --- /dev/null +++ b/system/command-templates/nginx/php-vhost-ssl.conf @@ -0,0 +1,38 @@ +server { + listen 80; + listen 443 ssl; + server_name __domain__ www.__domain__; + root __path__/__web_directory__; + + ssl on; + ssl_certificate __certificate__; + ssl_certificate_key __private_key__; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php; + + charset utf-8; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php__php_version__-fpm.sock; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ /\.(?!well-known).* { + deny all; + } + + include conf.d/__domain___redirects; +} diff --git a/system/command-templates/nginx/php-vhost.conf b/system/command-templates/nginx/php-vhost.conf new file mode 100755 index 0000000..5d26a40 --- /dev/null +++ b/system/command-templates/nginx/php-vhost.conf @@ -0,0 +1,33 @@ +server { + listen 80; + server_name __domain__ www.__domain__; + root __path__/__web_directory__; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php; + + charset utf-8; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php__php_version__-fpm.sock; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ /\.(?!well-known).* { + deny all; + } + + include conf.d/__domain___redirects; +} diff --git a/system/command-templates/nginx/phpmyadmin-vhost.conf b/system/command-templates/nginx/phpmyadmin-vhost.conf new file mode 100755 index 0000000..490743a --- /dev/null +++ b/system/command-templates/nginx/phpmyadmin-vhost.conf @@ -0,0 +1,31 @@ +server { + listen 54331; + server_name _; + root /home/vito/phpmyadmin; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php; + + charset utf-8; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php__php_version__-fpm.sock; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ /\.(?!well-known).* { + deny all; + } +} diff --git a/system/command-templates/nginx/redirect.conf b/system/command-templates/nginx/redirect.conf new file mode 100644 index 0000000..bd4f246 --- /dev/null +++ b/system/command-templates/nginx/redirect.conf @@ -0,0 +1,3 @@ +location __from__ { + return __mode__ __to__; +} diff --git a/system/command-templates/nginx/reverse-vhost-ssl.conf b/system/command-templates/nginx/reverse-vhost-ssl.conf new file mode 100755 index 0000000..92127bc --- /dev/null +++ b/system/command-templates/nginx/reverse-vhost-ssl.conf @@ -0,0 +1,36 @@ +server { + listen 80; + listen 443 ssl; + server_name __domain__ __aliases__; + root __path__; + + ssl on; + ssl_certificate __certificate__; + ssl_certificate_key __private_key__; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php; + + charset utf-8; + + location / { + proxy_pass http://127.0.0.1:__port__/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $remote_addr; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ /\.(?!well-known).* { + deny all; + } + + include conf.d/__domain___redirects; +} diff --git a/system/command-templates/nginx/reverse-vhost.conf b/system/command-templates/nginx/reverse-vhost.conf new file mode 100755 index 0000000..e31a3ae --- /dev/null +++ b/system/command-templates/nginx/reverse-vhost.conf @@ -0,0 +1,31 @@ +server { + listen 80; + server_name __domain__ __aliases__; + root __path__; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php; + + charset utf-8; + + location / { + proxy_pass http://127.0.0.1:__port__/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $remote_addr; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ /\.(?!well-known).* { + deny all; + } + + include conf.d/__domain___redirects; +} diff --git a/system/command-templates/nginx/vhost-ssl.conf b/system/command-templates/nginx/vhost-ssl.conf new file mode 100755 index 0000000..3dc7dec --- /dev/null +++ b/system/command-templates/nginx/vhost-ssl.conf @@ -0,0 +1,32 @@ +server { + listen 80; + listen 443 ssl; + server_name __domain__ __aliases__; + root __path__/__web_directory__; + + ssl on; + ssl_certificate __certificate__; + ssl_certificate_key __private_key__; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.html; + + charset utf-8; + + location / { + try_files $uri $uri/ /index.html; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.html; + + location ~ /\.(?!well-known).* { + deny all; + } + + include conf.d/__domain___redirects; +} diff --git a/system/command-templates/nginx/vhost.conf b/system/command-templates/nginx/vhost.conf new file mode 100755 index 0000000..631e3c6 --- /dev/null +++ b/system/command-templates/nginx/vhost.conf @@ -0,0 +1,27 @@ +server { + listen 80; + server_name __domain__ __aliases__; + root __path__/__web_directory__; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.html; + + charset utf-8; + + location / { + try_files $uri $uri/ /index.html; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.html; + + location ~ /\.(?!well-known).* { + deny all; + } + + include conf.d/__domain___redirects; +} diff --git a/system/command-templates/supervisor/worker.conf b/system/command-templates/supervisor/worker.conf new file mode 100644 index 0000000..c21ece5 --- /dev/null +++ b/system/command-templates/supervisor/worker.conf @@ -0,0 +1,10 @@ +[program:__name__] +process_name=%(program_name)s_%(process_num)02d +command=__command__ +autostart=__auto_start__ +autorestart=__auto_restart__ +user=__user__ +numprocs=__numprocs__ +redirect_stderr=true +stdout_logfile=__log_file__ +stopwaitsecs=3600 diff --git a/system/commands/common/clone-repository.sh b/system/commands/common/clone-repository.sh new file mode 100755 index 0000000..d2792af --- /dev/null +++ b/system/commands/common/clone-repository.sh @@ -0,0 +1,23 @@ +ssh-keyscan -H __host__ >> ~/.ssh/known_hosts + +rm -rf __path__ + +if ! git config --global core.fileMode false; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! git clone -b __branch__ __repo__ __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! find __path__ -type d -exec chmod 755 {} \;; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! find __path__ -type f -exec chmod 644 {} \;; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! cd __path__ && git config core.fileMode false; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/composer-install.sh b/system/commands/common/composer-install.sh new file mode 100755 index 0000000..cd5067e --- /dev/null +++ b/system/commands/common/composer-install.sh @@ -0,0 +1,7 @@ +if ! cd __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/create-custom-ssl.sh b/system/commands/common/create-custom-ssl.sh new file mode 100644 index 0000000..aaa44fa --- /dev/null +++ b/system/commands/common/create-custom-ssl.sh @@ -0,0 +1,13 @@ +if ! sudo mkdir __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! echo __certificate__ | sudo tee __certificate_path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! echo __pk__ | sudo tee __pk_path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Successfully received certificate." diff --git a/system/commands/common/create-letsencrypt-ssl.sh b/system/commands/common/create-letsencrypt-ssl.sh new file mode 100644 index 0000000..45ba158 --- /dev/null +++ b/system/commands/common/create-letsencrypt-ssl.sh @@ -0,0 +1,3 @@ +if ! sudo certbot certonly --force-renewal --nginx --noninteractive --agree-tos --cert-name __domain__ -m __email__ -d __domain__ --verbose; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/download-phpmyadmin.sh b/system/commands/common/download-phpmyadmin.sh new file mode 100644 index 0000000..492fbc3 --- /dev/null +++ b/system/commands/common/download-phpmyadmin.sh @@ -0,0 +1,21 @@ +sudo rm -rf phpmyadmin + +if ! wget https://files.phpmyadmin.net/phpMyAdmin/5.1.2/phpMyAdmin-5.1.2-all-languages.zip; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! unzip phpMyAdmin-5.1.2-all-languages.zip; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! rm -rf phpMyAdmin-5.1.2-all-languages.zip; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! mv phpMyAdmin-5.1.2-all-languages phpmyadmin; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! mv phpmyadmin/config.sample.inc.php phpmyadmin/config.inc.php; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/edit-file.sh b/system/commands/common/edit-file.sh new file mode 100644 index 0000000..67e5def --- /dev/null +++ b/system/commands/common/edit-file.sh @@ -0,0 +1,3 @@ +if ! echo "__content__" | tee __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/get-public-key.sh b/system/commands/common/get-public-key.sh new file mode 100755 index 0000000..254fd72 --- /dev/null +++ b/system/commands/common/get-public-key.sh @@ -0,0 +1 @@ +cat ~/.ssh/id_rsa.pub diff --git a/system/commands/common/install-composer.sh b/system/commands/common/install-composer.sh new file mode 100755 index 0000000..c4cdb68 --- /dev/null +++ b/system/commands/common/install-composer.sh @@ -0,0 +1,7 @@ +cd ~ + +curl -sS https://getcomposer.org/installer -o composer-setup.php + +sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer + +composer diff --git a/system/commands/common/run-script.sh b/system/commands/common/run-script.sh new file mode 100644 index 0000000..7ecdab1 --- /dev/null +++ b/system/commands/common/run-script.sh @@ -0,0 +1,5 @@ +if ! cd __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +__script__ diff --git a/system/commands/common/storage/download-from-dropbox.sh b/system/commands/common/storage/download-from-dropbox.sh new file mode 100644 index 0000000..eafa63d --- /dev/null +++ b/system/commands/common/storage/download-from-dropbox.sh @@ -0,0 +1,4 @@ +curl -o __dest__ --location --request POST 'https://content.dropboxapi.com/2/files/download' \ +--header 'Accept: application/json' \ +--header 'Dropbox-API-Arg: {"path":"__src__"}' \ +--header 'Authorization: Bearer __token__' diff --git a/system/commands/common/storage/upload-to-dropbox.sh b/system/commands/common/storage/upload-to-dropbox.sh new file mode 100644 index 0000000..0f427a3 --- /dev/null +++ b/system/commands/common/storage/upload-to-dropbox.sh @@ -0,0 +1,6 @@ +curl --location --request POST 'https://content.dropboxapi.com/2/files/upload' \ +--header 'Accept: application/json' \ +--header 'Dropbox-API-Arg: {"path":"__dest__"}' \ +--header 'Content-Type: text/plain; charset=dropbox-cors-hack' \ +--header 'Authorization: Bearer __token__' \ +--data-binary '@__src__' diff --git a/system/commands/common/update-branch.sh b/system/commands/common/update-branch.sh new file mode 100644 index 0000000..bfaf9b7 --- /dev/null +++ b/system/commands/common/update-branch.sh @@ -0,0 +1,7 @@ +if ! cd __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! git checkout -f __branch__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/update-cron-jobs.sh b/system/commands/common/update-cron-jobs.sh new file mode 100755 index 0000000..aea5170 --- /dev/null +++ b/system/commands/common/update-cron-jobs.sh @@ -0,0 +1,7 @@ +if ! echo '__data__' | sudo -u __user__ crontab -; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo -u __user__ crontab -l; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/common/wordpress/install.sh b/system/commands/common/wordpress/install.sh new file mode 100644 index 0000000..0321d66 --- /dev/null +++ b/system/commands/common/wordpress/install.sh @@ -0,0 +1,27 @@ +if ! curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! chmod +x wp-cli.phar; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo mv wp-cli.phar /usr/local/bin/wp; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +rm -rf __path__ + +if ! wp --path=__path__ core download; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! wp --path=__path__ core config --dbname='__db_name__' --dbuser='__db_user__' --dbpass='__db_pass__' --dbhost='__db_host__' --dbprefix='__db_prefix__'; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! wp --path=__path__ core install --url='http://__domain__' --title="__title__" --admin_user='__username__' --admin_password="__password__" --admin_email='__email__'; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +print "Wordpress installed!" diff --git a/system/commands/database/mysql/backup.sh b/system/commands/database/mysql/backup.sh new file mode 100644 index 0000000..33197f3 --- /dev/null +++ b/system/commands/database/mysql/backup.sh @@ -0,0 +1,11 @@ +if ! sudo DEBIAN_FRONTEND=noninteractive mysqldump -u root __database__ > __file__.sql; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! DEBIAN_FRONTEND=noninteractive zip __file__.zip __file__.sql; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! rm __file__.sql; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/database/mysql/create-user.sh b/system/commands/database/mysql/create-user.sh new file mode 100755 index 0000000..8eb6271 --- /dev/null +++ b/system/commands/database/mysql/create-user.sh @@ -0,0 +1,9 @@ +if ! sudo mysql -e "CREATE USER IF NOT EXISTS '__username__'@'__host__' IDENTIFIED BY '__password__'"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo mysql -e "FLUSH PRIVILEGES"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Command executed" diff --git a/system/commands/database/mysql/create.sh b/system/commands/database/mysql/create.sh new file mode 100755 index 0000000..a318617 --- /dev/null +++ b/system/commands/database/mysql/create.sh @@ -0,0 +1,5 @@ +if ! sudo mysql -e "CREATE DATABASE IF NOT EXISTS __name__ CHARACTER SET utf8 COLLATE utf8_general_ci"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Command executed" diff --git a/system/commands/database/mysql/delete-user.sh b/system/commands/database/mysql/delete-user.sh new file mode 100755 index 0000000..5a82b9b --- /dev/null +++ b/system/commands/database/mysql/delete-user.sh @@ -0,0 +1,9 @@ +if ! sudo mysql -e "DROP USER IF EXISTS '__username__'@'__host__'"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo mysql -e "FLUSH PRIVILEGES"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Command executed" diff --git a/system/commands/database/mysql/delete.sh b/system/commands/database/mysql/delete.sh new file mode 100755 index 0000000..54c06fd --- /dev/null +++ b/system/commands/database/mysql/delete.sh @@ -0,0 +1,5 @@ +if ! sudo mysql -e "DROP DATABASE IF EXISTS __name__"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Command executed" diff --git a/system/commands/database/mysql/link.sh b/system/commands/database/mysql/link.sh new file mode 100755 index 0000000..adbc74b --- /dev/null +++ b/system/commands/database/mysql/link.sh @@ -0,0 +1,9 @@ +if ! sudo mysql -e "GRANT ALL PRIVILEGES ON __database__.* TO '__username__'@'__host__'"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo mysql -e "FLUSH PRIVILEGES"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Linking to __database__ finished" diff --git a/system/commands/database/mysql/restore.sh b/system/commands/database/mysql/restore.sh new file mode 100644 index 0000000..d90826f --- /dev/null +++ b/system/commands/database/mysql/restore.sh @@ -0,0 +1,11 @@ +if ! DEBIAN_FRONTEND=noninteractive unzip __file__.zip; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo DEBIAN_FRONTEND=noninteractive mysql -u root __database__ < __file__.sql; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! rm __file__.sql __file__.zip; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/database/mysql/unlink.sh b/system/commands/database/mysql/unlink.sh new file mode 100755 index 0000000..f1ac881 --- /dev/null +++ b/system/commands/database/mysql/unlink.sh @@ -0,0 +1,5 @@ +if ! sudo mysql -e "REVOKE ALL PRIVILEGES, GRANT OPTION FROM '__username__'@'__host__'"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Command executed" diff --git a/system/commands/firewall/ufw/add-rule.sh b/system/commands/firewall/ufw/add-rule.sh new file mode 100755 index 0000000..af95de0 --- /dev/null +++ b/system/commands/firewall/ufw/add-rule.sh @@ -0,0 +1,11 @@ +if ! sudo ufw __type__ from __source__/__mask__ to any proto __protocol__ port __port__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw reload; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service ufw restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/firewall/ufw/remove-rule.sh b/system/commands/firewall/ufw/remove-rule.sh new file mode 100755 index 0000000..f07ecd2 --- /dev/null +++ b/system/commands/firewall/ufw/remove-rule.sh @@ -0,0 +1,11 @@ +if ! sudo ufw delete __type__ from __source__/__mask__ to any proto __protocol__ port __port__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw reload; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service ufw restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/basics.sh b/system/commands/ubuntu/basics.sh new file mode 100755 index 0000000..5ee2f96 --- /dev/null +++ b/system/commands/ubuntu/basics.sh @@ -0,0 +1 @@ +sudo sed -i "s/#precedence ::ffff:0:0\/96 100/precedence ::ffff:0:0\/96 100/" /etc/gai.conf diff --git a/system/commands/ubuntu/change-default-php.sh b/system/commands/ubuntu/change-default-php.sh new file mode 100755 index 0000000..e769d1f --- /dev/null +++ b/system/commands/ubuntu/change-default-php.sh @@ -0,0 +1,11 @@ +if ! sudo rm /usr/bin/php; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ln -s /usr/bin/php__version__ /usr/bin/php; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "Default php is: \n" + +php -v diff --git a/system/commands/ubuntu/create-user.sh b/system/commands/ubuntu/create-user.sh new file mode 100755 index 0000000..cf6a328 --- /dev/null +++ b/system/commands/ubuntu/create-user.sh @@ -0,0 +1,11 @@ +export DEBIAN_FRONTEND=noninteractive +echo "__key__" | sudo tee -a /home/root/.ssh/authorized_keys +sudo useradd -p $(openssl passwd -1 __password__) __user__ +sudo usermod -aG sudo __user__ +echo "__user__ ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers +sudo mkdir /home/__user__ +sudo mkdir /home/__user__/.ssh +echo "__key__" | sudo tee -a /home/__user__/.ssh/authorized_keys +sudo chown -R __user__:__user__ /home/__user__ +sudo chsh -s /bin/bash __user__ +sudo su - __user__ -c "ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa" <<< y diff --git a/system/commands/ubuntu/delete-ssh-key.sh b/system/commands/ubuntu/delete-ssh-key.sh new file mode 100644 index 0000000..e28ecf1 --- /dev/null +++ b/system/commands/ubuntu/delete-ssh-key.sh @@ -0,0 +1 @@ +sudo sed -i 's/__key__//g' ~/.ssh/authorized_keys diff --git a/system/commands/ubuntu/deploy-ssh-key.sh b/system/commands/ubuntu/deploy-ssh-key.sh new file mode 100644 index 0000000..6ea323a --- /dev/null +++ b/system/commands/ubuntu/deploy-ssh-key.sh @@ -0,0 +1,3 @@ +if ! echo '__key__' | sudo tee -a ~/.ssh/authorized_keys; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/get-php-ini.sh b/system/commands/ubuntu/get-php-ini.sh new file mode 100644 index 0000000..adfe1a5 --- /dev/null +++ b/system/commands/ubuntu/get-php-ini.sh @@ -0,0 +1 @@ +cat /etc/php/__version__/cli/php.ini diff --git a/system/commands/ubuntu/install-certbot.sh b/system/commands/ubuntu/install-certbot.sh new file mode 100755 index 0000000..2ddaa43 --- /dev/null +++ b/system/commands/ubuntu/install-certbot.sh @@ -0,0 +1 @@ +sudo DEBIAN_FRONTEND=noninteractive apt install certbot python3-certbot-nginx -y diff --git a/system/commands/ubuntu/install-mariadb.sh b/system/commands/ubuntu/install-mariadb.sh new file mode 100755 index 0000000..dd3bc49 --- /dev/null +++ b/system/commands/ubuntu/install-mariadb.sh @@ -0,0 +1,12 @@ +wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup + +chmod +x mariadb_repo_setup + +sudo DEBIAN_FRONTEND=noninteractive ./mariadb_repo_setup \ + --mariadb-server-version="mariadb-10.3" + +sudo DEBIAN_FRONTEND=noninteractive apt update + +sudo DEBIAN_FRONTEND=noninteractive apt install mariadb-server mariadb-backup -y + +sudo service mysql start diff --git a/system/commands/ubuntu/install-mysql-8.sh b/system/commands/ubuntu/install-mysql-8.sh new file mode 100755 index 0000000..9d8b822 --- /dev/null +++ b/system/commands/ubuntu/install-mysql-8.sh @@ -0,0 +1,19 @@ +wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb + +sudo DEBIAN_FRONTEND=noninteractive dpkg -i mysql-apt-config_0.8.22-1_all.deb + +sudo DEBIAN_FRONTEND=noninteractive apt update + +sudo DEBIAN_FRONTEND=noninteractive apt install mysql-server -y + +sudo service mysql enable + +sudo service mysql start + +if ! sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH auth_socket;"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo mysql -e "FLUSH PRIVILEGES"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/install-mysql.sh b/system/commands/ubuntu/install-mysql.sh new file mode 100755 index 0000000..9d1484c --- /dev/null +++ b/system/commands/ubuntu/install-mysql.sh @@ -0,0 +1,13 @@ +sudo DEBIAN_FRONTEND=noninteractive apt install mysql-server -y + +sudo service mysql enable + +sudo service mysql start + +if ! sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH auth_socket;"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo mysql -e "FLUSH PRIVILEGES"; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/install-nginx.sh b/system/commands/ubuntu/install-nginx.sh new file mode 100755 index 0000000..9908ab6 --- /dev/null +++ b/system/commands/ubuntu/install-nginx.sh @@ -0,0 +1,8 @@ +sudo DEBIAN_FRONTEND=noninteractive apt install nginx -y + +if ! echo '__config__' | sudo tee /etc/nginx/nginx.conf; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +sudo service nginx start + diff --git a/system/commands/ubuntu/install-nodejs.sh b/system/commands/ubuntu/install-nodejs.sh new file mode 100755 index 0000000..9a230da --- /dev/null +++ b/system/commands/ubuntu/install-nodejs.sh @@ -0,0 +1,5 @@ +curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -; + +sudo DEBIAN_FRONTEND=noninteractive apt update + +sudo DEBIAN_FRONTEND=noninteractive apt install nodejs -y diff --git a/system/commands/ubuntu/install-php-extension.sh b/system/commands/ubuntu/install-php-extension.sh new file mode 100644 index 0000000..bda498e --- /dev/null +++ b/system/commands/ubuntu/install-php-extension.sh @@ -0,0 +1,5 @@ +sudo apt install -y php__version__-__name__ + +sudo service php__version__-fpm restart + +php__version__ -m diff --git a/system/commands/ubuntu/install-php.sh b/system/commands/ubuntu/install-php.sh new file mode 100755 index 0000000..d18c1b5 --- /dev/null +++ b/system/commands/ubuntu/install-php.sh @@ -0,0 +1,13 @@ +sudo add-apt-repository ppa:ondrej/php -y + +sudo DEBIAN_FRONTEND=noninteractive apt update + +sudo DEBIAN_FRONTEND=noninteractive apt install -y php__version__ php__version__-fpm php__version__-mbstring php__version__-mysql php__version__-mcrypt php__version__-gd php__version__-xml php__version__-curl php__version__-gettext php__version__-zip php__version__-bcmath php__version__-soap php__version__-redis + +if ! sudo sed -i 's/www-data/__user__/g' /etc/php/__version__/fpm/pool.d/www.conf; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +sudo service php__version__-fpm enable + +sudo service php__version__-fpm start diff --git a/system/commands/ubuntu/install-redis.sh b/system/commands/ubuntu/install-redis.sh new file mode 100755 index 0000000..a6dbdbe --- /dev/null +++ b/system/commands/ubuntu/install-redis.sh @@ -0,0 +1,5 @@ +sudo DEBIAN_FRONTEND=noninteractive apt install redis-server -y + +sudo service redis enable + +sudo service redis start diff --git a/system/commands/ubuntu/install-requirements.sh b/system/commands/ubuntu/install-requirements.sh new file mode 100755 index 0000000..b71731f --- /dev/null +++ b/system/commands/ubuntu/install-requirements.sh @@ -0,0 +1,3 @@ +sudo DEBIAN_FRONTEND=noninteractive apt install -y software-properties-common curl zip unzip git gcc +git config --global user.email "__email__" +git config --global user.name "__name__" diff --git a/system/commands/ubuntu/install-supervisor.sh b/system/commands/ubuntu/install-supervisor.sh new file mode 100755 index 0000000..a3c0922 --- /dev/null +++ b/system/commands/ubuntu/install-supervisor.sh @@ -0,0 +1,5 @@ +sudo DEBIAN_FRONTEND=noninteractive apt-get install supervisor -y + +sudo service supervisor enable + +sudo service supervisor start diff --git a/system/commands/ubuntu/install-ufw.sh b/system/commands/ubuntu/install-ufw.sh new file mode 100755 index 0000000..a893f51 --- /dev/null +++ b/system/commands/ubuntu/install-ufw.sh @@ -0,0 +1,27 @@ +if ! sudo ufw default deny incoming; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw default allow outgoing; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw allow from 0.0.0.0/0 to any proto tcp port 22; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw allow from 0.0.0.0/0 to any proto tcp port 80; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw allow from 0.0.0.0/0 to any proto tcp port 443; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw --force enable; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ufw reload; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/process-manager/supervisor/create-worker.sh b/system/commands/ubuntu/process-manager/supervisor/create-worker.sh new file mode 100644 index 0000000..ea4c994 --- /dev/null +++ b/system/commands/ubuntu/process-manager/supervisor/create-worker.sh @@ -0,0 +1,21 @@ +mkdir -p ~/.logs + +mkdir -p ~/.logs/workers + +touch ~/.logs/workers/__id__.log + +if ! echo '__config__' | sudo tee /etc/supervisor/conf.d/__id__.conf; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo supervisorctl reread; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo supervisorctl update; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo supervisorctl start __id__:*; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/process-manager/supervisor/delete-worker.sh b/system/commands/ubuntu/process-manager/supervisor/delete-worker.sh new file mode 100644 index 0000000..13ace91 --- /dev/null +++ b/system/commands/ubuntu/process-manager/supervisor/delete-worker.sh @@ -0,0 +1,20 @@ +if ! sudo supervisorctl stop __id__:*; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo rm -rf ~/.logs/workers/__id__.log; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo rm -rf /etc/supervisor/conf.d/__id__.conf; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo supervisorctl reread; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo supervisorctl update; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + diff --git a/system/commands/ubuntu/process-manager/supervisor/restart-worker.sh b/system/commands/ubuntu/process-manager/supervisor/restart-worker.sh new file mode 100644 index 0000000..ad31160 --- /dev/null +++ b/system/commands/ubuntu/process-manager/supervisor/restart-worker.sh @@ -0,0 +1,3 @@ +if ! sudo supervisorctl restart __id__:*; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/process-manager/supervisor/start-worker.sh b/system/commands/ubuntu/process-manager/supervisor/start-worker.sh new file mode 100644 index 0000000..d4e6cbc --- /dev/null +++ b/system/commands/ubuntu/process-manager/supervisor/start-worker.sh @@ -0,0 +1,3 @@ +if ! sudo supervisorctl start __id__:*; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/process-manager/supervisor/stop-worker.sh b/system/commands/ubuntu/process-manager/supervisor/stop-worker.sh new file mode 100644 index 0000000..5fa8bfa --- /dev/null +++ b/system/commands/ubuntu/process-manager/supervisor/stop-worker.sh @@ -0,0 +1,3 @@ +if ! sudo supervisorctl stop __id__:*; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/reboot.sh b/system/commands/ubuntu/reboot.sh new file mode 100644 index 0000000..ed586e7 --- /dev/null +++ b/system/commands/ubuntu/reboot.sh @@ -0,0 +1,3 @@ +echo "Rebooting..." + +sudo reboot diff --git a/system/commands/ubuntu/restart-service.sh b/system/commands/ubuntu/restart-service.sh new file mode 100644 index 0000000..d54efec --- /dev/null +++ b/system/commands/ubuntu/restart-service.sh @@ -0,0 +1,3 @@ +sudo service __service__ restart + +sudo service __service__ status | cat diff --git a/system/commands/ubuntu/service-status.sh b/system/commands/ubuntu/service-status.sh new file mode 100755 index 0000000..fce6f4f --- /dev/null +++ b/system/commands/ubuntu/service-status.sh @@ -0,0 +1 @@ +sudo service __service__ status | cat diff --git a/system/commands/ubuntu/start-service.sh b/system/commands/ubuntu/start-service.sh new file mode 100644 index 0000000..e9d8531 --- /dev/null +++ b/system/commands/ubuntu/start-service.sh @@ -0,0 +1,3 @@ +sudo service __service__ start + +sudo service __service__ status | cat diff --git a/system/commands/ubuntu/stop-service.sh b/system/commands/ubuntu/stop-service.sh new file mode 100644 index 0000000..1b7db27 --- /dev/null +++ b/system/commands/ubuntu/stop-service.sh @@ -0,0 +1,3 @@ +sudo service __service__ stop + +sudo service __service__ status | cat diff --git a/system/commands/ubuntu/uninstall-php.sh b/system/commands/ubuntu/uninstall-php.sh new file mode 100755 index 0000000..750ebf6 --- /dev/null +++ b/system/commands/ubuntu/uninstall-php.sh @@ -0,0 +1,5 @@ +sudo service php__version__-fpm stop + +if ! sudo DEBIAN_FRONTEND=noninteractive apt remove -y php__version__ php__version__-fpm php__version__-mbstring php__version__-mysql php__version__-mcrypt php__version__-gd php__version__-xml php__version__-curl php__version__-gettext php__version__-zip php__version__-bcmath php__version__-soap php__version__-redis; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/update-php-ini.sh b/system/commands/ubuntu/update-php-ini.sh new file mode 100644 index 0000000..0d8fde6 --- /dev/null +++ b/system/commands/ubuntu/update-php-ini.sh @@ -0,0 +1,7 @@ +if ! sudo echo '__ini__' > /etc/php/__version__/cli/php.ini; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service php__version__-fpm restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/update-php-settings.sh b/system/commands/ubuntu/update-php-settings.sh new file mode 100644 index 0000000..5cb8585 --- /dev/null +++ b/system/commands/ubuntu/update-php-settings.sh @@ -0,0 +1,11 @@ +if ! sudo sed -i 's,^__variable__ =.*$,__variable__ = __value__,' /etc/php/__version__/cli/php.ini; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo sed -i 's,^__variable__ =.*$,__variable__ = __value__,' /etc/php/__version__/fpm/php.ini; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service php__version__-fpm restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/upgrade.sh b/system/commands/ubuntu/upgrade.sh new file mode 100755 index 0000000..8f30eb9 --- /dev/null +++ b/system/commands/ubuntu/upgrade.sh @@ -0,0 +1,7 @@ +sudo DEBIAN_FRONTEND=noninteractive apt clean + +sudo DEBIAN_FRONTEND=noninteractive apt update + +sudo DEBIAN_FRONTEND=noninteractive apt upgrade -y + +sudo DEBIAN_FRONTEND=noninteractive apt autoremove -y diff --git a/system/commands/ubuntu/webserver/nginx/change-php-version.sh b/system/commands/ubuntu/webserver/nginx/change-php-version.sh new file mode 100755 index 0000000..c5e0a91 --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/change-php-version.sh @@ -0,0 +1,9 @@ +if ! sudo sed -i 's/php__old_version__/php__new_version__/g' /etc/nginx/sites-available/__domain__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service nginx restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "PHP Version Changed to __new_version__" diff --git a/system/commands/ubuntu/webserver/nginx/create-phpmyadmin-vhost.sh b/system/commands/ubuntu/webserver/nginx/create-phpmyadmin-vhost.sh new file mode 100644 index 0000000..704d8ea --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/create-phpmyadmin-vhost.sh @@ -0,0 +1,17 @@ +if ! sudo chown -R 755 /home/vito/phpmyadmin; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! echo '__vhost__' | sudo tee /etc/nginx/sites-available/phpmyadmin; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ln -s /etc/nginx/sites-available/phpmyadmin /etc/nginx/sites-enabled/; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service nginx restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "PHPMyAdmin vhost created" diff --git a/system/commands/ubuntu/webserver/nginx/create-vhost.sh b/system/commands/ubuntu/webserver/nginx/create-vhost.sh new file mode 100755 index 0000000..d12630d --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/create-vhost.sh @@ -0,0 +1,27 @@ +if ! rm -rf __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! mkdir __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo chown -R 755 __path__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! echo '' | sudo tee /etc/nginx/conf.d/__domain___redirects; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! echo '__vhost__' | sudo tee /etc/nginx/sites-available/__domain__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo ln -s /etc/nginx/sites-available/__domain__ /etc/nginx/sites-enabled/; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service nginx restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/webserver/nginx/delete-phpmyadmin-vhost.sh b/system/commands/ubuntu/webserver/nginx/delete-phpmyadmin-vhost.sh new file mode 100644 index 0000000..21aa844 --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/delete-phpmyadmin-vhost.sh @@ -0,0 +1,11 @@ +sudo rm -rf __path__ + +sudo rm /etc/nginx/sites-available/phpmyadmin + +sudo rm /etc/nginx/sites-enabled/phpmyadmin + +if ! sudo service nginx restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +echo "PHPMyAdmin deleted" diff --git a/system/commands/ubuntu/webserver/nginx/delete-site.sh b/system/commands/ubuntu/webserver/nginx/delete-site.sh new file mode 100755 index 0000000..51adfbf --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/delete-site.sh @@ -0,0 +1,7 @@ +rm -rf __path__ + +sudo rm /etc/nginx/sites-available/__domain__ + +sudo rm /etc/nginx/sites-enabled/__domain__ + +echo "Site deleted" diff --git a/system/commands/ubuntu/webserver/nginx/update-redirects.sh b/system/commands/ubuntu/webserver/nginx/update-redirects.sh new file mode 100644 index 0000000..9b5d66a --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/update-redirects.sh @@ -0,0 +1,7 @@ +if ! echo '__redirects__' | sudo tee /etc/nginx/conf.d/__domain___redirects; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service nginx restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/system/commands/ubuntu/webserver/nginx/update-vhost.sh b/system/commands/ubuntu/webserver/nginx/update-vhost.sh new file mode 100755 index 0000000..97ce3e0 --- /dev/null +++ b/system/commands/ubuntu/webserver/nginx/update-vhost.sh @@ -0,0 +1,7 @@ +if ! echo '__vhost__' | sudo tee /etc/nginx/sites-available/__domain__; then + echo 'VITO_SSH_ERROR' && exit 1 +fi + +if ! sudo service nginx restart; then + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..67db259 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,27 @@ +const defaultTheme = require('tailwindcss/defaultTheme'); +const colors = require("tailwindcss/colors"); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php', + './storage/framework/views/*.php', + './resources/views/**/*.blade.php', + './resources/js/**/*.vue', + ], + + theme: { + extend: { + fontFamily: { + sans: ['Figtree', ...defaultTheme.fontFamily.sans], + }, + + colors: { + gray: colors.slate, + primary: colors.indigo + }, + }, + }, + + plugins: [require('@tailwindcss/forms')], +}; diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php new file mode 100644 index 0000000..cc68301 --- /dev/null +++ b/tests/CreatesApplication.php @@ -0,0 +1,21 @@ +make(Kernel::class)->bootstrap(); + + return $app; + } +} diff --git a/tests/Feature/Http/ApplicationTest.php b/tests/Feature/Http/ApplicationTest.php new file mode 100644 index 0000000..7ca36a3 --- /dev/null +++ b/tests/Feature/Http/ApplicationTest.php @@ -0,0 +1,69 @@ +actingAs($this->user); + + $this->get( + route('servers.sites.application', [ + 'server' => $this->server, + 'site' => $this->site + ]) + ) + ->assertOk() + ->assertSeeLivewire(LaravelApp::class); + } + + public function test_update_deployment_script() + { + $this->actingAs($this->user); + + Livewire::test(Deploy::class, ['site' => $this->site]) + ->assertDontSeeText('Deploy'); + + Livewire::test(DeploymentScript::class, ['site' => $this->site]) + ->set('script', 'some script') + ->call('save') + ->assertSuccessful(); + + $this->assertDatabaseHas('deployment_scripts', [ + 'site_id' => $this->site->id, + 'content' => 'some script' + ]); + + $this->site->refresh(); + + Livewire::test(Deploy::class, ['site' => $this->site]) + ->assertSeeText('Deploy'); + } + + public function test_change_branch() + { + Bus::fake(); + + $this->actingAs($this->user); + + Livewire::test(ChangeBranch::class, ['site' => $this->site]) + ->set('branch', 'master') + ->call('change') + ->assertSuccessful(); + + Bus::assertDispatched(UpdateBranch::class); + } +} diff --git a/tests/Feature/Http/Auth/AuthenticationTest.php b/tests/Feature/Http/Auth/AuthenticationTest.php new file mode 100644 index 0000000..502f0b8 --- /dev/null +++ b/tests/Feature/Http/Auth/AuthenticationTest.php @@ -0,0 +1,40 @@ +get('/login'); + + $response->assertStatus(200); + } + + public function test_users_can_authenticate_using_the_login_screen(): void + { + $response = $this->post('/login', [ + 'email' => $this->user->email, + 'password' => 'password', + ]); + + $this->assertAuthenticated(); + $response->assertRedirect(RouteServiceProvider::HOME); + } + + public function test_users_can_not_authenticate_with_invalid_password(): void + { + $this->post('/login', [ + 'email' => $this->user->email, + 'password' => 'wrong-password', + ]); + + $this->assertGuest(); + } +} diff --git a/tests/Feature/Http/Auth/PasswordConfirmationTest.php b/tests/Feature/Http/Auth/PasswordConfirmationTest.php new file mode 100644 index 0000000..13e41a3 --- /dev/null +++ b/tests/Feature/Http/Auth/PasswordConfirmationTest.php @@ -0,0 +1,47 @@ +actingAs($this->user); + + $response = $this->get('/confirm-password'); + + $response->assertStatus(200); + } + + /** + * @throws JsonException + */ + public function test_password_can_be_confirmed(): void + { + $this->actingAs($this->user); + + $response = $this->post('/confirm-password', [ + 'password' => 'password', + ]); + + $response->assertRedirect(); + $response->assertSessionHasNoErrors(); + } + + public function test_password_is_not_confirmed_with_invalid_password(): void + { + $this->actingAs($this->user); + + $response = $this->post('/confirm-password', [ + 'password' => 'wrong-password', + ]); + + $response->assertSessionHasErrors(); + } +} diff --git a/tests/Feature/Http/Auth/PasswordResetTest.php b/tests/Feature/Http/Auth/PasswordResetTest.php new file mode 100644 index 0000000..b0a649a --- /dev/null +++ b/tests/Feature/Http/Auth/PasswordResetTest.php @@ -0,0 +1,64 @@ +get('/forgot-password'); + + $response->assertStatus(200); + } + + public function test_reset_password_link_can_be_requested(): void + { + Notification::fake(); + + $this->post('/forgot-password', ['email' => $this->user->email]); + + Notification::assertSentTo($this->user, ResetPassword::class); + } + + public function test_reset_password_screen_can_be_rendered(): void + { + Notification::fake(); + + $this->post('/forgot-password', ['email' => $this->user->email]); + + Notification::assertSentTo($this->user, ResetPassword::class, function ($notification) { + $response = $this->get('/reset-password/'.$notification->token); + + $response->assertStatus(200); + + return true; + }); + } + + public function test_password_can_be_reset_with_valid_token(): void + { + Notification::fake(); + + $this->post('/forgot-password', ['email' => $this->user->email]); + + Notification::assertSentTo($this->user, ResetPassword::class, function ($notification) { + $response = $this->post('/reset-password', [ + 'token' => $notification->token, + 'email' => $this->user->email, + 'password' => 'password', + 'password_confirmation' => 'password', + ]); + + $response->assertSessionHasNoErrors(); + + return true; + }); + } +} diff --git a/tests/Feature/Http/Auth/PasswordUpdateTest.php b/tests/Feature/Http/Auth/PasswordUpdateTest.php new file mode 100644 index 0000000..40eb528 --- /dev/null +++ b/tests/Feature/Http/Auth/PasswordUpdateTest.php @@ -0,0 +1,40 @@ +actingAs($this->user); + + Livewire::test(UpdatePassword::class) + ->set('current_password', 'password') + ->set('password', 'new-password') + ->set('password_confirmation', 'new-password') + ->call('update') + ->assertSuccessful(); + + $this->assertTrue(Hash::check('new-password', $this->user->refresh()->password)); + } + + public function test_correct_password_must_be_provided_to_update_password(): void + { + $this->actingAs($this->user); + + Livewire::test(UpdatePassword::class) + ->set('current_password', 'wrong-password') + ->set('password', 'new-password') + ->set('password_confirmation', 'new-password') + ->call('update') + ->assertHasErrors(); + } +} diff --git a/tests/Feature/Http/CronjobTest.php b/tests/Feature/Http/CronjobTest.php new file mode 100644 index 0000000..38c5824 --- /dev/null +++ b/tests/Feature/Http/CronjobTest.php @@ -0,0 +1,64 @@ +actingAs($this->user); + + /** @var CronJob $cronjob */ + $cronjob = CronJob::factory()->create([ + 'server_id' => $this->server->id, + ]); + + Livewire::test(CronjobsList::class, ['server' => $this->server]) + ->assertSeeText($cronjob->frequency_label); + } + + public function test_delete_cronjob() + { + $this->actingAs($this->user); + + /** @var CronJob $cronjob */ + $cronjob = CronJob::factory()->create([ + 'server_id' => $this->server->id, + ]); + + Livewire::test(CronjobsList::class, ['server' => $this->server]) + ->set('deleteId', $cronjob->id) + ->call('delete') + ->assertDispatchedBrowserEvent('confirmed', true); + } + + public function test_create_cronjob() + { + $this->actingAs($this->user); + + Livewire::test(CreateCronjob::class, ['server' => $this->server]) + ->set('command', 'ls -la') + ->set('user', 'vito') + ->set('frequency', '* * * * *') + ->call('create') + ->assertDispatchedBrowserEvent('created', true); + + $this->assertDatabaseHas('cron_jobs', [ + 'server_id' => $this->server->id, + 'command' => 'ls -la', + 'user' => 'vito', + 'frequency' => '* * * * *', + 'status' => CronjobStatus::CREATING + ]); + } +} diff --git a/tests/Feature/Http/DatabaseTest.php b/tests/Feature/Http/DatabaseTest.php new file mode 100644 index 0000000..7ed9bd7 --- /dev/null +++ b/tests/Feature/Http/DatabaseTest.php @@ -0,0 +1,76 @@ +actingAs($this->user); + + Bus::fake(); + + SSH::fake()->outputShouldBe('test'); + + Livewire::test(DatabaseList::class, ['server' => $this->server]) + ->set('name', 'database') + ->call('create') + ->assertSuccessful(); + + Bus::assertDispatched(CreateOnServer::class); + + $this->assertDatabaseHas('databases', [ + 'name' => 'database', + 'status' => DatabaseStatus::CREATING, + ]); + } + + public function test_see_databases_list(): void + { + $this->actingAs($this->user); + + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + Livewire::test(DatabaseList::class, ['server' => $this->server]) + ->assertSee([ + $database->name, + ]); + } + + public function test_delete_database(): void + { + $this->actingAs($this->user); + + Bus::fake(); + + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + Livewire::test(DatabaseList::class, ['server' => $this->server]) + ->set('deleteId', $database->id) + ->call('delete'); + + $this->assertDatabaseHas('databases', [ + 'id' => $database->id, + 'status' => DatabaseStatus::DELETING, + ]); + + Bus::assertDispatched(DeleteFromServer::class); + } +} diff --git a/tests/Feature/Http/DatabaseUserTest.php b/tests/Feature/Http/DatabaseUserTest.php new file mode 100644 index 0000000..5c30ead --- /dev/null +++ b/tests/Feature/Http/DatabaseUserTest.php @@ -0,0 +1,74 @@ +actingAs($this->user); + + Bus::fake(); + + Livewire::test(DatabaseUserList::class, ['server' => $this->server]) + ->set('username', 'user') + ->set('password', 'password') + ->call('create') + ->assertSuccessful(); + + Bus::assertDispatched(CreateOnServer::class); + + $this->assertDatabaseHas('database_users', [ + 'username' => 'user', + 'status' => DatabaseUserStatus::CREATING, + ]); + } + + public function test_see_database_users_list(): void + { + $this->actingAs($this->user); + + $databaseUser = DatabaseUser::factory()->create([ + 'server_id' => $this->server, + ]); + + Livewire::test(DatabaseUserList::class, ['server' => $this->server]) + ->assertSee([ + $databaseUser->username, + ]); + } + + public function test_delete_database_user(): void + { + $this->actingAs($this->user); + + Bus::fake(); + + $databaseUser = DatabaseUser::factory()->create([ + 'server_id' => $this->server, + ]); + + Livewire::test(DatabaseUserList::class, ['server' => $this->server]) + ->set('deleteId', $databaseUser->id) + ->call('delete'); + + $this->assertDatabaseHas('database_users', [ + 'id' => $databaseUser->id, + 'status' => DatabaseUserStatus::DELETING, + ]); + + Bus::assertDispatched(DeleteFromServer::class); + } +} diff --git a/tests/Feature/Http/FirewallTest.php b/tests/Feature/Http/FirewallTest.php new file mode 100644 index 0000000..bd1eb36 --- /dev/null +++ b/tests/Feature/Http/FirewallTest.php @@ -0,0 +1,79 @@ +actingAs($this->user); + + Livewire::test(CreateFirewallRule::class, ['server' => $this->server]) + ->set('type', 'allow') + ->set('protocol', 'tcp') + ->set('port', '1234') + ->set('source', '0.0.0.0') + ->set('mask', '0') + ->call('create') + ->assertSuccessful(); + + Bus::assertDispatched(AddToServer::class); + + $this->assertDatabaseHas('firewall_rules', [ + 'port' => '1234' + ]); + } + + public function test_see_firewall_rules(): void + { + $this->actingAs($this->user); + + $rule = FirewallRule::factory()->create([ + 'server_id' => $this->server->id + ]); + + Livewire::test(FirewallRulesList::class, ['server' => $this->server]) + ->assertSee([ + $rule->source, + $rule->port, + ]); + } + + public function test_delete_firewall_rule(): void + { + Bus::fake(); + + $this->actingAs($this->user); + + $rule = FirewallRule::factory()->create([ + 'server_id' => $this->server->id + ]); + + Livewire::test(FirewallRulesList::class, ['server' => $this->server]) + ->set('deleteId', $rule->id) + ->call('delete') + ->assertSuccessful(); + + Bus::assertDispatched(RemoveFromServer::class); + + $this->assertDatabaseHas('firewall_rules', [ + 'id' => $rule->id, + 'status' => FirewallRuleStatus::DELETING + ]); + } +} diff --git a/tests/Feature/Http/LogsTest.php b/tests/Feature/Http/LogsTest.php new file mode 100644 index 0000000..be01d41 --- /dev/null +++ b/tests/Feature/Http/LogsTest.php @@ -0,0 +1,30 @@ +actingAs($this->user); + + /** @var ServerLog $log */ + $log = ServerLog::factory()->create([ + 'server_id' => $this->server->id, + ]); + + $this->get(route('servers.logs', $this->server)) + ->assertOk(); + + Livewire::test(LogsList::class, ['server' => $this->server]) + ->assertSeeText($log->type); + } +} diff --git a/tests/Feature/Http/NotificationChannelsTest.php b/tests/Feature/Http/NotificationChannelsTest.php new file mode 100644 index 0000000..1ad05ad --- /dev/null +++ b/tests/Feature/Http/NotificationChannelsTest.php @@ -0,0 +1,85 @@ +actingAs($this->user); + + Livewire::test(AddChannel::class) + ->set('provider', NotificationChannel::EMAIL) + ->set('email', 'email@example.com') + ->call('add') + ->assertSuccessful(); + } + + public function test_add_slack_channel(): void + { + $this->actingAs($this->user); + + Http::fake(); + + Livewire::test(AddChannel::class) + ->set('provider', NotificationChannel::SLACK) + ->set('label', 'Slack') + ->set('webhook_url', $this->faker->url) + ->call('add') + ->assertSuccessful(); + } + + public function test_add_discord_channel(): void + { + $this->actingAs($this->user); + + Http::fake(); + + Livewire::test(AddChannel::class) + ->set('provider', NotificationChannel::DISCORD) + ->set('label', 'Slack') + ->set('webhook_url', $this->faker->url) + ->call('add') + ->assertSuccessful(); + } + + public function test_see_channels_list(): void + { + $this->actingAs($this->user); + + $channel = \App\Models\NotificationChannel::factory()->create(); + + Livewire::test(ChannelsList::class) + ->assertSee([ + $channel->provider, + ]); + } + + public function test_delete_channel(): void + { + $this->actingAs($this->user); + + $channel = \App\Models\NotificationChannel::factory()->create(); + + Livewire::test(ChannelsList::class) + ->set('deleteId', $channel->id) + ->call('delete') + ->assertSuccessful(); + + $this->assertDatabaseMissing('notification_channels', [ + 'id' => $channel->id, + ]); + } +} diff --git a/tests/Feature/Http/PHP.php b/tests/Feature/Http/PHP.php new file mode 100644 index 0000000..baa18a6 --- /dev/null +++ b/tests/Feature/Http/PHP.php @@ -0,0 +1,71 @@ +actingAs($this->user); + + Livewire::test(InstalledVersions::class, ['server' => $this->server]) + ->call('install', '8.1') + ->assertSuccessful(); + + Bus::assertDispatched(InstallPHP::class); + } + + public function test_uninstall_new_php(): void + { + Bus::fake(); + + $this->actingAs($this->user); + + Livewire::test(InstalledVersions::class, ['server' => $this->server]) + ->set('uninstallId', $this->server->php('8.2')?->id) + ->call('uninstall') + ->assertSuccessful(); + + Bus::assertDispatched(UninstallPHP::class); + } + + public function test_change_default_php_cli(): void + { + Bus::fake(); + + $this->actingAs($this->user); + + Service::factory()->create([ + 'server_id' => $this->server->id, + 'type' => 'php', + 'type_data' => [ + 'extensions' => [], + ], + 'name' => 'php', + 'version' => '8.1', + 'status' => ServiceStatus::READY + ]); + + Livewire::test(DefaultCli::class, ['server' => $this->server]) + ->call('change', '8.1') + ->assertSuccessful(); + + Bus::assertDispatched(SetDefaultCli::class); + } +} diff --git a/tests/Feature/Http/ProfileTest.php b/tests/Feature/Http/ProfileTest.php new file mode 100644 index 0000000..70ef2d9 --- /dev/null +++ b/tests/Feature/Http/ProfileTest.php @@ -0,0 +1,40 @@ +actingAs($this->user); + + $this + ->get(route('profile')) + ->assertSeeLivewire(UpdateProfileInformation::class) + ->assertSeeLivewire(UpdatePassword::class); + } + + public function test_profile_information_can_be_updated(): void + { + $this->actingAs($this->user); + + Livewire::test(UpdateProfileInformation::class) + ->set('name', 'Test') + ->set('email', 'test@example.com') + ->call('submit') + ->assertSuccessful(); + + $this->user->refresh(); + + $this->assertSame('Test', $this->user->name); + $this->assertSame('test@example.com', $this->user->email); + } +} diff --git a/tests/Feature/Http/QueuesTest.php b/tests/Feature/Http/QueuesTest.php new file mode 100644 index 0000000..a2b41d4 --- /dev/null +++ b/tests/Feature/Http/QueuesTest.php @@ -0,0 +1,69 @@ +actingAs($this->user); + + $queue = Queue::factory()->create([ + 'server_id' => $this->server->id, + 'site_id' => $this->site->id, + ]); + + Livewire::test(QueuesList::class, ['site' => $this->site]) + ->assertSeeText($queue->command); + } + + public function test_delete_queue() + { + $this->actingAs($this->user); + + $queue = Queue::factory()->create([ + 'server_id' => $this->server->id, + 'site_id' => $this->site->id, + ]); + + Livewire::test(QueuesList::class, ['site' => $this->site]) + ->set('deleteId', $queue->id) + ->call('delete') + ->assertDispatchedBrowserEvent('confirmed', true); + } + + public function test_create_queue() + { + $this->actingAs($this->user); + + Livewire::test(CreateQueue::class, ['site' => $this->site]) + ->set('command', 'php artisan queue:work') + ->set('user', 'vito') + ->set('auto_start', 1) + ->set('auto_restart', 1) + ->set('numprocs', 1) + ->call('create') + ->assertDispatchedBrowserEvent('created', true); + + $this->assertDatabaseHas('queues', [ + 'server_id' => $this->server->id, + 'site_id' => $this->site->id, + 'command' => 'php artisan queue:work', + 'user' => 'vito', + 'auto_start' => 1, + 'auto_restart' => 1, + 'numprocs' => 1, + 'status' => QueueStatus::CREATING + ]); + } +} diff --git a/tests/Feature/Http/ServerKeysTest.php b/tests/Feature/Http/ServerKeysTest.php new file mode 100644 index 0000000..bdef927 --- /dev/null +++ b/tests/Feature/Http/ServerKeysTest.php @@ -0,0 +1,111 @@ +actingAs($this->user); + + $sshKey = SshKey::factory()->create([ + 'user_id' => $this->user->id, + 'name' => 'My first key', + 'public_key' => 'public-key-content', + ]); + + $this->server->sshKeys()->attach($sshKey); + + Livewire::test(ServerKeysList::class, ['server' => $this->server]) + ->assertSeeText('My first key'); + } + + public function test_delete_ssh_key() + { + Bus::fake(); + + $this->actingAs($this->user); + + $sshKey = SshKey::factory()->create([ + 'user_id' => $this->user->id, + 'name' => 'My first key', + 'public_key' => 'public-key-content', + ]); + + $this->server->sshKeys()->attach($sshKey); + + Livewire::test(ServerKeysList::class, ['server' => $this->server]) + ->set('deleteId', $sshKey->id) + ->call('delete') + ->assertDispatchedBrowserEvent('confirmed'); + + $this->assertDatabaseHas('server_ssh_keys', [ + 'server_id' => $this->server->id, + 'ssh_key_id' => $sshKey->id, + 'status' => SshKeyStatus::DELETING + ]); + + Bus::assertDispatched(DeleteSshKeyFromServer::class); + } + + public function test_add_new_ssh_key() + { + Bus::fake(); + + $this->actingAs($this->user); + + Livewire::test(AddNewKey::class, ['server' => $this->server]) + ->set('name', 'My first key') + ->set('public_key', 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3CCnyBbpCgOJ0AWUSfBZ+mYAsYzcQDegPkBx1kyE0bXT1yX4+6uYx1Jh6NxWgLyaU0BaP4nsClrK1u5FojQHd8J7ycc0N3H8B+v2NPzj1Q6bFnl40saastONVm+d4edbCg9BowGAafLcf9ALsognqqOWQbK/QOpAhg25IAe47eiY3IjDGMHlsvaZkMtkDhT4t1mK8ZLjxw5vjyVYgINJefR981bIxMFrXy+0xBCsYOZxMIoAJsgCkrAGlI4kQHKv0SQVccSyTE1eziIZa5b3QUlXj8ogxMfK/EOD7Aoqinw652k4S5CwFs/LLmjWcFqCKDM6CSggWpB78DZ729O6zFvQS9V99/9SsSV7Qc5ML7B0DKzJ/tbHkaAE8xdZnQnZFVUegUMtUmjvngMaGlYsxkAZrUKsFRoh7xfXVkDyRBaBSslRNe8LFsXw9f7Q+3jdZ5vhGhmp+TBXTlgxApwR023411+ABE9y0doCx8illya3m2olEiiMZkRclgqsWFSk=') + ->call('add') + ->assertSuccessful() + ->assertDispatchedBrowserEvent('added'); + + $this->assertDatabaseHas('server_ssh_keys', [ + 'server_id' => $this->server->id, + 'status' => SshKeyStatus::ADDING + ]); + + Bus::assertDispatched(DeploySshKeyToServer::class); + } + + public function test_add_existing_key() + { + Bus::fake(); + + $this->actingAs($this->user); + + $sshKey = SshKey::factory()->create([ + 'user_id' => $this->user->id, + 'name' => 'My first key', + 'public_key' => 'public-key-content', + ]); + + Livewire::test(AddExistingKey::class, ['server' => $this->server]) + ->set('key_id', $sshKey->id) + ->call('add') + ->assertSuccessful() + ->assertDispatchedBrowserEvent('added'); + + $this->assertDatabaseHas('server_ssh_keys', [ + 'server_id' => $this->server->id, + 'status' => SshKeyStatus::ADDING + ]); + + Bus::assertDispatched(DeploySshKeyToServer::class); + } +} diff --git a/tests/Feature/Http/ServerProvidersTest.php b/tests/Feature/Http/ServerProvidersTest.php new file mode 100644 index 0000000..ce1382c --- /dev/null +++ b/tests/Feature/Http/ServerProvidersTest.php @@ -0,0 +1,67 @@ +actingAs($this->user); + + Http::fake(); + + Livewire::test(ConnectProvider::class) + ->set('provider', ServerProvider::HETZNER) + ->set('name', 'profile') + ->set('token', 'token') + ->call('connect') + ->assertSuccessful(); + + $this->assertDatabaseHas('server_providers', [ + 'provider' => ServerProvider::HETZNER, + 'profile' => 'profile', + ]); + } + + public function test_see_providers_list(): void + { + $this->actingAs($this->user); + + $provider = \App\Models\ServerProvider::factory()->create([ + 'user_id' => $this->user->id, + ]); + + Livewire::test(ProvidersList::class) + ->assertSee([ + $provider->profile, + ]); + } + + public function test_delete_provider(): void + { + $this->actingAs($this->user); + + $provider = \App\Models\ServerProvider::factory()->create([ + 'user_id' => $this->user->id, + ]); + + Livewire::test(ProvidersList::class) + ->set('deleteId', $provider->id) + ->call('delete') + ->assertSuccessful(); + + $this->assertDatabaseMissing('server_providers', [ + 'id' => $provider->id, + ]); + } +} diff --git a/tests/Feature/Http/ServerTest.php b/tests/Feature/Http/ServerTest.php new file mode 100644 index 0000000..03467ca --- /dev/null +++ b/tests/Feature/Http/ServerTest.php @@ -0,0 +1,47 @@ +actingAs($this->user); + + Bus::fake(); + + Livewire::test(CreateServer::class) + ->set('provider', ServerProvider::CUSTOM) + ->set('name', 'test') + ->set('ip', '1.1.1.1') + ->set('port', '22') + ->set('os', OperatingSystem::UBUNTU22) + ->set('webserver', Webserver::NGINX) + ->set('database', Database::MYSQL80) + ->set('php', '8.2') + ->call('submit') + ->assertSuccessful(); + + $this->assertDatabaseHas('servers', [ + 'name' => 'test', + 'ip' => '1.1.1.1', + 'status' => ServerStatus::INSTALLING, + ]); + + Bus::assertDispatched(Initialize::class); + } +} diff --git a/tests/Feature/Http/ServicesTest.php b/tests/Feature/Http/ServicesTest.php new file mode 100644 index 0000000..d1249ae --- /dev/null +++ b/tests/Feature/Http/ServicesTest.php @@ -0,0 +1,94 @@ +actingAs($this->user); + + Livewire::test(ServicesList::class, ['server' => $this->server]) + ->assertSee([ + 'nginx', + 'php', + 'supervisor', + 'redis', + 'ufw', + 'php' + ]); + } + + /** + * @dataProvider data + */ + public function test_restart_service(string $name): void + { + $service = $this->server->services()->where('name', $name)->first(); + + Bus::fake(); + + Livewire::test(ServicesList::class, ['server' => $this->server]) + ->call('restart', $service->id) + ->assertSuccessful(); + + Bus::assertDispatched(Manage::class); + } + + /** + * @dataProvider data + */ + public function test_stop_service(string $name): void + { + $service = $this->server->services()->where('name', $name)->first(); + + Bus::fake(); + + Livewire::test(ServicesList::class, ['server' => $this->server]) + ->call('stop', $service->id) + ->assertSuccessful(); + + Bus::assertDispatched(Manage::class); + } + + /** + * @dataProvider data + */ + public function test_start_service(string $name): void + { + $service = $this->server->services()->where('name', $name)->first(); + + $service->status = ServiceStatus::STOPPED; + $service->save(); + + Bus::fake(); + + Livewire::test(ServicesList::class, ['server' => $this->server]) + ->call('start', $service->id) + ->assertSuccessful(); + + Bus::assertDispatched(Manage::class); + } + + public static function data(): array + { + return [ + ['nginx'], + ['php'], + ['supervisor'], + ['redis'], + ['ufw'], + ['php'], + ]; + } +} diff --git a/tests/Feature/Http/SitesTest.php b/tests/Feature/Http/SitesTest.php new file mode 100644 index 0000000..9a93ab0 --- /dev/null +++ b/tests/Feature/Http/SitesTest.php @@ -0,0 +1,111 @@ +actingAs($this->user); + + \App\Models\SourceControl::factory()->create([ + 'provider' => SourceControl::GITHUB, + ]); + + Livewire::test(CreateSite::class, ['server' => $this->server]) + ->set('type', SiteType::LARAVEL) + ->set('domain', 'example.com') + ->set('alias', 'www.example.com') + ->set('php_version', '8.2') + ->set('web_directory', 'public') + ->set('source_control', SourceControl::GITHUB) + ->set('repository', 'test/test') + ->set('branch', 'main') + ->set('composer', true) + ->call('create') + ->assertSuccessful() + ->assertHasNoErrors(); + + Bus::assertDispatched(CreateVHost::class); + + $this->assertDatabaseHas('sites', [ + 'domain' => 'example.com', + 'status' => SiteStatus::INSTALLING, + ]); + } + + public function test_see_sites_list(): void + { + $this->actingAs($this->user); + + $site = Site::factory()->create([ + 'server_id' => $this->server->id, + ]); + + Livewire::test(SitesList::class, ['server' => $this->server]) + ->assertSee([ + $site->domain, + ]); + } + + public function test_delete_site(): void + { + Bus::fake(); + + $this->actingAs($this->user); + + $site = Site::factory()->create([ + 'server_id' => $this->server->id, + ]); + + Livewire::test(DeleteSite::class, ['server' => $this->server]) + ->set('site', $site) + ->call('delete') + ->assertSuccessful(); + + Bus::assertDispatched(\App\Jobs\Site\DeleteSite::class); + + $site->refresh(); + + $this->assertEquals(SiteStatus::DELETING, $site->status); + } + + public function test_change_php_version(): void + { + Bus::fake(); + + $this->actingAs($this->user); + + $site = Site::factory()->create([ + 'server_id' => $this->server->id, + ]); + + Livewire::test(ChangePhpVersion::class, ['site' => $site]) + ->set('version', '8.1') + ->call('change') + ->assertSuccessful(); + + Bus::assertDispatched(\App\Jobs\Site\ChangePHPVersion::class); + } +} diff --git a/tests/Feature/Http/SourceControlsTest.php b/tests/Feature/Http/SourceControlsTest.php new file mode 100644 index 0000000..593056c --- /dev/null +++ b/tests/Feature/Http/SourceControlsTest.php @@ -0,0 +1,66 @@ +actingAs($this->user); + + Http::fake(); + + Livewire::test($component) + ->set('token', 'token') + ->call('connect') + ->assertSuccessful(); + + $this->assertDatabaseHas('source_controls', [ + 'provider' => $provider, + ]); + } + + /** + * @dataProvider data + */ + public function test_delete_provider(string $provider, string $component): void + { + $this->actingAs($this->user); + + SourceControl::factory()->create([ + 'provider' => $provider, + ]); + + Livewire::test($component) + ->set('token', '') + ->call('connect') + ->assertSuccessful(); + + $this->assertDatabaseMissing('source_controls', [ + 'provider' => $provider, + ]); + } + + public static function data(): array + { + return [ + ['github', Github::class], + ['gitlab', Gitlab::class], + ['bitbucket', Bitbucket::class], + ]; + } +} diff --git a/tests/Feature/Http/SshKeysTest.php b/tests/Feature/Http/SshKeysTest.php new file mode 100644 index 0000000..19765ca --- /dev/null +++ b/tests/Feature/Http/SshKeysTest.php @@ -0,0 +1,61 @@ +actingAs($this->user); + + Livewire::test(AddKey::class) + ->set('name', 'test') + ->set( + 'public_key', + 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q== test@test.local' + ) + ->call('add') + ->assertSuccessful(); + } + + public function test_get_public_keys_list(): void + { + $this->actingAs($this->user); + + $key = SshKey::factory()->create([ + 'user_id' => $this->user->id, + ]); + + Livewire::test(KeysList::class) + ->assertSee([ + $key->name, + ]); + } + + public function test_delete_key(): void + { + $this->actingAs($this->user); + + $key = SshKey::factory()->create([ + 'user_id' => $this->user->id, + ]); + + Livewire::test(KeysList::class) + ->set('deleteId', $key->id) + ->call('delete') + ->assertSuccessful(); + + $this->assertDatabaseMissing('ssh_keys', [ + 'id' => $key->id, + ]); + } +} diff --git a/tests/Feature/Http/SslTest.php b/tests/Feature/Http/SslTest.php new file mode 100644 index 0000000..ea1a49e --- /dev/null +++ b/tests/Feature/Http/SslTest.php @@ -0,0 +1,83 @@ +actingAs($this->user); + + $ssl = Ssl::factory()->create([ + 'site_id' => $this->site->id, + ]); + + Livewire::test(SslsList::class, ['site' => $this->site]) + ->assertSeeText($ssl->type); + } + + public function test_see_ssls_list_with_no_ssls() + { + $this->actingAs($this->user); + + Livewire::test(SslsList::class, ['site' => $this->site]) + ->assertSeeText(__("You don't have any SSL certificates yet!")); + } + + public function test_create_ssl() + { + Bus::fake(); + + $this->actingAs($this->user); + + Livewire::test(CreateSsl::class, ['site' => $this->site]) + ->set('type', SslType::LETSENCRYPT) + ->call('create') + ->assertDispatchedBrowserEvent('created'); + + $this->assertDatabaseHas('ssls', [ + 'site_id' => $this->site->id, + 'type' => SslType::LETSENCRYPT, + 'status' => SslStatus::CREATING, + ]); + + Bus::assertDispatched(Deploy::class); + } + + public function test_delete_ssl() + { + Bus::fake(); + + $this->actingAs($this->user); + + $ssl = Ssl::factory()->create([ + 'site_id' => $this->site->id, + ]); + + Livewire::test(SslsList::class, ['site' => $this->site]) + ->set('deleteId', $ssl->id) + ->call('delete') + ->assertDispatchedBrowserEvent('confirmed'); + + $this->assertDatabaseHas('ssls', [ + 'id' => $ssl->id, + 'status' => SslStatus::DELETING, + ]); + + Bus::assertDispatched(Remove::class); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..2faec5f --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,72 @@ +user = User::factory()->create(); + + $this->setupServer(); + + $this->setupSite(); + + $this->setupKeys(); + } + + private function setupServer(): void + { + $this->server = Server::factory()->create([ + 'user_id' => $this->user->id, + ]); + + $this->server->type()->createServices([ + 'webserver' => Webserver::NGINX, + 'database' => Database::MYSQL80, + 'php' => '8.2', + ]); + + $this->server->services()->update([ + 'status' => ServiceStatus::READY, + ]); + } + + private function setupSite(): void + { + $this->site = Site::factory()->create([ + 'server_id' => $this->server->id, + ]); + } + + private function setupKeys(): void + { + config()->set('core.ssh_public_key_name', 'ssh-public.key'); + config()->set('core.ssh_private_key_name', 'ssh-private.pem'); + if (! File::exists(storage_path(config('core.ssh_public_key_name')))) { + File::put(storage_path(config('core.ssh_public_key_name')), 'public_key'); + } + if (! File::exists(storage_path(config('core.ssh_private_key_name')))) { + File::put(storage_path(config('core.ssh_private_key_name')), 'private_key'); + } + } +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..89f26f5 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,14 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; + +export default defineConfig({ + plugins: [ + laravel({ + input: [ + 'resources/css/app.css', + 'resources/js/app.js', + ], + refresh: true, + }), + ], +});