From 3c25084ada6ceb93945b531504ad7402e1fab031 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:31:34 +0200
Subject: [PATCH 001/514] =?UTF-8?q?chore:=20=F0=9F=93=8C=20Updated=20deps?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 composer.lock | 1079 +++++++++++++++++++++++++------------------------
 1 file changed, 544 insertions(+), 535 deletions(-)

diff --git a/composer.lock b/composer.lock
index 7916f4433..f01833cca 100644
--- a/composer.lock
+++ b/composer.lock
@@ -130,24 +130,25 @@
         },
         {
             "name": "biscolab/laravel-recaptcha",
-            "version": "5.2.0",
+            "version": "v5.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/biscolab/laravel-recaptcha.git",
-                "reference": "30175f16f77d5439d0e058e4dd3b2071dfe4c269"
+                "reference": "1bab726402d5376553a439b88a0faa07e84488fd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/biscolab/laravel-recaptcha/zipball/30175f16f77d5439d0e058e4dd3b2071dfe4c269",
-                "reference": "30175f16f77d5439d0e058e4dd3b2071dfe4c269",
+                "url": "https://api.github.com/repos/biscolab/laravel-recaptcha/zipball/1bab726402d5376553a439b88a0faa07e84488fd",
+                "reference": "1bab726402d5376553a439b88a0faa07e84488fd",
                 "shasum": ""
             },
             "require": {
-                "laravel/framework": "^7.0|^8.0",
+                "illuminate/routing": "^7.0|^8.0|^9.0",
+                "illuminate/support": "^7.0|^8.0|^9.0",
                 "php": "^7.3|^8.0"
             },
             "require-dev": {
-                "orchestra/testbench": "5.*|6.*",
+                "orchestra/testbench": "5.*|6.*|^7.0",
                 "phpunit/phpunit": "^9.1"
             },
             "suggest": {
@@ -165,12 +166,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Biscolab\\ReCaptcha\\": "src/"
-                },
                 "files": [
                     "src/helpers.php"
-                ]
+                ],
+                "psr-4": {
+                    "Biscolab\\ReCaptcha\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -194,9 +195,9 @@
             ],
             "support": {
                 "issues": "https://github.com/biscolab/laravel-recaptcha/issues",
-                "source": "https://github.com/biscolab/laravel-recaptcha/tree/v5.2.0"
+                "source": "https://github.com/biscolab/laravel-recaptcha/tree/v5.4.0"
             },
-            "time": "2022-01-15T14:51:25+00:00"
+            "time": "2022-05-07T12:52:46+00:00"
         },
         {
             "name": "brick/math",
@@ -335,16 +336,16 @@
         },
         {
             "name": "doctrine/cache",
-            "version": "2.1.1",
+            "version": "2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/cache.git",
-                "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce"
+                "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce",
-                "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce",
+                "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
+                "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
                 "shasum": ""
             },
             "require": {
@@ -354,18 +355,12 @@
                 "doctrine/common": ">2.2,<2.4"
             },
             "require-dev": {
-                "alcaeus/mongo-php-adapter": "^1.1",
                 "cache/integration-tests": "dev-master",
-                "doctrine/coding-standard": "^8.0",
-                "mongodb/mongodb": "^1.1",
-                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
-                "predis/predis": "~1.0",
+                "doctrine/coding-standard": "^9",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
                 "psr/cache": "^1.0 || ^2.0 || ^3.0",
-                "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev",
-                "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev"
-            },
-            "suggest": {
-                "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+                "symfony/cache": "^4.4 || ^5.4 || ^6",
+                "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
             },
             "type": "library",
             "autoload": {
@@ -414,7 +409,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/cache/issues",
-                "source": "https://github.com/doctrine/cache/tree/2.1.1"
+                "source": "https://github.com/doctrine/cache/tree/2.2.0"
             },
             "funding": [
                 {
@@ -430,26 +425,26 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-07-17T14:49:29+00:00"
+            "time": "2022-05-20T20:07:39+00:00"
         },
         {
             "name": "doctrine/dbal",
-            "version": "3.3.2",
+            "version": "3.3.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "35eae239ef515d55ebb24e9d4715cad09a4f58ed"
+                "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/35eae239ef515d55ebb24e9d4715cad09a4f58ed",
-                "reference": "35eae239ef515d55ebb24e9d4715cad09a4f58ed",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/9e7f76dd1cde81c62574fdffa5a9c655c847ad21",
+                "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21",
                 "shasum": ""
             },
             "require": {
                 "composer-runtime-api": "^2",
                 "doctrine/cache": "^1.11|^2.0",
-                "doctrine/deprecations": "^0.5.3",
+                "doctrine/deprecations": "^0.5.3|^1",
                 "doctrine/event-manager": "^1.0",
                 "php": "^7.3 || ^8.0",
                 "psr/cache": "^1|^2|^3",
@@ -457,15 +452,15 @@
             },
             "require-dev": {
                 "doctrine/coding-standard": "9.0.0",
-                "jetbrains/phpstorm-stubs": "2021.1",
-                "phpstan/phpstan": "1.4.0",
-                "phpstan/phpstan-strict-rules": "^1.1",
-                "phpunit/phpunit": "9.5.11",
+                "jetbrains/phpstorm-stubs": "2022.1",
+                "phpstan/phpstan": "1.6.3",
+                "phpstan/phpstan-strict-rules": "^1.2",
+                "phpunit/phpunit": "9.5.20",
                 "psalm/plugin-phpunit": "0.16.1",
                 "squizlabs/php_codesniffer": "3.6.2",
                 "symfony/cache": "^5.2|^6.0",
                 "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
-                "vimeo/psalm": "4.16.1"
+                "vimeo/psalm": "4.23.0"
             },
             "suggest": {
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -525,7 +520,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/3.3.2"
+                "source": "https://github.com/doctrine/dbal/tree/3.3.6"
             },
             "funding": [
                 {
@@ -541,29 +536,29 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-02-05T16:33:45+00:00"
+            "time": "2022-05-02T17:21:01+00:00"
         },
         {
             "name": "doctrine/deprecations",
-            "version": "v0.5.3",
+            "version": "v1.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/deprecations.git",
-                "reference": "9504165960a1f83cc1480e2be1dd0a0478561314"
+                "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314",
-                "reference": "9504165960a1f83cc1480e2be1dd0a0478561314",
+                "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+                "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.1|^8.0"
             },
             "require-dev": {
-                "doctrine/coding-standard": "^6.0|^7.0|^8.0",
-                "phpunit/phpunit": "^7.0|^8.0|^9.0",
-                "psr/log": "^1.0"
+                "doctrine/coding-standard": "^9",
+                "phpunit/phpunit": "^7.5|^8.5|^9.5",
+                "psr/log": "^1|^2|^3"
             },
             "suggest": {
                 "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
@@ -582,9 +577,9 @@
             "homepage": "https://www.doctrine-project.org/",
             "support": {
                 "issues": "https://github.com/doctrine/deprecations/issues",
-                "source": "https://github.com/doctrine/deprecations/tree/v0.5.3"
+                "source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
             },
-            "time": "2021-03-21T12:59:47+00:00"
+            "time": "2022-05-02T15:47:09+00:00"
         },
         {
             "name": "doctrine/event-manager",
@@ -773,16 +768,16 @@
         },
         {
             "name": "doctrine/lexer",
-            "version": "1.2.2",
+            "version": "1.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/lexer.git",
-                "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c"
+                "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/lexer/zipball/9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c",
-                "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c",
+                "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229",
+                "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229",
                 "shasum": ""
             },
             "require": {
@@ -790,7 +785,7 @@
             },
             "require-dev": {
                 "doctrine/coding-standard": "^9.0",
-                "phpstan/phpstan": "1.3",
+                "phpstan/phpstan": "^1.3",
                 "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
                 "vimeo/psalm": "^4.11"
             },
@@ -829,7 +824,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/lexer/issues",
-                "source": "https://github.com/doctrine/lexer/tree/1.2.2"
+                "source": "https://github.com/doctrine/lexer/tree/1.2.3"
             },
             "funding": [
                 {
@@ -845,20 +840,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-12T08:27:12+00:00"
+            "time": "2022-02-28T11:07:21+00:00"
         },
         {
             "name": "dompdf/dompdf",
-            "version": "v1.2.0",
+            "version": "v1.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dompdf/dompdf.git",
-                "reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd"
+                "reference": "5031045d9640b38cfc14aac9667470df09c9e090"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dompdf/dompdf/zipball/60b704331479a69e9bcdb3496da2315b5c4f94fd",
-                "reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd",
+                "url": "https://api.github.com/repos/dompdf/dompdf/zipball/5031045d9640b38cfc14aac9667470df09c9e090",
+                "reference": "5031045d9640b38cfc14aac9667470df09c9e090",
                 "shasum": ""
             },
             "require": {
@@ -869,6 +864,8 @@
                 "php": "^7.1 || ^8.0"
             },
             "require-dev": {
+                "ext-json": "*",
+                "ext-zip": "*",
                 "mockery/mockery": "^1.3",
                 "phpunit/phpunit": "^7.5 || ^8 || ^9",
                 "squizlabs/php_codesniffer": "^3.5"
@@ -910,9 +907,9 @@
             "homepage": "https://github.com/dompdf/dompdf",
             "support": {
                 "issues": "https://github.com/dompdf/dompdf/issues",
-                "source": "https://github.com/dompdf/dompdf/tree/v1.2.0"
+                "source": "https://github.com/dompdf/dompdf/tree/v1.2.2"
             },
-            "time": "2022-02-07T13:02:10+00:00"
+            "time": "2022-04-27T13:50:54+00:00"
         },
         {
             "name": "dragonmantank/cron-expression",
@@ -1103,25 +1100,23 @@
         },
         {
             "name": "fruitcake/laravel-cors",
-            "version": "v2.0.5",
+            "version": "v2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/fruitcake/laravel-cors.git",
-                "reference": "3a066e5cac32e2d1cdaacd6b961692778f37b5fc"
+                "reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/3a066e5cac32e2d1cdaacd6b961692778f37b5fc",
-                "reference": "3a066e5cac32e2d1cdaacd6b961692778f37b5fc",
+                "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/783a74f5e3431d7b9805be8afb60fd0a8f743534",
+                "reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534",
                 "shasum": ""
             },
             "require": {
                 "asm89/stack-cors": "^2.0.1",
                 "illuminate/contracts": "^6|^7|^8|^9",
                 "illuminate/support": "^6|^7|^8|^9",
-                "php": ">=7.2",
-                "symfony/http-foundation": "^4|^5|^6",
-                "symfony/http-kernel": "^4.3.4|^5|^6"
+                "php": ">=7.2"
             },
             "require-dev": {
                 "laravel/framework": "^6|^7.24|^8",
@@ -1132,7 +1127,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-master": "2.1-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -1168,7 +1163,7 @@
             ],
             "support": {
                 "issues": "https://github.com/fruitcake/laravel-cors/issues",
-                "source": "https://github.com/fruitcake/laravel-cors/tree/v2.0.5"
+                "source": "https://github.com/fruitcake/laravel-cors/tree/v2.2.0"
             },
             "funding": [
                 {
@@ -1180,7 +1175,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-01-03T14:53:04+00:00"
+            "time": "2022-02-23T14:25:13+00:00"
         },
         {
             "name": "graham-campbell/result-type",
@@ -1246,16 +1241,16 @@
         },
         {
             "name": "guzzlehttp/guzzle",
-            "version": "7.4.1",
+            "version": "7.4.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/guzzle.git",
-                "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79"
+                "reference": "e3ff079b22820c2029d4c2a87796b6a0b8716ad8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79",
-                "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/e3ff079b22820c2029d4c2a87796b6a0b8716ad8",
+                "reference": "e3ff079b22820c2029d4c2a87796b6a0b8716ad8",
                 "shasum": ""
             },
             "require": {
@@ -1288,12 +1283,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "GuzzleHttp\\": "src/"
-                },
                 "files": [
                     "src/functions_include.php"
-                ]
+                ],
+                "psr-4": {
+                    "GuzzleHttp\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -1350,7 +1345,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/guzzle/issues",
-                "source": "https://github.com/guzzle/guzzle/tree/7.4.1"
+                "source": "https://github.com/guzzle/guzzle/tree/7.4.4"
             },
             "funding": [
                 {
@@ -1366,7 +1361,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-12-06T18:43:05+00:00"
+            "time": "2022-06-09T21:39:15+00:00"
         },
         {
             "name": "guzzlehttp/promises",
@@ -1395,12 +1390,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "GuzzleHttp\\Promise\\": "src/"
-                },
                 "files": [
                     "src/functions_include.php"
-                ]
+                ],
+                "psr-4": {
+                    "GuzzleHttp\\Promise\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -1454,16 +1449,16 @@
         },
         {
             "name": "guzzlehttp/psr7",
-            "version": "2.1.0",
+            "version": "2.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72"
+                "reference": "83260bb50b8fc753c72d14dc1621a2dac31877ee"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72",
-                "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/83260bb50b8fc753c72d14dc1621a2dac31877ee",
+                "reference": "83260bb50b8fc753c72d14dc1621a2dac31877ee",
                 "shasum": ""
             },
             "require": {
@@ -1487,7 +1482,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.1-dev"
+                    "dev-master": "2.3-dev"
                 }
             },
             "autoload": {
@@ -1549,7 +1544,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.1.0"
+                "source": "https://github.com/guzzle/psr7/tree/2.3.0"
             },
             "funding": [
                 {
@@ -1565,7 +1560,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-10-06T17:43:30+00:00"
+            "time": "2022-06-09T08:26:02+00:00"
         },
         {
             "name": "hidehalo/nanoid-php",
@@ -1626,27 +1621,29 @@
         },
         {
             "name": "kkomelin/laravel-translatable-string-exporter",
-            "version": "1.14.0",
+            "version": "1.17.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/kkomelin/laravel-translatable-string-exporter.git",
-                "reference": "9dce1e5f8ed59a1b58e77ec7d84f1427d5e29f0a"
+                "reference": "0425f2c3add32df852c002b11bffe72c9c67ec89"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/kkomelin/laravel-translatable-string-exporter/zipball/9dce1e5f8ed59a1b58e77ec7d84f1427d5e29f0a",
-                "reference": "9dce1e5f8ed59a1b58e77ec7d84f1427d5e29f0a",
+                "url": "https://api.github.com/repos/kkomelin/laravel-translatable-string-exporter/zipball/0425f2c3add32df852c002b11bffe72c9c67ec89",
+                "reference": "0425f2c3add32df852c002b11bffe72c9c67ec89",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
-                "illuminate/support": "^5.4|^6|^7|^8",
-                "illuminate/translation": "^5.4|^6|^7|^8",
-                "php": ">=5.4.0",
-                "symfony/finder": "^3.2|^4|^5"
+                "illuminate/support": "^5.4|^6|^7|^8|^9",
+                "illuminate/translation": "^5.4|^6|^7|^8|^9",
+                "php": "^7.2|^8.0",
+                "symfony/finder": "^3.2|^4|^5|^6"
             },
             "require-dev": {
-                "orchestra/testbench": "^3.4|^4.0|^5.0|^6.0"
+                "nunomaduro/larastan": "^1.0|^2.0",
+                "orchestra/testbench": "^3.4|^4.0|^5.0|^6.0|^7.0",
+                "phpunit/phpunit": "^6.0|^7.0|^8.0|^9.0"
             },
             "type": "library",
             "extra": {
@@ -1677,26 +1674,28 @@
                 "exporter",
                 "json",
                 "laravel",
+                "localization",
+                "translation",
                 "translations"
             ],
             "support": {
                 "issues": "https://github.com/kkomelin/laravel-translatable-string-exporter/issues",
-                "source": "https://github.com/kkomelin/laravel-translatable-string-exporter/tree/1.14.0"
+                "source": "https://github.com/kkomelin/laravel-translatable-string-exporter/tree/1.17.0"
             },
-            "time": "2021-08-08T06:48:21+00:00"
+            "time": "2022-06-13T07:13:55+00:00"
         },
         {
             "name": "laravel/framework",
-            "version": "v8.82.0",
+            "version": "v8.83.16",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "411d5243c58cbf12b0fc89cab1ceb50088968c27"
+                "reference": "6be5abd144faf517879af7298e9d79f06f250f75"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/411d5243c58cbf12b0fc89cab1ceb50088968c27",
-                "reference": "411d5243c58cbf12b0fc89cab1ceb50088968c27",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/6be5abd144faf517879af7298e9d79f06f250f75",
+                "reference": "6be5abd144faf517879af7298e9d79f06f250f75",
                 "shasum": ""
             },
             "require": {
@@ -1856,20 +1855,20 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2022-02-01T16:13:57+00:00"
+            "time": "2022-06-07T15:09:06+00:00"
         },
         {
             "name": "laravel/serializable-closure",
-            "version": "v1.1.0",
+            "version": "v1.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/serializable-closure.git",
-                "reference": "65c9faf50d567b65d81764a44526545689e3fe63"
+                "reference": "09f0e9fb61829f628205b7c94906c28740ff9540"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/65c9faf50d567b65d81764a44526545689e3fe63",
-                "reference": "65c9faf50d567b65d81764a44526545689e3fe63",
+                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540",
+                "reference": "09f0e9fb61829f628205b7c94906c28740ff9540",
                 "shasum": ""
             },
             "require": {
@@ -1915,20 +1914,20 @@
                 "issues": "https://github.com/laravel/serializable-closure/issues",
                 "source": "https://github.com/laravel/serializable-closure"
             },
-            "time": "2022-02-01T16:29:39+00:00"
+            "time": "2022-05-16T17:09:47+00:00"
         },
         {
             "name": "laravel/socialite",
-            "version": "v5.5.0",
+            "version": "v5.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/socialite.git",
-                "reference": "cb5b5538c207efa19aa5d7f46cd76acb03ec3055"
+                "reference": "68afb03259b82d898c68196cbcacd48596a9dd72"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/socialite/zipball/cb5b5538c207efa19aa5d7f46cd76acb03ec3055",
-                "reference": "cb5b5538c207efa19aa5d7f46cd76acb03ec3055",
+                "url": "https://api.github.com/repos/laravel/socialite/zipball/68afb03259b82d898c68196cbcacd48596a9dd72",
+                "reference": "68afb03259b82d898c68196cbcacd48596a9dd72",
                 "shasum": ""
             },
             "require": {
@@ -1984,20 +1983,20 @@
                 "issues": "https://github.com/laravel/socialite/issues",
                 "source": "https://github.com/laravel/socialite"
             },
-            "time": "2022-02-01T16:31:36+00:00"
+            "time": "2022-03-10T15:26:19+00:00"
         },
         {
             "name": "laravel/tinker",
-            "version": "v2.7.0",
+            "version": "v2.7.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/tinker.git",
-                "reference": "5f2f9815b7631b9f586a3de7933c25f9327d4073"
+                "reference": "dff39b661e827dae6e092412f976658df82dbac5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/tinker/zipball/5f2f9815b7631b9f586a3de7933c25f9327d4073",
-                "reference": "5f2f9815b7631b9f586a3de7933c25f9327d4073",
+                "url": "https://api.github.com/repos/laravel/tinker/zipball/dff39b661e827dae6e092412f976658df82dbac5",
+                "reference": "dff39b661e827dae6e092412f976658df82dbac5",
                 "shasum": ""
             },
             "require": {
@@ -2050,28 +2049,28 @@
             ],
             "support": {
                 "issues": "https://github.com/laravel/tinker/issues",
-                "source": "https://github.com/laravel/tinker/tree/v2.7.0"
+                "source": "https://github.com/laravel/tinker/tree/v2.7.2"
             },
-            "time": "2022-01-10T08:52:49+00:00"
+            "time": "2022-03-23T12:38:24+00:00"
         },
         {
             "name": "laravel/ui",
-            "version": "v3.4.2",
+            "version": "v3.4.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/ui.git",
-                "reference": "e01198123f7f4369d13c1f83a897c3f5e97fc9f4"
+                "reference": "65ec5c03f7fee2c8ecae785795b829a15be48c2c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/ui/zipball/e01198123f7f4369d13c1f83a897c3f5e97fc9f4",
-                "reference": "e01198123f7f4369d13c1f83a897c3f5e97fc9f4",
+                "url": "https://api.github.com/repos/laravel/ui/zipball/65ec5c03f7fee2c8ecae785795b829a15be48c2c",
+                "reference": "65ec5c03f7fee2c8ecae785795b829a15be48c2c",
                 "shasum": ""
             },
             "require": {
                 "illuminate/console": "^8.42|^9.0",
                 "illuminate/filesystem": "^8.42|^9.0",
-                "illuminate/support": "^8.42|^9.0",
+                "illuminate/support": "^8.82|^9.0",
                 "illuminate/validation": "^8.42|^9.0",
                 "php": "^7.3|^8.0"
             },
@@ -2111,9 +2110,9 @@
                 "ui"
             ],
             "support": {
-                "source": "https://github.com/laravel/ui/tree/v3.4.2"
+                "source": "https://github.com/laravel/ui/tree/v3.4.6"
             },
-            "time": "2022-01-25T20:15:56+00:00"
+            "time": "2022-05-20T13:38:08+00:00"
         },
         {
             "name": "laraveldaily/laravel-invoices",
@@ -2182,16 +2181,16 @@
         },
         {
             "name": "league/commonmark",
-            "version": "2.2.1",
+            "version": "2.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/commonmark.git",
-                "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a"
+                "reference": "0da1dca5781dd3cfddbe328224d9a7a62571addc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a",
-                "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a",
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/0da1dca5781dd3cfddbe328224d9a7a62571addc",
+                "reference": "0da1dca5781dd3cfddbe328224d9a7a62571addc",
                 "shasum": ""
             },
             "require": {
@@ -2200,17 +2199,19 @@
                 "php": "^7.4 || ^8.0",
                 "psr/event-dispatcher": "^1.0",
                 "symfony/deprecation-contracts": "^2.1 || ^3.0",
-                "symfony/polyfill-php80": "^1.15"
+                "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",
+                "nyholm/psr7": "^1.5",
                 "phpstan/phpstan": "^0.12.88 || ^1.0.0",
                 "phpunit/phpunit": "^9.5.5",
                 "scrutinizer/ocular": "^1.8.1",
@@ -2225,7 +2226,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "2.3-dev"
+                    "dev-main": "2.4-dev"
                 }
             },
             "autoload": {
@@ -2282,7 +2283,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-25T14:37:33+00:00"
+            "time": "2022-06-07T21:28:26+00:00"
         },
         {
             "name": "league/config",
@@ -2462,16 +2463,16 @@
         },
         {
             "name": "league/mime-type-detection",
-            "version": "1.9.0",
+            "version": "1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/mime-type-detection.git",
-                "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69"
+                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69",
-                "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69",
+                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
                 "shasum": ""
             },
             "require": {
@@ -2502,7 +2503,7 @@
             "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.9.0"
+                "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
             },
             "funding": [
                 {
@@ -2514,20 +2515,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-21T11:48:40+00:00"
+            "time": "2022-04-17T13:12:02+00:00"
         },
         {
             "name": "league/oauth1-client",
-            "version": "v1.10.0",
+            "version": "v1.10.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/oauth1-client.git",
-                "reference": "88dd16b0cff68eb9167bfc849707d2c40ad91ddc"
+                "reference": "d6365b901b5c287dd41f143033315e2f777e1167"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/88dd16b0cff68eb9167bfc849707d2c40ad91ddc",
-                "reference": "88dd16b0cff68eb9167bfc849707d2c40ad91ddc",
+                "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167",
+                "reference": "d6365b901b5c287dd41f143033315e2f777e1167",
                 "shasum": ""
             },
             "require": {
@@ -2588,22 +2589,22 @@
             ],
             "support": {
                 "issues": "https://github.com/thephpleague/oauth1-client/issues",
-                "source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.0"
+                "source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1"
             },
-            "time": "2021-08-15T23:05:49+00:00"
+            "time": "2022-04-15T14:02:14+00:00"
         },
         {
             "name": "monolog/monolog",
-            "version": "2.3.5",
+            "version": "2.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/monolog.git",
-                "reference": "fd4380d6fc37626e2f799f29d91195040137eba9"
+                "reference": "5579edf28aee1190a798bfa5be8bc16c563bd524"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9",
-                "reference": "fd4380d6fc37626e2f799f29d91195040137eba9",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5579edf28aee1190a798bfa5be8bc16c563bd524",
+                "reference": "5579edf28aee1190a798bfa5be8bc16c563bd524",
                 "shasum": ""
             },
             "require": {
@@ -2616,18 +2617,23 @@
             "require-dev": {
                 "aws/aws-sdk-php": "^2.4.9 || ^3.0",
                 "doctrine/couchdb": "~1.0@dev",
-                "elasticsearch/elasticsearch": "^7",
+                "elasticsearch/elasticsearch": "^7 || ^8",
+                "ext-json": "*",
                 "graylog2/gelf-php": "^1.4.2",
+                "guzzlehttp/guzzle": "^7.4",
+                "guzzlehttp/psr7": "^2.2",
                 "mongodb/mongodb": "^1.8",
                 "php-amqplib/php-amqplib": "~2.4 || ^3",
                 "php-console/php-console": "^3.1.3",
-                "phpspec/prophecy": "^1.6.1",
+                "phpspec/prophecy": "^1.15",
                 "phpstan/phpstan": "^0.12.91",
-                "phpunit/phpunit": "^8.5",
+                "phpunit/phpunit": "^8.5.14",
                 "predis/predis": "^1.1",
-                "rollbar/rollbar": "^1.3",
-                "ruflin/elastica": ">=0.90@dev",
-                "swiftmailer/swiftmailer": "^5.3|^6.0"
+                "rollbar/rollbar": "^1.3 || ^2 || ^3",
+                "ruflin/elastica": "^7",
+                "swiftmailer/swiftmailer": "^5.3|^6.0",
+                "symfony/mailer": "^5.4 || ^6",
+                "symfony/mime": "^5.4 || ^6"
             },
             "suggest": {
                 "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
@@ -2677,7 +2683,7 @@
             ],
             "support": {
                 "issues": "https://github.com/Seldaek/monolog/issues",
-                "source": "https://github.com/Seldaek/monolog/tree/2.3.5"
+                "source": "https://github.com/Seldaek/monolog/tree/2.7.0"
             },
             "funding": [
                 {
@@ -2689,20 +2695,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-10-01T21:08:31+00:00"
+            "time": "2022-06-09T08:59:12+00:00"
         },
         {
             "name": "nesbot/carbon",
-            "version": "2.56.0",
+            "version": "2.58.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "626ec8cbb724cd3c3400c3ed8f730545b744e3f4"
+                "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/626ec8cbb724cd3c3400c3ed8f730545b744e3f4",
-                "reference": "626ec8cbb724cd3c3400c3ed8f730545b744e3f4",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/97a34af22bde8d0ac20ab34b29d7bfe360902055",
+                "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055",
                 "shasum": ""
             },
             "require": {
@@ -2720,7 +2726,8 @@
                 "phpmd/phpmd": "^2.9",
                 "phpstan/extension-installer": "^1.0",
                 "phpstan/phpstan": "^0.12.54 || ^1.0",
-                "phpunit/phpunit": "^7.5.20 || ^8.5.14",
+                "phpunit/php-file-iterator": "^2.0.5",
+                "phpunit/phpunit": "^7.5.20 || ^8.5.23",
                 "squizlabs/php_codesniffer": "^3.4"
             },
             "bin": [
@@ -2785,7 +2792,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-21T17:08:38+00:00"
+            "time": "2022-04-25T19:31:17+00:00"
         },
         {
             "name": "nette/schema",
@@ -2936,16 +2943,16 @@
         },
         {
             "name": "nikic/php-parser",
-            "version": "v4.13.2",
+            "version": "v4.14.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "210577fe3cf7badcc5814d99455df46564f3c077"
+                "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077",
-                "reference": "210577fe3cf7badcc5814d99455df46564f3c077",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1",
+                "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1",
                 "shasum": ""
             },
             "require": {
@@ -2986,9 +2993,9 @@
             ],
             "support": {
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
-                "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2"
+                "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0"
             },
-            "time": "2021-11-30T19:35:32+00:00"
+            "time": "2022-05-31T20:59:12+00:00"
         },
         {
             "name": "opis/closure",
@@ -3018,12 +3025,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Opis\\Closure\\": "src/"
-                },
                 "files": [
                     "functions.php"
-                ]
+                ],
+                "psr-4": {
+                    "Opis\\Closure\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -3128,8 +3135,8 @@
             "type": "library",
             "autoload": {
                 "psr-4": {
-                    "PayPalCheckoutSdk\\": "lib/PayPalCheckoutSdk",
-                    "Sample\\": "samples/"
+                    "Sample\\": "samples/",
+                    "PayPalCheckoutSdk\\": "lib/PayPalCheckoutSdk"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -3300,25 +3307,25 @@
         },
         {
             "name": "phenx/php-svg-lib",
-            "version": "0.4.0",
+            "version": "0.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dompdf/php-svg-lib.git",
-                "reference": "3ffbbb037f0871c3a819e90cff8b36dd7e656189"
+                "reference": "4498b5df7b08e8469f0f8279651ea5de9626ed02"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/3ffbbb037f0871c3a819e90cff8b36dd7e656189",
-                "reference": "3ffbbb037f0871c3a819e90cff8b36dd7e656189",
+                "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/4498b5df7b08e8469f0f8279651ea5de9626ed02",
+                "reference": "4498b5df7b08e8469f0f8279651ea5de9626ed02",
                 "shasum": ""
             },
             "require": {
                 "ext-mbstring": "*",
-                "php": "^7.4 || ^8.0",
+                "php": "^7.1 || ^7.2 || ^7.3 || ^7.4 || ^8.0",
                 "sabberworm/php-css-parser": "^8.4"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.5"
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
             },
             "type": "library",
             "autoload": {
@@ -3340,9 +3347,9 @@
             "homepage": "https://github.com/PhenX/php-svg-lib",
             "support": {
                 "issues": "https://github.com/dompdf/php-svg-lib/issues",
-                "source": "https://github.com/dompdf/php-svg-lib/tree/0.4.0"
+                "source": "https://github.com/dompdf/php-svg-lib/tree/0.4.1"
             },
-            "time": "2021-12-17T14:08:35+00:00"
+            "time": "2022-03-07T12:52:04+00:00"
         },
         {
             "name": "phpoption/phpoption",
@@ -3825,16 +3832,16 @@
         },
         {
             "name": "psy/psysh",
-            "version": "v0.11.1",
+            "version": "v0.11.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/bobthecow/psysh.git",
-                "reference": "570292577277f06f590635381a7f761a6cf4f026"
+                "reference": "c23686f9c48ca202710dbb967df8385a952a2daf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/570292577277f06f590635381a7f761a6cf4f026",
-                "reference": "570292577277f06f590635381a7f761a6cf4f026",
+                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/c23686f9c48ca202710dbb967df8385a952a2daf",
+                "reference": "c23686f9c48ca202710dbb967df8385a952a2daf",
                 "shasum": ""
             },
             "require": {
@@ -3845,16 +3852,17 @@
                 "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",
-                "hoa/console": "3.17.05.02"
+                "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.",
-                "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit."
+                "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history."
             },
             "bin": [
                 "bin/psysh"
@@ -3894,9 +3902,9 @@
             ],
             "support": {
                 "issues": "https://github.com/bobthecow/psysh/issues",
-                "source": "https://github.com/bobthecow/psysh/tree/v0.11.1"
+                "source": "https://github.com/bobthecow/psysh/tree/v0.11.5"
             },
-            "time": "2022-01-03T13:58:38+00:00"
+            "time": "2022-05-27T18:03:49+00:00"
         },
         {
             "name": "ralouphie/getallheaders",
@@ -4023,25 +4031,24 @@
         },
         {
             "name": "ramsey/uuid",
-            "version": "4.2.3",
+            "version": "4.3.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ramsey/uuid.git",
-                "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df"
+                "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df",
-                "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/8505afd4fea63b81a85d3b7b53ac3cb8dc347c28",
+                "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28",
                 "shasum": ""
             },
             "require": {
                 "brick/math": "^0.8 || ^0.9",
+                "ext-ctype": "*",
                 "ext-json": "*",
-                "php": "^7.2 || ^8.0",
-                "ramsey/collection": "^1.0",
-                "symfony/polyfill-ctype": "^1.8",
-                "symfony/polyfill-php80": "^1.14"
+                "php": "^8.0",
+                "ramsey/collection": "^1.0"
             },
             "replace": {
                 "rhumsaa/uuid": "self.version"
@@ -4078,20 +4085,17 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "4.x-dev"
-                },
                 "captainhook": {
                     "force-install": true
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Ramsey\\Uuid\\": "src/"
-                },
                 "files": [
                     "src/functions.php"
-                ]
+                ],
+                "psr-4": {
+                    "Ramsey\\Uuid\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -4105,7 +4109,7 @@
             ],
             "support": {
                 "issues": "https://github.com/ramsey/uuid/issues",
-                "source": "https://github.com/ramsey/uuid/tree/4.2.3"
+                "source": "https://github.com/ramsey/uuid/tree/4.3.1"
             },
             "funding": [
                 {
@@ -4117,7 +4121,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-09-25T23:10:38+00:00"
+            "time": "2022-03-27T21:42:02+00:00"
         },
         {
             "name": "sabberworm/php-css-parser",
@@ -4521,16 +4525,16 @@
         },
         {
             "name": "stripe/stripe-php",
-            "version": "v7.113.0",
+            "version": "v7.128.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/stripe/stripe-php.git",
-                "reference": "1aef1ccffad48f39952073e0ed53cb8f3f1b1d8c"
+                "reference": "c704949c49b72985c76cc61063aa26fefbd2724e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/1aef1ccffad48f39952073e0ed53cb8f3f1b1d8c",
-                "reference": "1aef1ccffad48f39952073e0ed53cb8f3f1b1d8c",
+                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/c704949c49b72985c76cc61063aa26fefbd2724e",
+                "reference": "c704949c49b72985c76cc61063aa26fefbd2724e",
                 "shasum": ""
             },
             "require": {
@@ -4575,9 +4579,9 @@
             ],
             "support": {
                 "issues": "https://github.com/stripe/stripe-php/issues",
-                "source": "https://github.com/stripe/stripe-php/tree/v7.113.0"
+                "source": "https://github.com/stripe/stripe-php/tree/v7.128.0"
             },
-            "time": "2022-02-03T23:46:29+00:00"
+            "time": "2022-05-05T17:18:02+00:00"
         },
         {
             "name": "swiftmailer/swiftmailer",
@@ -4657,16 +4661,16 @@
         },
         {
             "name": "symfony/console",
-            "version": "v5.4.3",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8"
+                "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/a2a86ec353d825c75856c6fd14fac416a7bdb6b8",
-                "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8",
+                "url": "https://api.github.com/repos/symfony/console/zipball/829d5d1bf60b2efeb0887b7436873becc71a45eb",
+                "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb",
                 "shasum": ""
             },
             "require": {
@@ -4736,7 +4740,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v5.4.3"
+                "source": "https://github.com/symfony/console/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -4752,7 +4756,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-26T16:28:35+00:00"
+            "time": "2022-05-18T06:17:34+00:00"
         },
         {
             "name": "symfony/css-selector",
@@ -4821,16 +4825,16 @@
         },
         {
             "name": "symfony/deprecation-contracts",
-            "version": "v3.0.0",
+            "version": "v3.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/deprecation-contracts.git",
-                "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced"
+                "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced",
-                "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c",
+                "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c",
                 "shasum": ""
             },
             "require": {
@@ -4868,7 +4872,7 @@
             "description": "A generic function and convention to trigger deprecation notices",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0"
+                "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1"
             },
             "funding": [
                 {
@@ -4884,20 +4888,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-01T23:48:49+00:00"
+            "time": "2022-01-02T09:55:41+00:00"
         },
         {
             "name": "symfony/error-handler",
-            "version": "v5.4.3",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5"
+                "reference": "c116cda1f51c678782768dce89a45f13c949455d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5",
-                "reference": "c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/c116cda1f51c678782768dce89a45f13c949455d",
+                "reference": "c116cda1f51c678782768dce89a45f13c949455d",
                 "shasum": ""
             },
             "require": {
@@ -4939,7 +4943,7 @@
             "description": "Provides tools to manage errors and ease debugging PHP code",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/error-handler/tree/v5.4.3"
+                "source": "https://github.com/symfony/error-handler/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -4955,20 +4959,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-05-21T13:57:48+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v6.0.3",
+            "version": "v6.0.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934"
+                "reference": "5c85b58422865d42c6eb46f7693339056db098a8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934",
-                "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/5c85b58422865d42c6eb46f7693339056db098a8",
+                "reference": "5c85b58422865d42c6eb46f7693339056db098a8",
                 "shasum": ""
             },
             "require": {
@@ -5022,7 +5026,7 @@
             "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.0.3"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.9"
             },
             "funding": [
                 {
@@ -5038,20 +5042,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:55:41+00:00"
+            "time": "2022-05-05T16:45:52+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
-            "version": "v3.0.0",
+            "version": "v3.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher-contracts.git",
-                "reference": "aa5422287b75594b90ee9cd807caf8f0df491385"
+                "reference": "7bc61cc2db649b4637d331240c5346dcc7708051"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385",
-                "reference": "aa5422287b75594b90ee9cd807caf8f0df491385",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051",
+                "reference": "7bc61cc2db649b4637d331240c5346dcc7708051",
                 "shasum": ""
             },
             "require": {
@@ -5101,7 +5105,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0"
+                "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1"
             },
             "funding": [
                 {
@@ -5117,20 +5121,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-07-15T12:33:35+00:00"
+            "time": "2022-01-02T09:55:41+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v5.4.3",
+            "version": "v5.4.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d"
+                "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d",
-                "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/9b630f3427f3ebe7cd346c277a1408b00249dad9",
+                "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9",
                 "shasum": ""
             },
             "require": {
@@ -5164,7 +5168,7 @@
             "description": "Finds files and directories via an intuitive fluent interface",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/finder/tree/v5.4.3"
+                "source": "https://github.com/symfony/finder/tree/v5.4.8"
             },
             "funding": [
                 {
@@ -5180,20 +5184,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-26T16:34:36+00:00"
+            "time": "2022-04-15T08:07:45+00:00"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v5.4.3",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "ef409ff341a565a3663157d4324536746d49a0c7"
+                "reference": "6b0d0e4aca38d57605dcd11e2416994b38774522"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ef409ff341a565a3663157d4324536746d49a0c7",
-                "reference": "ef409ff341a565a3663157d4324536746d49a0c7",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6b0d0e4aca38d57605dcd11e2416994b38774522",
+                "reference": "6b0d0e4aca38d57605dcd11e2416994b38774522",
                 "shasum": ""
             },
             "require": {
@@ -5237,7 +5241,7 @@
             "description": "Defines an object-oriented layer for the HTTP specification",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-foundation/tree/v5.4.3"
+                "source": "https://github.com/symfony/http-foundation/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -5253,20 +5257,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-05-17T15:07:29+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v5.4.4",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "49f40347228c773688a0488feea0175aa7f4d268"
+                "reference": "34b121ad3dc761f35fe1346d2f15618f8cbf77f8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/49f40347228c773688a0488feea0175aa7f4d268",
-                "reference": "49f40347228c773688a0488feea0175aa7f4d268",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/34b121ad3dc761f35fe1346d2f15618f8cbf77f8",
+                "reference": "34b121ad3dc761f35fe1346d2f15618f8cbf77f8",
                 "shasum": ""
             },
             "require": {
@@ -5349,7 +5353,7 @@
             "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/v5.4.4"
+                "source": "https://github.com/symfony/http-kernel/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -5365,20 +5369,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-29T18:08:07+00:00"
+            "time": "2022-05-27T07:09:08+00:00"
         },
         {
             "name": "symfony/intl",
-            "version": "v5.4.3",
+            "version": "v5.4.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/intl.git",
-                "reference": "29e326276b2455bcfa4ce02abcf7689e884acdac"
+                "reference": "b9e17d7ab867ce99f89950ebced0fa91076ba12b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/intl/zipball/29e326276b2455bcfa4ce02abcf7689e884acdac",
-                "reference": "29e326276b2455bcfa4ce02abcf7689e884acdac",
+                "url": "https://api.github.com/repos/symfony/intl/zipball/b9e17d7ab867ce99f89950ebced0fa91076ba12b",
+                "reference": "b9e17d7ab867ce99f89950ebced0fa91076ba12b",
                 "shasum": ""
             },
             "require": {
@@ -5391,15 +5395,15 @@
             },
             "type": "library",
             "autoload": {
+                "files": [
+                    "Resources/functions.php"
+                ],
                 "psr-4": {
                     "Symfony\\Component\\Intl\\": ""
                 },
                 "classmap": [
                     "Resources/stubs"
                 ],
-                "files": [
-                    "Resources/functions.php"
-                ],
                 "exclude-from-classmap": [
                     "/Tests/"
                 ]
@@ -5437,7 +5441,7 @@
                 "localization"
             ],
             "support": {
-                "source": "https://github.com/symfony/intl/tree/v5.4.3"
+                "source": "https://github.com/symfony/intl/tree/v5.4.8"
             },
             "funding": [
                 {
@@ -5453,20 +5457,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-04-07T09:39:59+00:00"
         },
         {
             "name": "symfony/mime",
-            "version": "v5.4.3",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mime.git",
-                "reference": "e1503cfb5c9a225350f549d3bb99296f4abfb80f"
+                "reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mime/zipball/e1503cfb5c9a225350f549d3bb99296f4abfb80f",
-                "reference": "e1503cfb5c9a225350f549d3bb99296f4abfb80f",
+                "url": "https://api.github.com/repos/symfony/mime/zipball/2b3802a24e48d0cfccf885173d2aac91e73df92e",
+                "reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e",
                 "shasum": ""
             },
             "require": {
@@ -5520,7 +5524,7 @@
                 "mime-type"
             ],
             "support": {
-                "source": "https://github.com/symfony/mime/tree/v5.4.3"
+                "source": "https://github.com/symfony/mime/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -5536,20 +5540,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-05-21T10:24:18+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "30885182c981ab175d4d034db0f6f469898070ab"
+                "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
-                "reference": "30885182c981ab175d4d034db0f6f469898070ab",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+                "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
                 "shasum": ""
             },
             "require": {
@@ -5564,7 +5568,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -5572,12 +5576,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Ctype\\": ""
-                },
                 "files": [
                     "bootstrap.php"
-                ]
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -5602,7 +5606,7 @@
                 "portable"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -5618,20 +5622,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-10-20T20:35:02+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-iconv",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-iconv.git",
-                "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40"
+                "reference": "143f1881e655bebca1312722af8068de235ae5dc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/f1aed619e28cb077fc83fac8c4c0383578356e40",
-                "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40",
+                "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/143f1881e655bebca1312722af8068de235ae5dc",
+                "reference": "143f1881e655bebca1312722af8068de235ae5dc",
                 "shasum": ""
             },
             "require": {
@@ -5646,7 +5650,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -5685,7 +5689,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-iconv/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-iconv/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -5701,20 +5705,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-04T09:04:05+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-intl-grapheme",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
-                "reference": "81b86b50cf841a64252b439e738e97f4a34e2783"
+                "reference": "433d05519ce6990bf3530fba6957499d327395c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783",
-                "reference": "81b86b50cf841a64252b439e738e97f4a34e2783",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2",
+                "reference": "433d05519ce6990bf3530fba6957499d327395c2",
                 "shasum": ""
             },
             "require": {
@@ -5726,7 +5730,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -5766,7 +5770,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -5782,20 +5786,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-23T21:10:46+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-intl-idn",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-idn.git",
-                "reference": "749045c69efb97c70d25d7463abba812e91f3a44"
+                "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44",
-                "reference": "749045c69efb97c70d25d7463abba812e91f3a44",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
+                "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
                 "shasum": ""
             },
             "require": {
@@ -5809,7 +5813,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -5853,7 +5857,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -5869,20 +5873,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-09-14T14:02:44+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-intl-normalizer",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
-                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
+                "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
-                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
+                "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
                 "shasum": ""
             },
             "require": {
@@ -5894,7 +5898,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -5937,7 +5941,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -5953,20 +5957,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-02-19T12:13:01+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
+                "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
-                "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+                "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
                 "shasum": ""
             },
             "require": {
@@ -5981,7 +5985,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -5989,12 +5993,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Mbstring\\": ""
-                },
                 "files": [
                     "bootstrap.php"
-                ]
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -6020,7 +6024,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -6036,20 +6040,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-30T18:21:41+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-php72",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php72.git",
-                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
+                "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
-                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
+                "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
                 "shasum": ""
             },
             "require": {
@@ -6058,7 +6062,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -6096,7 +6100,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -6112,20 +6116,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-05-27T09:17:38+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-php73",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php73.git",
-                "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5"
+                "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5",
-                "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5",
+                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
+                "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
                 "shasum": ""
             },
             "require": {
@@ -6134,7 +6138,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -6175,7 +6179,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -6191,20 +6195,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-06-05T21:20:04+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-php80",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php80.git",
-                "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
+                "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
-                "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+                "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
                 "shasum": ""
             },
             "require": {
@@ -6213,7 +6217,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -6258,7 +6262,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -6274,20 +6278,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-09-13T13:58:33+00:00"
+            "time": "2022-05-10T07:21:04+00:00"
         },
         {
             "name": "symfony/polyfill-php81",
-            "version": "v1.24.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php81.git",
-                "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"
+                "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
-                "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
+                "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1",
+                "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1",
                 "shasum": ""
             },
             "require": {
@@ -6296,7 +6300,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -6337,7 +6341,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0"
+                "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -6353,20 +6357,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-09-13T13:58:11+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/process",
-            "version": "v5.4.3",
+            "version": "v5.4.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "553f50487389a977eb31cf6b37faae56da00f753"
+                "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/553f50487389a977eb31cf6b37faae56da00f753",
-                "reference": "553f50487389a977eb31cf6b37faae56da00f753",
+                "url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
+                "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
                 "shasum": ""
             },
             "require": {
@@ -6399,7 +6403,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v5.4.3"
+                "source": "https://github.com/symfony/process/tree/v5.4.8"
             },
             "funding": [
                 {
@@ -6415,20 +6419,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-26T16:28:35+00:00"
+            "time": "2022-04-08T05:07:18+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v5.4.3",
+            "version": "v5.4.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "44b29c7a94e867ccde1da604792f11a469958981"
+                "reference": "e07817bb6244ea33ef5ad31abc4a9288bef3f2f7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/44b29c7a94e867ccde1da604792f11a469958981",
-                "reference": "44b29c7a94e867ccde1da604792f11a469958981",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/e07817bb6244ea33ef5ad31abc4a9288bef3f2f7",
+                "reference": "e07817bb6244ea33ef5ad31abc4a9288bef3f2f7",
                 "shasum": ""
             },
             "require": {
@@ -6489,7 +6493,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v5.4.3"
+                "source": "https://github.com/symfony/routing/tree/v5.4.8"
             },
             "funding": [
                 {
@@ -6505,25 +6509,26 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-04-18T21:45:37+00:00"
         },
         {
             "name": "symfony/service-contracts",
-            "version": "v2.4.1",
+            "version": "v2.5.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/service-contracts.git",
-                "reference": "d664541b99d6fb0247ec5ff32e87238582236204"
+                "reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d664541b99d6fb0247ec5ff32e87238582236204",
-                "reference": "d664541b99d6fb0247ec5ff32e87238582236204",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/24d9dc654b83e91aa59f9d167b131bc3b5bea24c",
+                "reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c",
                 "shasum": ""
             },
             "require": {
                 "php": ">=7.2.5",
-                "psr/container": "^1.1"
+                "psr/container": "^1.1",
+                "symfony/deprecation-contracts": "^2.1|^3"
             },
             "conflict": {
                 "ext-psr": "<1.1|>=2"
@@ -6534,7 +6539,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "2.4-dev"
+                    "dev-main": "2.5-dev"
                 },
                 "thanks": {
                     "name": "symfony/contracts",
@@ -6571,7 +6576,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/service-contracts/tree/v2.4.1"
+                "source": "https://github.com/symfony/service-contracts/tree/v2.5.1"
             },
             "funding": [
                 {
@@ -6587,20 +6592,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-04T16:37:19+00:00"
+            "time": "2022-03-13T20:07:29+00:00"
         },
         {
             "name": "symfony/string",
-            "version": "v6.0.3",
+            "version": "v6.0.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2"
+                "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2",
-                "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2",
+                "url": "https://api.github.com/repos/symfony/string/zipball/df9f03d595aa2d446498ba92fe803a519b2c43cc",
+                "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc",
                 "shasum": ""
             },
             "require": {
@@ -6621,12 +6626,12 @@
             },
             "type": "library",
             "autoload": {
-                "psr-4": {
-                    "Symfony\\Component\\String\\": ""
-                },
                 "files": [
                     "Resources/functions.php"
                 ],
+                "psr-4": {
+                    "Symfony\\Component\\String\\": ""
+                },
                 "exclude-from-classmap": [
                     "/Tests/"
                 ]
@@ -6656,7 +6661,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v6.0.3"
+                "source": "https://github.com/symfony/string/tree/v6.0.9"
             },
             "funding": [
                 {
@@ -6672,20 +6677,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:55:41+00:00"
+            "time": "2022-04-22T08:18:02+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v6.0.3",
+            "version": "v6.0.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "71bb15335798f8c4da110911bcf2d2fead7a430d"
+                "reference": "9ba011309943955a3807b8236c17cff3b88f67b6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/71bb15335798f8c4da110911bcf2d2fead7a430d",
-                "reference": "71bb15335798f8c4da110911bcf2d2fead7a430d",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/9ba011309943955a3807b8236c17cff3b88f67b6",
+                "reference": "9ba011309943955a3807b8236c17cff3b88f67b6",
                 "shasum": ""
             },
             "require": {
@@ -6751,7 +6756,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v6.0.3"
+                "source": "https://github.com/symfony/translation/tree/v6.0.9"
             },
             "funding": [
                 {
@@ -6767,20 +6772,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-07T00:29:03+00:00"
+            "time": "2022-05-06T14:27:17+00:00"
         },
         {
             "name": "symfony/translation-contracts",
-            "version": "v3.0.0",
+            "version": "v3.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation-contracts.git",
-                "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77"
+                "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1b6ea5a7442af5a12dba3dbd6d71034b5b234e77",
-                "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77",
+                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9",
+                "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9",
                 "shasum": ""
             },
             "require": {
@@ -6829,7 +6834,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/translation-contracts/tree/v3.0.0"
+                "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1"
             },
             "funding": [
                 {
@@ -6845,20 +6850,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-09-07T12:43:40+00:00"
+            "time": "2022-01-02T09:55:41+00:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v5.4.3",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "970a01f208bf895c5f327ba40b72288da43adec4"
+                "reference": "af52239a330fafd192c773795520dc2dd62b5657"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/970a01f208bf895c5f327ba40b72288da43adec4",
-                "reference": "970a01f208bf895c5f327ba40b72288da43adec4",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/af52239a330fafd192c773795520dc2dd62b5657",
+                "reference": "af52239a330fafd192c773795520dc2dd62b5657",
                 "shasum": ""
             },
             "require": {
@@ -6918,7 +6923,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v5.4.3"
+                "source": "https://github.com/symfony/var-dumper/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -6934,7 +6939,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-17T16:30:37+00:00"
+            "time": "2022-05-21T10:24:18+00:00"
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
@@ -7145,21 +7150,21 @@
         },
         {
             "name": "webmozart/assert",
-            "version": "1.10.0",
+            "version": "1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webmozarts/assert.git",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.2 || ^8.0",
-                "symfony/polyfill-ctype": "^1.8"
+                "ext-ctype": "*",
+                "php": "^7.2 || ^8.0"
             },
             "conflict": {
                 "phpstan/phpstan": "<0.12.20",
@@ -7197,22 +7202,22 @@
             ],
             "support": {
                 "issues": "https://github.com/webmozarts/assert/issues",
-                "source": "https://github.com/webmozarts/assert/tree/1.10.0"
+                "source": "https://github.com/webmozarts/assert/tree/1.11.0"
             },
-            "time": "2021-03-09T10:59:23+00:00"
+            "time": "2022-06-03T18:03:27+00:00"
         },
         {
             "name": "yajra/laravel-datatables-oracle",
-            "version": "v9.19.0",
+            "version": "v9.20.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/yajra/laravel-datatables.git",
-                "reference": "553482df5f68969928acc0ee1a3af032cdaaf824"
+                "reference": "4c22b09c8c664df5aad9f17d99c3823c0f2d84e2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/553482df5f68969928acc0ee1a3af032cdaaf824",
-                "reference": "553482df5f68969928acc0ee1a3af032cdaaf824",
+                "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/4c22b09c8c664df5aad9f17d99c3823c0f2d84e2",
+                "reference": "4c22b09c8c664df5aad9f17d99c3823c0f2d84e2",
                 "shasum": ""
             },
             "require": {
@@ -7272,7 +7277,7 @@
             ],
             "support": {
                 "issues": "https://github.com/yajra/laravel-datatables/issues",
-                "source": "https://github.com/yajra/laravel-datatables/tree/v9.19.0"
+                "source": "https://github.com/yajra/laravel-datatables/tree/v9.20.0"
             },
             "funding": [
                 {
@@ -7284,22 +7289,22 @@
                     "type": "patreon"
                 }
             ],
-            "time": "2022-01-18T01:13:47+00:00"
+            "time": "2022-05-08T16:04:16+00:00"
         }
     ],
     "packages-dev": [
         {
             "name": "barryvdh/laravel-debugbar",
-            "version": "v3.6.6",
+            "version": "v3.6.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-debugbar.git",
-                "reference": "f92fe967b40b36ad1ee8ed2fd59c05ae67a1ebba"
+                "reference": "b96f9820aaf1ff9afe945207883149e1c7afb298"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/f92fe967b40b36ad1ee8ed2fd59c05ae67a1ebba",
-                "reference": "f92fe967b40b36ad1ee8ed2fd59c05ae67a1ebba",
+                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/b96f9820aaf1ff9afe945207883149e1c7afb298",
+                "reference": "b96f9820aaf1ff9afe945207883149e1c7afb298",
                 "shasum": ""
             },
             "require": {
@@ -7313,7 +7318,7 @@
             },
             "require-dev": {
                 "mockery/mockery": "^1.3.3",
-                "orchestra/testbench-dusk": "^4|^5|^6",
+                "orchestra/testbench-dusk": "^4|^5|^6|^7",
                 "phpunit/phpunit": "^8.5|^9.0",
                 "squizlabs/php_codesniffer": "^3.5"
             },
@@ -7332,12 +7337,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Barryvdh\\Debugbar\\": "src/"
-                },
                 "files": [
                     "src/helpers.php"
-                ]
+                ],
+                "psr-4": {
+                    "Barryvdh\\Debugbar\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -7359,7 +7364,7 @@
             ],
             "support": {
                 "issues": "https://github.com/barryvdh/laravel-debugbar/issues",
-                "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.6.6"
+                "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.6.7"
             },
             "funding": [
                 {
@@ -7371,33 +7376,34 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-12-21T18:20:10+00:00"
+            "time": "2022-02-09T07:52:32+00:00"
         },
         {
             "name": "doctrine/instantiator",
-            "version": "1.4.0",
+            "version": "1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/instantiator.git",
-                "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
+                "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
-                "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
+                "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.1 || ^8.0"
             },
             "require-dev": {
-                "doctrine/coding-standard": "^8.0",
+                "doctrine/coding-standard": "^9",
                 "ext-pdo": "*",
                 "ext-phar": "*",
-                "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
-                "phpstan/phpstan": "^0.12",
-                "phpstan/phpstan-phpunit": "^0.12",
-                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
+                "phpbench/phpbench": "^0.16 || ^1",
+                "phpstan/phpstan": "^1.4",
+                "phpstan/phpstan-phpunit": "^1",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "vimeo/psalm": "^4.22"
             },
             "type": "library",
             "autoload": {
@@ -7424,7 +7430,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/instantiator/issues",
-                "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
+                "source": "https://github.com/doctrine/instantiator/tree/1.4.1"
             },
             "funding": [
                 {
@@ -7440,7 +7446,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2020-11-10T18:47:58+00:00"
+            "time": "2022-03-03T08:28:38+00:00"
         },
         {
             "name": "facade/flare-client-php",
@@ -7476,12 +7482,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Facade\\FlareClient\\": "src"
-                },
                 "files": [
                     "src/helpers.php"
-                ]
+                ],
+                "psr-4": {
+                    "Facade\\FlareClient\\": "src"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -7509,16 +7515,16 @@
         },
         {
             "name": "facade/ignition",
-            "version": "2.17.4",
+            "version": "2.17.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/facade/ignition.git",
-                "reference": "95c80bd35ee6858e9e1439b2f6a698295eeb2070"
+                "reference": "1d71996f83c9a5a7807331b8986ac890352b7a0c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/facade/ignition/zipball/95c80bd35ee6858e9e1439b2f6a698295eeb2070",
-                "reference": "95c80bd35ee6858e9e1439b2f6a698295eeb2070",
+                "url": "https://api.github.com/repos/facade/ignition/zipball/1d71996f83c9a5a7807331b8986ac890352b7a0c",
+                "reference": "1d71996f83c9a5a7807331b8986ac890352b7a0c",
                 "shasum": ""
             },
             "require": {
@@ -7558,12 +7564,12 @@
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Facade\\Ignition\\": "src"
-                },
                 "files": [
                     "src/helpers.php"
-                ]
+                ],
+                "psr-4": {
+                    "Facade\\Ignition\\": "src"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -7583,7 +7589,7 @@
                 "issues": "https://github.com/facade/ignition/issues",
                 "source": "https://github.com/facade/ignition"
             },
-            "time": "2021-12-27T15:11:24+00:00"
+            "time": "2022-02-23T18:31:24+00:00"
         },
         {
             "name": "facade/ignition-contracts",
@@ -7829,16 +7835,16 @@
         },
         {
             "name": "laravel/sail",
-            "version": "v1.13.1",
+            "version": "v1.14.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/sail.git",
-                "reference": "b9749028732eca8080c26d01cd88a2f3549c2e3e"
+                "reference": "0ea5d683af4d189071efcdb9e83946c10dab82c3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/sail/zipball/b9749028732eca8080c26d01cd88a2f3549c2e3e",
-                "reference": "b9749028732eca8080c26d01cd88a2f3549c2e3e",
+                "url": "https://api.github.com/repos/laravel/sail/zipball/0ea5d683af4d189071efcdb9e83946c10dab82c3",
+                "reference": "0ea5d683af4d189071efcdb9e83946c10dab82c3",
                 "shasum": ""
             },
             "require": {
@@ -7885,29 +7891,30 @@
                 "issues": "https://github.com/laravel/sail/issues",
                 "source": "https://github.com/laravel/sail"
             },
-            "time": "2022-01-20T15:31:25+00:00"
+            "time": "2022-06-09T07:10:28+00:00"
         },
         {
             "name": "maximebf/debugbar",
-            "version": "v1.17.3",
+            "version": "v1.18.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/maximebf/php-debugbar.git",
-                "reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c"
+                "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/e8ac3499af0ea5b440908e06cc0abe5898008b3c",
-                "reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c",
+                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6",
+                "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.1|^8",
                 "psr/log": "^1|^2|^3",
-                "symfony/var-dumper": "^2.6|^3|^4|^5"
+                "symfony/var-dumper": "^2.6|^3|^4|^5|^6"
             },
             "require-dev": {
-                "phpunit/phpunit": "^7.5.20 || ^9.4.2"
+                "phpunit/phpunit": "^7.5.20 || ^9.4.2",
+                "twig/twig": "^1.38|^2.7|^3.0"
             },
             "suggest": {
                 "kriswallsmith/assetic": "The best way to manage assets",
@@ -7948,9 +7955,9 @@
             ],
             "support": {
                 "issues": "https://github.com/maximebf/php-debugbar/issues",
-                "source": "https://github.com/maximebf/php-debugbar/tree/v1.17.3"
+                "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0"
             },
-            "time": "2021-10-19T12:33:27+00:00"
+            "time": "2021-12-27T18:49:48+00:00"
         },
         {
             "name": "mockery/mockery",
@@ -8026,28 +8033,29 @@
         },
         {
             "name": "myclabs/deep-copy",
-            "version": "1.10.2",
+            "version": "1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/myclabs/DeepCopy.git",
-                "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
+                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
-                "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.1 || ^8.0"
             },
-            "replace": {
-                "myclabs/deep-copy": "self.version"
+            "conflict": {
+                "doctrine/collections": "<1.6.8",
+                "doctrine/common": "<2.13.3 || >=3,<3.2.2"
             },
             "require-dev": {
-                "doctrine/collections": "^1.0",
-                "doctrine/common": "^2.6",
-                "phpunit/phpunit": "^7.1"
+                "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": {
@@ -8072,7 +8080,7 @@
             ],
             "support": {
                 "issues": "https://github.com/myclabs/DeepCopy/issues",
-                "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
             },
             "funding": [
                 {
@@ -8080,7 +8088,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2020-11-13T09:40:50+00:00"
+            "time": "2022-03-03T13:19:32+00:00"
         },
         {
             "name": "nunomaduro/collision",
@@ -8231,16 +8239,16 @@
         },
         {
             "name": "phar-io/version",
-            "version": "3.1.1",
+            "version": "3.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phar-io/version.git",
-                "reference": "15a90844ad40f127afd244c0cad228de2a80052a"
+                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a",
-                "reference": "15a90844ad40f127afd244c0cad228de2a80052a",
+                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
                 "shasum": ""
             },
             "require": {
@@ -8276,9 +8284,9 @@
             "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.1.1"
+                "source": "https://github.com/phar-io/version/tree/3.2.1"
             },
-            "time": "2022-02-07T21:56:48+00:00"
+            "time": "2022-02-21T01:04:05+00:00"
         },
         {
             "name": "phpdocumentor/reflection-common",
@@ -8392,16 +8400,16 @@
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "1.6.0",
+            "version": "1.6.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706"
+                "reference": "77a32518733312af16a44300404e945338981de3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706",
-                "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
+                "reference": "77a32518733312af16a44300404e945338981de3",
                 "shasum": ""
             },
             "require": {
@@ -8436,9 +8444,9 @@
             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
             "support": {
                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0"
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
             },
-            "time": "2022-01-04T19:58:01+00:00"
+            "time": "2022-03-15T21:29:03+00:00"
         },
         {
             "name": "phpspec/prophecy",
@@ -8509,16 +8517,16 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "9.2.10",
+            "version": "9.2.15",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687"
+                "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687",
-                "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f",
+                "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f",
                 "shasum": ""
             },
             "require": {
@@ -8574,7 +8582,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10"
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15"
             },
             "funding": [
                 {
@@ -8582,7 +8590,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-12-05T09:12:13+00:00"
+            "time": "2022-03-07T09:28:20+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
@@ -8827,16 +8835,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "9.5.13",
+            "version": "9.5.20",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "597cb647654ede35e43b137926dfdfef0fb11743"
+                "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743",
-                "reference": "597cb647654ede35e43b137926dfdfef0fb11743",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba",
+                "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba",
                 "shasum": ""
             },
             "require": {
@@ -8852,7 +8860,7 @@
                 "phar-io/version": "^3.0.2",
                 "php": ">=7.3",
                 "phpspec/prophecy": "^1.12.1",
-                "phpunit/php-code-coverage": "^9.2.7",
+                "phpunit/php-code-coverage": "^9.2.13",
                 "phpunit/php-file-iterator": "^3.0.5",
                 "phpunit/php-invoker": "^3.1.1",
                 "phpunit/php-text-template": "^2.0.3",
@@ -8866,7 +8874,7 @@
                 "sebastian/global-state": "^5.0.1",
                 "sebastian/object-enumerator": "^4.0.3",
                 "sebastian/resource-operations": "^3.0.3",
-                "sebastian/type": "^2.3.4",
+                "sebastian/type": "^3.0",
                 "sebastian/version": "^3.0.2"
             },
             "require-dev": {
@@ -8914,7 +8922,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20"
             },
             "funding": [
                 {
@@ -8926,7 +8934,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-01-24T07:33:35+00:00"
+            "time": "2022-04-01T12:37:26+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -9294,16 +9302,16 @@
         },
         {
             "name": "sebastian/environment",
-            "version": "5.1.3",
+            "version": "5.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "388b6ced16caa751030f6a69e588299fa09200ac"
+                "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac",
-                "reference": "388b6ced16caa751030f6a69e588299fa09200ac",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7",
+                "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7",
                 "shasum": ""
             },
             "require": {
@@ -9345,7 +9353,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/environment/issues",
-                "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3"
+                "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
             },
             "funding": [
                 {
@@ -9353,7 +9361,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-09-28T05:52:38+00:00"
+            "time": "2022-04-03T09:37:03+00:00"
         },
         {
             "name": "sebastian/exporter",
@@ -9434,16 +9442,16 @@
         },
         {
             "name": "sebastian/global-state",
-            "version": "5.0.3",
+            "version": "5.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/global-state.git",
-                "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49"
+                "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49",
-                "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+                "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
                 "shasum": ""
             },
             "require": {
@@ -9486,7 +9494,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/global-state/issues",
-                "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3"
+                "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
             },
             "funding": [
                 {
@@ -9494,7 +9502,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-06-11T13:31:12+00:00"
+            "time": "2022-02-14T08:28:10+00:00"
         },
         {
             "name": "sebastian/lines-of-code",
@@ -9785,28 +9793,28 @@
         },
         {
             "name": "sebastian/type",
-            "version": "2.3.4",
+            "version": "3.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/type.git",
-                "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
+                "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
-                "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
+                "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
                 "shasum": ""
             },
             "require": {
                 "php": ">=7.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^9.5"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.3-dev"
+                    "dev-master": "3.0-dev"
                 }
             },
             "autoload": {
@@ -9829,7 +9837,7 @@
             "homepage": "https://github.com/sebastianbergmann/type",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/type/issues",
-                "source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
+                "source": "https://github.com/sebastianbergmann/type/tree/3.0.0"
             },
             "funding": [
                 {
@@ -9837,7 +9845,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-06-15T12:49:02+00:00"
+            "time": "2022-03-15T09:54:48+00:00"
         },
         {
             "name": "sebastian/version",
@@ -9894,16 +9902,16 @@
         },
         {
             "name": "symfony/debug",
-            "version": "v4.4.37",
+            "version": "v4.4.41",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git",
-                "reference": "5de6c6e7f52b364840e53851c126be4d71e60470"
+                "reference": "6637e62480b60817b9a6984154a533e8e64c6bd5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug/zipball/5de6c6e7f52b364840e53851c126be4d71e60470",
-                "reference": "5de6c6e7f52b364840e53851c126be4d71e60470",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/6637e62480b60817b9a6984154a533e8e64c6bd5",
+                "reference": "6637e62480b60817b9a6984154a533e8e64c6bd5",
                 "shasum": ""
             },
             "require": {
@@ -9942,7 +9950,7 @@
             "description": "Provides tools to ease debugging PHP code",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/debug/tree/v4.4.37"
+                "source": "https://github.com/symfony/debug/tree/v4.4.41"
             },
             "funding": [
                 {
@@ -9958,7 +9966,8 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:41:36+00:00"
+            "abandoned": "symfony/error-handler",
+            "time": "2022-04-12T15:19:55+00:00"
         },
         {
             "name": "theseer/tokenizer",

From 8f38b9e023c3b1f17b93fc5372cfc4423c069c33 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:32:00 +0200
Subject: [PATCH 002/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Migration?=
 =?UTF-8?q?=20->=20Column=20Billing=20Period?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ..._092704_add_billing_period_to_products.php | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 database/migrations/2022_06_16_092704_add_billing_period_to_products.php

diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
new file mode 100644
index 000000000..4018fb473
--- /dev/null
+++ b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+class AddBillingPeriodToProducts extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->string('billing_period')->default("hourly");
+        });
+
+        DB::statement('UPDATE products SET billing_period="hourly"');
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->dropColumn('billing_period');
+        });
+    }
+}

From 950278c9487c540ea9e70601c4afa8f690d42210 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:55:34 +0200
Subject: [PATCH 003/514] =?UTF-8?q?fix:=20=E2=9C=A8=20Updated=20Migration?=
 =?UTF-8?q?=20to=20calculate=20hourly=20price=20from=20existing=20products?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2022_06_16_092704_add_billing_period_to_products.php  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
index 4018fb473..708e6e5e4 100644
--- a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
+++ b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
@@ -19,6 +19,14 @@ public function up()
         });
 
         DB::statement('UPDATE products SET billing_period="hourly"');
+
+        $products = DB::table('products')->get();
+        foreach ($products as $product) {
+            $price = $product->price;
+            $price = $price / 30 / 24;
+            DB::table('products')->where('id', $product->id)->update(['price' => $price]);
+        }
+
     }
 
     /**

From 8383fa03aacb375588a21cbe0b42ad2720fa8ced Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:56:05 +0200
Subject: [PATCH 004/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Added=20Migration?=
 =?UTF-8?q?=20->=20Updated=20user=20credits=20column=20to=20be=20decimal?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...6_16_094402_update_user_price_datatype.php | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 database/migrations/2022_06_16_094402_update_user_price_datatype.php

diff --git a/database/migrations/2022_06_16_094402_update_user_price_datatype.php b/database/migrations/2022_06_16_094402_update_user_price_datatype.php
new file mode 100644
index 000000000..9b4abb9e7
--- /dev/null
+++ b/database/migrations/2022_06_16_094402_update_user_price_datatype.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class UpdateUserPriceDatatype extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->decimal('credits', 20, 10)->default(0)->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->unsignedFloat('credits')->default(250)->change();
+        });
+    }
+}

From d7830eeb41b4218da25b46e807810de17964e513 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:59:17 +0200
Subject: [PATCH 005/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Migration?=
 =?UTF-8?q?=20->=20last=20billed=20field=20to=20servers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...95818_add_last_billed_field_to_servers.php | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php

diff --git a/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php b/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php
new file mode 100644
index 000000000..6b05f3a5b
--- /dev/null
+++ b/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php
@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+class AddLastBilledFieldToServers extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->dateTime('last_billed')->default(DB::raw('CURRENT_TIMESTAMP'))->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->dropColumn('last_billed');
+        });
+    }
+}

From b726326e99e00cbfbefb0e85625a075013c9e984 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:01:53 +0200
Subject: [PATCH 006/514] =?UTF-8?q?feat:=20=F0=9F=93=9D=20Updated=20Produc?=
 =?UTF-8?q?tSeeder?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 database/seeders/Seeds/ProductSeeder.php | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/database/seeders/Seeds/ProductSeeder.php b/database/seeders/Seeds/ProductSeeder.php
index 7664dc867..a6035c009 100644
--- a/database/seeders/Seeds/ProductSeeder.php
+++ b/database/seeders/Seeds/ProductSeeder.php
@@ -16,29 +16,32 @@ public function run()
     {
         Product::create([
             'name' => 'Starter',
-            'description' => '64MB Ram, 1GB Disk, 1 Database, 140 credits monthly',
+            'description' => '64MB Ram, 1GB Disk, 1 Database, 140 credits hourly',
             'price' => 140,
             'memory' => 64,
             'disk' => 1000,
-            'databases' => 1
+            'databases' => 1,
+            'billing_period' => 'hourly'
         ]);
 
         Product::create([
             'name' => 'Standard',
-            'description' => '128MB Ram, 2GB Disk, 2 Database,  210 credits monthly',
+            'description' => '128MB Ram, 2GB Disk, 2 Database,  210 credits hourly',
             'price' => 210,
             'memory' => 128,
             'disk' => 2000,
-            'databases' => 2
+            'databases' => 2,
+            'billing_period' => 'hourly'
         ]);
 
         Product::create([
             'name' => 'Advanced',
-            'description' => '256MB Ram, 5GB Disk, 5 Database,  280 credits monthly',
+            'description' => '256MB Ram, 5GB Disk, 5 Database,  280 credits hourly',
             'price' => 280,
             'memory' => 256,
             'disk' => 5000,
-            'databases' => 5
+            'databases' => 5,
+            'billing_period' => 'hourly'
         ]);
     }
 }

From 87bca5c52bbda3624df52f77055789fb824f8cb9 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:04:52 +0200
Subject: [PATCH 007/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20billing=5Fp?=
 =?UTF-8?q?eriod=20to=20validation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/Admin/ProductController.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 6b855f9fe..d86f7873f 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -73,6 +73,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
+            "billing_period" => "required|in:hourly,daily,monthly",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
@@ -139,6 +140,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
+            "billing_period" => "required|in:hourly,daily,monthly",
         ]);
 
         $disabled = !is_null($request->input('disabled'));

From 4581b018b0bf57a527b813f4e1f902c84ebcbb86 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:27:53 +0200
Subject: [PATCH 008/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20billing=20p?=
 =?UTF-8?q?eriod=20to=20edit,=20create=20and=20show=20of=20products?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../views/admin/products/create.blade.php     | 55 ++++++++++++++-----
 resources/views/admin/products/edit.blade.php | 54 +++++++++++++-----
 .../views/admin/products/index.blade.php      |  2 +
 3 files changed, 85 insertions(+), 26 deletions(-)

diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index a4fb0dc1d..2470bb175 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -116,6 +116,20 @@ class="form-control @error('swap') is-invalid @enderror"
                                             @enderror
                                         </div>
 
+                                        <div class="form-group">
+                                            <label for="allocations">{{__('Allocations')}}</label>
+                                            <input value="{{$product->allocations ?? old('allocations') ?? 0}}"
+                                                   id="allocations" name="allocations"
+                                                   type="number"
+                                                   class="form-control @error('allocations') is-invalid @enderror"
+                                                   required="required">
+                                            @error('allocations')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
+
                                         <div class="form-group">
                                             <label for="description">{{__('Description')}} <i data-toggle="popover"
                                                                                               data-trigger="hover"
@@ -148,6 +162,34 @@ class="form-control @error('disk') is-invalid @enderror"
                                             @enderror
                                         </div>
 
+                                        <div class="form-group">
+                                            <label for="billing_period">{{__('Billing Period')}} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{__('Period when the user will be charged for the given price')}}"
+                                                    class="fas fa-info-circle"></i></label>
+
+                                            <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
+                                                autocomplete="off" @error('billing_period') is-invalid @enderror>
+                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
+                                                    @endif>
+                                                        {{__('Hourly')}}
+                                                    </option>
+                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
+                                                    @endif>
+                                                        {{__('Daily')}}
+                                                    </option>
+                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
+                                                     @endif>
+                                                        {{__('Monthly')}}
+                                                    </option>
+                                            </select>
+                                            @error('billing_period')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
+
                                         <div class="form-group">
                                             <label for="minimum_credits">{{__('Minimum')}} {{ CREDITS_DISPLAY_NAME }} <i
                                                     data-toggle="popover" data-trigger="hover"
@@ -205,19 +247,6 @@ class="form-control @error('backups') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
-                                        <div class="form-group">
-                                            <label for="allocations">{{__('Allocations')}}</label>
-                                            <input value="{{$product->allocations ?? old('allocations') ?? 0}}"
-                                                   id="allocations" name="allocations"
-                                                   type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
-                                            @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
-                                            @enderror
-                                        </div>
                                     </div>
                                 </div>
 
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php
index 87622bd80..651e44923 100644
--- a/resources/views/admin/products/edit.blade.php
+++ b/resources/views/admin/products/edit.blade.php
@@ -122,7 +122,18 @@ class="form-control @error('swap') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
-
+                                        <div class="form-group">
+                                            <label for="allocations">{{__('Allocations')}}</label>
+                                            <input value="{{ $product->allocations }}" id="allocations"
+                                                   name="allocations" type="number"
+                                                   class="form-control @error('allocations') is-invalid @enderror"
+                                                   required="required">
+                                            @error('allocations')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
                                         <div class="form-group">
                                             <label for="description">{{__('Description')}} <i data-toggle="popover"
                                                                                               data-trigger="hover"
@@ -152,6 +163,35 @@ class="form-control @error('disk') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
+
+                                        <div class="form-group">
+                                            <label for="billing_period">{{__('Billing Period')}} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{__('Period when the user will be charged for the given price')}}"
+                                                    class="fas fa-info-circle"></i></label>
+
+                                            <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
+                                                autocomplete="off" @error('billing_period') is-invalid @enderror>
+                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
+                                                    @endif>
+                                                        {{__('Hourly')}}
+                                                    </option>
+                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
+                                                    @endif>
+                                                        {{__('Daily')}}
+                                                    </option>
+                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
+                                                     @endif>
+                                                        {{__('Monthly')}}
+                                                    </option>
+                                            </select>
+                                            @error('billing_period')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
+
                                         <div class="form-group">
                                             <label for="minimum_credits">{{__('Minimum')}} {{ CREDITS_DISPLAY_NAME }} <i
                                                     data-toggle="popover" data-trigger="hover"
@@ -202,18 +242,6 @@ class="form-control @error('backups') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
-                                        <div class="form-group">
-                                            <label for="allocations">{{__('Allocations')}}</label>
-                                            <input value="{{ $product->allocations }}" id="allocations"
-                                                   name="allocations" type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
-                                            @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
-                                            @enderror
-                                        </div>
                                     </div>
                                 </div>
 
diff --git a/resources/views/admin/products/index.blade.php b/resources/views/admin/products/index.blade.php
index b7c241b3e..25cea9a09 100644
--- a/resources/views/admin/products/index.blade.php
+++ b/resources/views/admin/products/index.blade.php
@@ -44,6 +44,7 @@ class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
                             <th>{{__('Active')}}</th>
                             <th>{{__('Name')}}</th>
                             <th>{{__('Price')}}</th>
+                            <th>{{__('Billing period')}}</th>
                             <th>{{__('Memory')}}</th>
                             <th>{{__('Cpu')}}</th>
                             <th>{{__('Swap')}}</th>
@@ -91,6 +92,7 @@ function submitResult() {
                     {data: "disabled"},
                     {data: "name"},
                     {data: "price"},
+                    {data: "billing_period"},
                     {data: "memory"},
                     {data: "cpu"},
                     {data: "swap"},

From 5c37dbcc51e3103fddb0f8896aaf77c19a56b35a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:36:01 +0200
Subject: [PATCH 009/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20billing=20p?=
 =?UTF-8?q?eriod=20to=20server=20creation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/create.blade.php | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/resources/views/servers/create.blade.php b/resources/views/servers/create.blade.php
index 775ed5ac9..26f55848f 100644
--- a/resources/views/servers/create.blade.php
+++ b/resources/views/servers/create.blade.php
@@ -201,6 +201,12 @@ class="custom-select">
                                                         ({{ __('ports') }})</span>
                                                     <span class="d-inline-block" x-text="product.allocations"></span>
                                                 </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-clock"></i>
+                                                        {{ __('Billing Period') }}</span>
+
+                                                    <span class="d-inline-block" x-text="product.billing_period"></span>
+                                                </li>
                                             </ul>
                                         </div>
                                         <div class="mt-2 mb-2">
@@ -210,8 +216,7 @@ class="custom-select">
                                     </div>
                                     <div class="mt-auto border rounded border-secondary">
                                         <div class="d-flex justify-content-between p-2">
-                                            <span class="d-inline-block mr-4">
-                                                {{ __('Price') }}:
+                                            <span class="d-inline-block mr-4" x-text="'{{ __('Price') }}' + ' (' + product.billing_period + ')'">
                                             </span>
                                             <span class="d-inline-block"
                                                 x-text="product.price + ' {{ CREDITS_DISPLAY_NAME }}'"></span>

From 9e8bd0a2d3097b68cd9780d04971f0603e21982a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 14:54:06 +0200
Subject: [PATCH 010/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20weekly=20to?=
 =?UTF-8?q?=20billing=5Fperiod=20options?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/Admin/ProductController.php | 4 ++--
 resources/views/admin/products/create.blade.php  | 4 ++++
 resources/views/admin/products/edit.blade.php    | 4 ++++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index d86f7873f..772abc67a 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -73,7 +73,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
@@ -140,7 +140,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index 2470bb175..0b9389a45 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -177,6 +177,10 @@ class="fas fa-info-circle"></i></label>
                                                     <option value="daily" @if ($product->billing_period  == 'daily') selected
                                                     @endif>
                                                         {{__('Daily')}}
+                                                    </option>
+                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
+                                                    @endif>
+                                                        {{__('Weekly')}}
                                                     </option>
                                                      <option value="monthly" @if ($product->billing_period  == 'monthly') selected
                                                      @endif>
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php
index 651e44923..3294b1657 100644
--- a/resources/views/admin/products/edit.blade.php
+++ b/resources/views/admin/products/edit.blade.php
@@ -179,6 +179,10 @@ class="fas fa-info-circle"></i></label>
                                                     <option value="daily" @if ($product->billing_period  == 'daily') selected
                                                     @endif>
                                                         {{__('Daily')}}
+                                                    </option>
+                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
+                                                    @endif>
+                                                        {{__('Weekly')}}
                                                     </option>
                                                      <option value="monthly" @if ($product->billing_period  == 'monthly') selected
                                                      @endif>

From fb23f43f884283d66c401f2bb8d525475fd765e3 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 14:54:42 +0200
Subject: [PATCH 011/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20ChargeServe?=
 =?UTF-8?q?rs=20command=20&=20updated=20laravel=20schedule=20command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php | 122 +++++++++++++++++++++++++
 app/Console/Kernel.php                 |   5 +-
 2 files changed, 125 insertions(+), 2 deletions(-)
 create mode 100644 app/Console/Commands/ChargeServers.php

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
new file mode 100644
index 000000000..678ab4b70
--- /dev/null
+++ b/app/Console/Commands/ChargeServers.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\Server;
+use App\Notifications\ServersSuspendedNotification;
+use Illuminate\Console\Command;
+
+class ChargeServers extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'servers:charge';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Charge all users with severs that are due to be charged';
+
+        /**
+     * A list of users that have to be notified
+     * @var array
+     */
+    protected $usersToNotify = [];
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        Server::whereNull('suspended')->with('users', 'products')->chunk(10, function ($servers) {
+            /** @var Server $server */
+            foreach ($servers as $server) {
+                /** @var Product $product */
+                $product = $server->product;
+                /** @var User $user */
+                $user = $server->user;
+
+                $billing_period = $product->billing_period;
+
+                // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
+                $newBillingDate = null;
+                switch($billing_period) {
+                    case 'monthly':
+                        $newBillingDate = $server->last_billed->addMonth();
+                        break;
+                    case 'weekly':
+                        $newBillingDate = $server->last_billed->addYear();
+                        break;
+                    case 'daily':
+                        $newBillingDate = $server->last_billed->addDay();
+                        break;
+                    default:
+                        $newBillingDate = $server->last_billed->addHour();
+                        break;
+                };
+                if (!($newBillingDate <= now())) return;
+
+                // check if user has enough credits to charge the server
+                if ($user->credits < $product->price) {
+                    try {
+                        #suspend server
+                        $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
+                        $server->suspend();
+
+                        #add user to notify list
+                        if (!in_array($user, $this->usersToNotify)) {
+                            array_push($this->usersToNotify, $user);
+                        }
+                    } catch (\Exception $exception) {
+                        $this->error($exception->getMessage());
+                    }
+                    return;
+                }
+
+                // charge credits to user
+                $this->line("<fg=blue>{$user->name}</> Current credits: <fg=green>{$user->credits}</> Credits to be removed: <fg=red>{$product->price}</>");
+                $user->decrement('credits', $product->price);
+
+                // update server last_billed date
+                $server->last_billed = $newBillingDate;
+            }
+
+            return $this->notifyUsers();
+        });
+    }
+
+    /**
+     * @return bool
+     */
+    public function notifyUsers()
+    {
+        if (!empty($this->usersToNotify)) {
+            /** @var User $user */
+            foreach ($this->usersToNotify as $user) {
+                $this->line("<fg=yellow>Notified user:</> <fg=blue>{$user->name}</>");
+                $user->notify(new ServersSuspendedNotification());
+            }
+        }
+
+        #reset array
+        $this->usersToNotify = array();
+        return true;
+    }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index fe25d44cc..9a56bf909 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -14,7 +14,8 @@ class Kernel extends ConsoleKernel
      * @var array
      */
     protected $commands = [
-        //
+        Commands\ChargeCreditsCommand::class,
+        Commands\ChargeServers::class,
     ];
 
     /**
@@ -25,7 +26,7 @@ class Kernel extends ConsoleKernel
      */
     protected function schedule(Schedule $schedule)
     {
-        $schedule->command('credits:charge')->hourly();
+        $schedule->command('servers:charge')->everyMinute();
 
         //log cronjob activity
         $schedule->call(function () {

From 6c9334320004071d0e935bf08a8af88cca09c537 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 15:32:42 +0200
Subject: [PATCH 012/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20decimal?=
 =?UTF-8?q?=20input=20steps=20to=20number=20inputs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/admin/products/create.blade.php | 1 +
 resources/views/admin/products/edit.blade.php   | 6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index 0b9389a45..4f79bb20c 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -66,6 +66,7 @@ class="form-control @error('name') is-invalid @enderror"
                                             <label for="price">{{__('Price in')}} {{CREDITS_DISPLAY_NAME}}</label>
                                             <input value="{{$product->price ??  old('price')}}" id="price" name="price"
                                                    type="number"
+                                                   step="0.0001"
                                                    class="form-control @error('price') is-invalid @enderror"
                                                    required="required">
                                             @error('price')
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php
index 3294b1657..cedbc72c8 100644
--- a/resources/views/admin/products/edit.blade.php
+++ b/resources/views/admin/products/edit.blade.php
@@ -75,8 +75,10 @@ class="form-control @error('name') is-invalid @enderror"
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="price">{{__('Price in')}} {{ CREDITS_DISPLAY_NAME }}</label>
-                                            <input value="{{ $product->price }}" id="price" name="price" type="number"
+                                            <label for="price">{{__('Price in')}} {{CREDITS_DISPLAY_NAME}}</label>
+                                            <input value="{{$product->price}}" id="price" name="price"
+                                                   type="number"
+                                                   step="0.0001"
                                                    class="form-control @error('price') is-invalid @enderror"
                                                    required="required">
                                             @error('price')

From d7c0c26f35ca6b494e8fd0c6175cce399d9d63e3 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 15:33:44 +0200
Subject: [PATCH 013/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Renamed=20Migrati?=
 =?UTF-8?q?on=20&=20changed=20precision=20on=20decimals=20to=20more=20reas?=
 =?UTF-8?q?onable=20number?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2022_06_16_092704_add_billing_period_to_products.php     | 5 +++++
 ...hp => 2022_06_16_094402_update_user_credits_datatype.php} | 5 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)
 rename database/migrations/{2022_06_16_094402_update_user_price_datatype.php => 2022_06_16_094402_update_user_credits_datatype.php} (82%)

diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
index 708e6e5e4..ceed9362f 100644
--- a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
+++ b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
@@ -16,6 +16,9 @@ public function up()
     {
         Schema::table('products', function (Blueprint $table) {
             $table->string('billing_period')->default("hourly");
+            $table->decimal('price', 15, 4)->change();
+            $table->decimal('minimum_credits', 15, 4)->change();
+
         });
 
         DB::statement('UPDATE products SET billing_period="hourly"');
@@ -38,6 +41,8 @@ public function down()
     {
         Schema::table('products', function (Blueprint $table) {
             $table->dropColumn('billing_period');
+            $table->decimal('price', 10, 0)->change();
+            $table->float('minimum_credits')->change();
         });
     }
 }
diff --git a/database/migrations/2022_06_16_094402_update_user_price_datatype.php b/database/migrations/2022_06_16_094402_update_user_credits_datatype.php
similarity index 82%
rename from database/migrations/2022_06_16_094402_update_user_price_datatype.php
rename to database/migrations/2022_06_16_094402_update_user_credits_datatype.php
index 9b4abb9e7..ed5922e86 100644
--- a/database/migrations/2022_06_16_094402_update_user_price_datatype.php
+++ b/database/migrations/2022_06_16_094402_update_user_credits_datatype.php
@@ -4,7 +4,7 @@
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Support\Facades\Schema;
 
-class UpdateUserPriceDatatype extends Migration
+class UpdateUserCreditsDatatype extends Migration
 {
     /**
      * Run the migrations.
@@ -14,7 +14,7 @@ class UpdateUserPriceDatatype extends Migration
     public function up()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->decimal('credits', 20, 10)->default(0)->change();
+            $table->decimal('credits', 15, 4)->default(0)->change();
         });
     }
 
@@ -27,6 +27,7 @@ public function down()
     {
         Schema::table('users', function (Blueprint $table) {
             $table->unsignedFloat('credits')->default(250)->change();
+
         });
     }
 }

From a26f6dd137298e7ed9dbf19624e06ee140c9b961 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 16:15:57 +0200
Subject: [PATCH 014/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20last=5Fbill?=
 =?UTF-8?q?ed=20to=20server=20model=20&=20always=20charge=20first=20&=20fi?=
 =?UTF-8?q?xed=20Charge=20Server=20command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php    | 24 +++++++++++++++--------
 app/Http/Controllers/ServerController.php | 12 ++++++------
 app/Models/Server.php                     |  1 +
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 678ab4b70..877cb8a5a 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -4,7 +4,9 @@
 
 use App\Models\Server;
 use App\Notifications\ServersSuspendedNotification;
+use Carbon\Carbon;
 use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
 
 class ChargeServers extends Command
 {
@@ -45,7 +47,7 @@ public function __construct()
      */
     public function handle()
     {
-        Server::whereNull('suspended')->with('users', 'products')->chunk(10, function ($servers) {
+        Server::whereNull('suspended')->with('user', 'product')->chunk(10, function ($servers) {
             /** @var Server $server */
             foreach ($servers as $server) {
                 /** @var Product $product */
@@ -55,23 +57,29 @@ public function handle()
 
                 $billing_period = $product->billing_period;
 
+
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
                 switch($billing_period) {
                     case 'monthly':
-                        $newBillingDate = $server->last_billed->addMonth();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
                     case 'weekly':
-                        $newBillingDate = $server->last_billed->addYear();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addYear();
                         break;
                     case 'daily':
-                        $newBillingDate = $server->last_billed->addDay();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addDay();
                         break;
+                    case 'hourly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addHour();
                     default:
-                        $newBillingDate = $server->last_billed->addHour();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addHour();
                         break;
                 };
-                if (!($newBillingDate <= now())) return;
+
+                if (!($newBillingDate->isPast())) {
+                    continue;
+                }
 
                 // check if user has enough credits to charge the server
                 if ($user->credits < $product->price) {
@@ -94,8 +102,8 @@ public function handle()
                 $this->line("<fg=blue>{$user->name}</> Current credits: <fg=green>{$user->credits}</> Credits to be removed: <fg=red>{$product->price}</>");
                 $user->decrement('credits', $product->price);
 
-                // update server last_billed date
-                $server->last_billed = $newBillingDate;
+                // update server last_billed date in db
+                DB::table('servers')->where('id', $server->id)->update(['last_billed' => $newBillingDate]);
             }
 
             return $this->notifyUsers();
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index c1c0a33ab..45d72569c 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -11,6 +11,7 @@
 use App\Models\Server;
 use App\Models\Settings;
 use App\Notifications\ServerCreationError;
+use Carbon\Carbon;
 use Exception;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Client\Response;
@@ -151,6 +152,7 @@ public function store(Request $request)
         $server = $request->user()->servers()->create([
             'name'       => $request->input('name'),
             'product_id' => $request->input('product'),
+            'last_billed' => Carbon::now()->toDateTimeString(),
         ]);
 
         //get free allocation ID
@@ -165,14 +167,12 @@ public function store(Request $request)
         //update server with pterodactyl_id
         $server->update([
             'pterodactyl_id' => $serverAttributes['id'],
-            'identifier'     => $serverAttributes['identifier']
+            'identifier'     => $serverAttributes['identifier'],
+
         ]);
 
-        if (config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
-            if ($request->user()->credits >= $server->product->getHourlyPrice()) {
-                $request->user()->decrement('credits', $server->product->getHourlyPrice());
-            }
-        }
+        // Charge first billing cycle
+        $request->user()->decrement('credits', $server->product->price);
 
         return redirect()->route('servers.index')->with('success', __('Server created'));
     }
diff --git a/app/Models/Server.php b/app/Models/Server.php
index 34c992ba7..82770a30c 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -47,6 +47,7 @@ class Server extends Model
         "identifier",
         "product_id",
         "pterodactyl_id",
+        "last_billed"
     ];
 
     /**

From cad41ffb0a8359e1be0990c2e2b96c42334424a0 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 16:18:27 +0200
Subject: [PATCH 015/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Update=20last=5Fbil?=
 =?UTF-8?q?led=20to=20current=20time=20on=20unsuspend=20server?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Models/Server.php | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/app/Models/Server.php b/app/Models/Server.php
index 82770a30c..fa6d17caf 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -3,6 +3,7 @@
 namespace App\Models;
 
 use App\Classes\Pterodactyl;
+use Carbon\Carbon;
 use Exception;
 use GuzzleHttp\Promise\PromiseInterface;
 use Hidehalo\Nanoid\Client;
@@ -124,10 +125,12 @@ public function unSuspend()
 
         if ($response->successful()) {
             $this->update([
-                'suspended' => null
+                'suspended' => null,
+                'last_billed' => Carbon::now()->toDateTimeString(),
             ]);
         }
 
+
         return $this;
     }
 

From 570b0b014f07fc3890ce0341b64583c56b942a10 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 19:03:59 +0200
Subject: [PATCH 016/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20ChargeSe?=
 =?UTF-8?q?rver=20Command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 877cb8a5a..769909c32 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -65,7 +65,7 @@ public function handle()
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
                     case 'weekly':
-                        $newBillingDate = Carbon::parse($server->last_billed)->addYear();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addWeek();
                         break;
                     case 'daily':
                         $newBillingDate = Carbon::parse($server->last_billed)->addDay();

From 609041a96799e42705ef1aa12244951171601e12 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sat, 18 Jun 2022 23:41:40 +0200
Subject: [PATCH 017/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20different?=
 =?UTF-8?q?=20billing=20periods=20to=20servers=20overview=20page?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 29 ++++++++++++-------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 72187653a..517c3f1ea 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -127,22 +127,21 @@ class="fas fa-info-circle"></i>
                                             ({{ CREDITS_DISPLAY_NAME }})
                                         </span>
                                     </div>
-                                    <div class="col-8">
-                                        <div class="row">
-                                            <div class="col-6  text-center">
-                                                <div class="text-muted">{{ __('per Hour') }}</div>
-                                                <span>
-                                                    {{ number_format($server->product->getHourlyPrice(), 2, '.', '') }}
-                                                </span>
+                                    <div class="col-8 text-center">
+                                        <div class="text-muted">
+                                        @if($server->product->billing_period == 'monthly')
+                                            {{ __('per Month') }}
+                                        @elseif($server->product->billing_period == 'weekly')
+                                            {{ __('per Week') }}
+                                        @elseif($server->product->billing_period == 'daily')
+                                            {{ __('per Day') }}
+                                        @elseif($server->product->billing_period == 'hourly')
+                                            {{ __('per Hour') }}
+                                        @endif
                                             </div>
-                                            <div class="col-6  text-center">
-                                                <div class="text-muted">{{ __('per Month') }}
-                                                </div>
-                                                <span>
-                                                    {{ $server->product->getHourlyPrice() * 24 * 30 }}
-                                                </span>
-                                            </div>
-                                        </div>
+                                        <span>
+                                            {{ $server->product->price }}
+                                        </span>
                                     </div>
                                 </div>
                             </div>

From b9b860b863059c717fa714fb81e25439189f535a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sat, 18 Jun 2022 23:43:58 +0200
Subject: [PATCH 018/514] =?UTF-8?q?fix:=20=F0=9F=94=A5=20Removed=20charge?=
 =?UTF-8?q?=20first=20hour=20at=20creation=20->=20not=20in=20use=20anymore?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../views/admin/settings/tabs/system.blade.php   | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/resources/views/admin/settings/tabs/system.blade.php b/resources/views/admin/settings/tabs/system.blade.php
index aece6bee0..3fd3e67ed 100644
--- a/resources/views/admin/settings/tabs/system.blade.php
+++ b/resources/views/admin/settings/tabs/system.blade.php
@@ -26,22 +26,6 @@
                                 class="fas fa-info-circle"></i>
                         </div>
                     </div>
-                    <div class="custom-control mb-3 p-0">
-                        <div class="col m-0 p-0 d-flex justify-content-between align-items-center">
-                            <div>
-                                <input value="true" id="server-create-charge-first-hour"
-                                    name="server-create-charge-first-hour"
-                                    {{ config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR') == 'true' ? 'checked' : '' }}
-                                    type="checkbox">
-                                <label for="server-create-charge-first-hour">{{ __('Charge first hour at creation') }}
-                                </label>
-                            </div>
-                            <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                data-content="{{ __('Charges the first hour worth of credits upon creating a server.') }}"
-                                class="fas fa-info-circle"></i>
-                        </div>
-                    </div>
-
                     <div class="custom-control mb-3 p-0">
                         <label for="credits-display-name">{{ __('Credits Display Name') }}</label>
                         <input x-model="credits-display-name" id="credits-display-name" name="credits-display-name"

From b6775f768d6948c5a1d9ac6fc138d95ec1cf4b3e Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sat, 18 Jun 2022 23:55:43 +0200
Subject: [PATCH 019/514] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Added=20Addon=20?=
 =?UTF-8?q?Docs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Addon-notes.md | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 Addon-notes.md

diff --git a/Addon-notes.md b/Addon-notes.md
new file mode 100644
index 000000000..3c335a7f6
--- /dev/null
+++ b/Addon-notes.md
@@ -0,0 +1,3 @@
+Export diff files:
+
+cp -pv --parents $(git diff <commit> --name-only) "..\controllpanelgg-monthly-addon\files-git-diff\"

From dfa50141fbd9dcd637cd87f7d4950d2397ace414 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sun, 19 Jun 2022 00:13:54 +0200
Subject: [PATCH 020/514] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Updated=20Export?=
 =?UTF-8?q?=20doc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Addon-notes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index 3c335a7f6..baf40c6aa 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,3 +1,3 @@
 Export diff files:
 
-cp -pv --parents $(git diff <commit> --name-only) "..\controllpanelgg-monthly-addon\files-git-diff\"
+git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf file.tgz -T -

From 43119e22a5fc093c12a0f2ab46ee63d645c27fb6 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Wed, 22 Jun 2022 12:01:47 +0200
Subject: [PATCH 021/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20No=20pro?=
 =?UTF-8?q?duct=20available=20at=20creation=20time?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/admin/products/create.blade.php | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index 4f79bb20c..747ee1a6c 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -171,20 +171,16 @@ class="fas fa-info-circle"></i></label>
 
                                             <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
                                                 autocomplete="off" @error('billing_period') is-invalid @enderror>
-                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
-                                                    @endif>
+                                                    <option value="hourly" selected>
                                                         {{__('Hourly')}}
                                                     </option>
-                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
-                                                    @endif>
+                                                    <option value="daily">
                                                         {{__('Daily')}}
                                                     </option>
-                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
-                                                    @endif>
+                                                    <option value="weekly">
                                                         {{__('Weekly')}}
                                                     </option>
-                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
-                                                     @endif>
+                                                     <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
                                             </select>

From 690e0e7e1239d26f956c8e97f2099f313d77034a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 01:50:45 +0200
Subject: [PATCH 022/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20migrations?=
 =?UTF-8?q?=20undo=20last=20patch=20db=20update=20&=20add=20cancelation=20?=
 =?UTF-8?q?of=20servers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...34527_add_cancelation_to_servers_table.php | 32 +++++++++++++++++++
 ...022_07_21_234818_undo_decimal_in_price.php | 32 +++++++++++++++++++
 2 files changed, 64 insertions(+)
 create mode 100644 database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
 create mode 100644 database/migrations/2022_07_21_234818_undo_decimal_in_price.php

diff --git a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
new file mode 100644
index 000000000..b9f758391
--- /dev/null
+++ b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddCancelationToServersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->boolean('canceled')->default(false);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->dropColumn('canceled');
+        });
+    }
+}
diff --git a/database/migrations/2022_07_21_234818_undo_decimal_in_price.php b/database/migrations/2022_07_21_234818_undo_decimal_in_price.php
new file mode 100644
index 000000000..cf4abb69b
--- /dev/null
+++ b/database/migrations/2022_07_21_234818_undo_decimal_in_price.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class UndoDecimalInPrice extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->decimal('price', 15, 4)->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->decimal('price',['11','2'])->change();
+        });
+    }
+}

From e207c0c5509bf1b2bea3650e3a7c5b26cbf2b466 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 02:58:08 +0200
Subject: [PATCH 023/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Cancel=20Bu?=
 =?UTF-8?q?tton=20&=20Next=20Billing=20Cycle=20field?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 116 ++++++++++++++++++------
 1 file changed, 89 insertions(+), 27 deletions(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 517c3f1ea..9c9d81b06 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -40,7 +40,6 @@ class="fa fa-plus mr-2"></i>
 
             <div class="row d-flex flex-row justify-content-center justify-content-md-start">
                 @foreach ($servers as $server)
-
                     <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
                         style="max-width: 350px">
                         <div class="card-header">
@@ -107,7 +106,7 @@ class="fas fa-info-circle"></i>
                                         <span>{{ $server->egg }}</span>
                                     </div>
                                 </div>
-                                <div class="row mb-4">
+                                <div class="row mb-2">
                                     <div class="col-5 ">
                                         {{ __('Resource plan') }}:
                                     </div>
@@ -115,11 +114,43 @@ class="fas fa-info-circle"></i>
                                         <span>{{ $server->product->name }}
                                         </span>
                                         <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>"
+                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
                                             class="fas fa-info-circle"></i>
                                     </div>
+                                </div>
 
+                                <div class="row mb-4 ">
+                                    <div class="col-5 ">
+                                        {{ __('Next Billing Cycle') }}:
+                                    </div>
+                                    <div class="col-7 d-flex text-wrap align-items-center">
+                                        <span>
+                                        @switch($server->product->billing_period)
+                                            @case('monthly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('weekly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('daily')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('hourly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('half-yearly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
+                                                @break
+                                            @case('yearly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
+                                                @break
+                                            @default
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                        @endswitch
+                                        </span>
+                                    </div>
                                 </div>
+
                                 <div class="row mb-2">
                                     <div class="col-4">
                                         {{ __('Price') }}:
@@ -147,17 +178,22 @@ class="fas fa-info-circle"></i>
                             </div>
                         </div>
 
-                        <div class="card-footer d-flex align-items-center justify-content-between">
+                        <div class="card-footer text-center">
                             <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
                                 target="__blank"
-                                class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex">
-                                <i class="fas fa-tools mr-2"></i>
-                                <span>{{ __('Manage') }}</span>
+                                class="btn btn-info text-center float-left ml-2"
+                                data-toggle="tooltip" data-placement="bottom" title="Manage Server">
+                                <i class="fas fa-tools mx-4"></i>
                             </a>
-                            <button onclick="confirmSubmit('{{ $server->id }}', handleServerDelete);" target="__blank"
-                                class="btn btn-danger mx-3 w-100 align-items-center justify-content-center d-flex">
-                                <i class="fas fa-trash mr-2"></i>
-                                <span>{{ __('Delete') }}</span>
+                            <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
+                                class="btn btn-warning  text-center"
+                                data-toggle="tooltip" data-placement="bottom" title="Cancel Server">
+                                <i class="fas fa-ban mx-4"></i>
+                            </button>
+                            <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
+                                class="btn btn-danger  text-center float-right mr-2"
+                                data-toggle="tooltip" data-placement="bottom" title="Delete Server">
+                                <i class="fas fa-trash mx-4"></i>
                             </button>
                         </div>
                     </div>
@@ -169,40 +205,66 @@ class="btn btn-danger mx-3 w-100 align-items-center justify-content-center d-fle
     <!-- END CONTENT -->
 
     <script>
-        const confirmSubmit = (serverId, handleServerDelete) => {
-            // Confirm delete submit with sweetalert
+        const handleServerCancel = (serverId) => {
+            // Handle server cancel with sweetalert
             Swal.fire({
-                title: "{{ __('Are you sure?') }}",
-                text: "{{ __('This is an irreversible action, all files of this server will be removed.') }}",
+                title: "{{ __('Cancel Server?') }}",
+                text: "{{ __('This will cancel your current server to the next billing period. It will get suspended when the current period runs out.') }}",
                 icon: 'warning',
                 confirmButtonColor: '#d9534f',
                 showCancelButton: true,
-                confirmButtonText: "{{ __('Yes, delete it!') }}",
-                cancelButtonText: "{{ __('No, cancel!') }}",
+                confirmButtonText: "{{ __('Yes, cancel it!') }}",
+                cancelButtonText: "{{ __('No, abort!') }}",
                 reverseButtons: true
             }).then((result) => {
                 if (result.value) {
-                    handleServerDelete(serverId);
+                    // Delete server
+                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
+                        method: 'DELETE',
+                        headers: {
+                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                        }
+                    }).then(() => {
+                        window.location.reload();
+                    });
                     return
                 }
-                Swal.fire("{{ __('Canceled ...') }}", `{{ __('Deletion has been canceled.') }}`, 'info');
-            });
+            })
         }
 
         const handleServerDelete = (serverId) => {
-            // Delete server
-            fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
-                method: 'DELETE',
-                headers: {
-                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
+            Swal.fire({
+                title: "{{ __('Delete Server?') }}",
+                text: "{{ __('This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.') }}",
+                icon: 'warning',
+                confirmButtonColor: '#d9534f',
+                showCancelButton: true,
+                confirmButtonText: "{{ __('Yes, delete it!') }}",
+                cancelButtonText: "{{ __('No, abort!') }}",
+                reverseButtons: true
+            }).then((result) => {
+                if (result.value) {
+                    // Delete server
+                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
+                        method: 'DELETE',
+                        headers: {
+                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                        }
+                    }).then(() => {
+                        window.location.reload();
+                    });
+                    return
                 }
-            }).then(() => {
-                window.location.reload();
             });
+
         }
 
         document.addEventListener('DOMContentLoaded', () => {
             $('[data-toggle="popover"]').popover();
         });
+
+        $(function () {
+            $('[data-toggle="tooltip"]').tooltip()
+        })
     </script>
 @endsection

From 32384044ea984b699de7d451c5440950f5b9e20a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 03:51:05 +0200
Subject: [PATCH 024/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Typo?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2022_07_21_234527_add_cancelation_to_servers_table.php    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
index b9f758391..15fafb168 100644
--- a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
+++ b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
@@ -14,7 +14,7 @@ class AddCancelationToServersTable extends Migration
     public function up()
     {
         Schema::table('servers', function (Blueprint $table) {
-            $table->boolean('canceled')->default(false);
+            $table->dateTime('cancelled')->nullable();
         });
     }
 
@@ -26,7 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('servers', function (Blueprint $table) {
-            $table->dropColumn('canceled');
+            $table->dropColumn('cancelled');
         });
     }
 }

From 78a6787607b9229986585c6089dae99a6049f768 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 03:52:49 +0200
Subject: [PATCH 025/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Server=20Ca?=
 =?UTF-8?q?ncelation=20route=20method=20and=20charging?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php         |  8 ++++----
 .../Controllers/Admin/ServerController.php     | 18 ++++++++++++++++++
 app/Http/Controllers/ServerController.php      | 16 +++++++++++++++-
 app/Models/Server.php                          |  3 ++-
 resources/views/servers/index.blade.php        |  4 ++--
 routes/web.php                                 |  2 ++
 6 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 769909c32..2a5d8a5ad 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -81,14 +81,14 @@ public function handle()
                     continue;
                 }
 
-                // check if user has enough credits to charge the server
-                if ($user->credits < $product->price) {
+                // check if the server is canceled or if user has enough credits to charge the server or
+                if ( $server->cancelled || $user->credits < $product->price) {
                     try {
-                        #suspend server
+                        // suspend server
                         $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
                         $server->suspend();
 
-                        #add user to notify list
+                        // add user to notify list
                         if (!in_array($user, $this->usersToNotify)) {
                             array_push($this->usersToNotify, $user);
                         }
diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index 5ebc29bce..594d7a0f6 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -108,6 +108,24 @@ public function destroy(Server $server)
         }
     }
 
+    /**
+     * Cancel the Server billing cycle.
+     *
+     * @param Server $server
+     * @return RedirectResponse|Response
+     */
+    public function cancel (Server $server)
+    {
+        try {
+            error_log($server->update([
+                'cancelled' => now(),
+            ]));
+            return redirect()->route('servers.index')->with('success', __('Server cancelled'));
+        } catch (Exception $e) {
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
+        }
+    }
+
     /**
      * @param Server $server
      * @return RedirectResponse
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 45d72569c..ee9c47b76 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -210,7 +210,21 @@ public function destroy(Server $server)
             $server->delete();
             return redirect()->route('servers.index')->with('success', __('Server removed'));
         } catch (Exception $e) {
-            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to remove a resource "') . $e->getMessage() . '"');
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to delete the server"') . $e->getMessage() . '"');
+        }
+    }
+
+    /** Cancel Server */
+    public function cancel (Server $server)
+    {
+        try {
+            error_log($server->update([
+                'cancelled' => now(),
+            ]));
+
+            return redirect()->route('servers.index')->with('success', __('Server cancelled'));
+        } catch (Exception $e) {
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
         }
     }
 }
diff --git a/app/Models/Server.php b/app/Models/Server.php
index fa6d17caf..5f87d488c 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -48,7 +48,8 @@ class Server extends Model
         "identifier",
         "product_id",
         "pterodactyl_id",
-        "last_billed"
+        "last_billed",
+        "cancelled"
     ];
 
     /**
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 9c9d81b06..e96b46b12 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -219,8 +219,8 @@ class="btn btn-danger  text-center float-right mr-2"
             }).then((result) => {
                 if (result.value) {
                     // Delete server
-                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
-                        method: 'DELETE',
+                    fetch("{{ route('servers.cancel', '') }}" + '/' + serverId, {
+                        method: 'PATCH',
                         headers: {
                             'X-CSRF-TOKEN': '{{ csrf_token() }}'
                         }
diff --git a/routes/web.php b/routes/web.php
index 168549f74..8755eb324 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -60,6 +60,7 @@
     #normal routes
     Route::get('notifications/readAll',[NotificationController::class,'readAll'])->name('notifications.readAll');
     Route::resource('notifications', NotificationController::class);
+    Route::patch('/servers/cancel/{server}', [ServerController::class, 'cancel'])->name('servers.cancel');
     Route::resource('servers', ServerController::class);
     Route::resource('profile', ProfileController::class);
     Route::resource('store', StoreController::class);
@@ -112,6 +113,7 @@
         #servers
         Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');
         Route::post('servers/togglesuspend/{server}', [AdminServerController::class, 'toggleSuspended'])->name('servers.togglesuspend');
+        Route::patch('/servers/cancel/{server}', [AdminServerController::class, 'cancel'])->name('servers.cancel');
         Route::resource('servers', AdminServerController::class);
 
         #products

From 08208cab727a73e75f51a33aa5ba7868606b953d Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:00:23 +0200
Subject: [PATCH 026/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20yearly=20an?=
 =?UTF-8?q?d=20half-yearly=20billing=20periods?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php           | 6 ++++++
 app/Http/Controllers/Admin/ProductController.php | 4 ++--
 resources/views/admin/products/create.blade.php  | 6 ++++++
 resources/views/admin/products/edit.blade.php    | 8 ++++++++
 resources/views/servers/index.blade.php          | 4 ++++
 5 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 2a5d8a5ad..45f18c2b1 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -61,6 +61,12 @@ public function handle()
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
                 switch($billing_period) {
+                    case 'yearly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addYear();
+                        break;
+                    case 'half-yearly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
+                        break;
                     case 'monthly':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 772abc67a..9fb518015 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -73,7 +73,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
@@ -140,7 +140,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index 8e0465fc1..578fa9104 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -183,6 +183,12 @@ class="fas fa-info-circle"></i></label>
                                                      <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="half-yearly">
+                                                        {{__('Half Yearly')}}
+                                                    </option>
+                                                    <option value="yearly">
+                                                        {{__('Yearly')}}
+                                                    </option>
                                             </select>
                                             @error('billing_period')
                                             <div class="invalid-feedback">
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php
index cedbc72c8..3401577b5 100644
--- a/resources/views/admin/products/edit.blade.php
+++ b/resources/views/admin/products/edit.blade.php
@@ -190,6 +190,14 @@ class="fas fa-info-circle"></i></label>
                                                      @endif>
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="half-yearly" @if ($product->billing_period  == 'half-yearly') selected
+                                                    @endif>
+                                                        {{__('Half Yearly')}}
+                                                    </option>
+                                                    <option value="yearly" @if ($product->billing_period  == 'yearly') selected
+                                                    @endif>
+                                                        {{__('Yearly')}}
+                                                    </option>
                                             </select>
                                             @error('billing_period')
                                             <div class="invalid-feedback">
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index e96b46b12..1d0edd657 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -162,6 +162,10 @@ class="fas fa-info-circle"></i>
                                         <div class="text-muted">
                                         @if($server->product->billing_period == 'monthly')
                                             {{ __('per Month') }}
+                                        @elseif($server->product->billing_period == 'half-yearly')
+                                            {{ __('per 6 Months') }}
+                                        @elseif($server->product->billing_period == 'yearly')
+                                            {{ __('per Year') }}
                                         @elseif($server->product->billing_period == 'weekly')
                                             {{ __('per Week') }}
                                         @elseif($server->product->billing_period == 'daily')

From 7369e8a643e5016459e5fd5be6e1e8682b9b44a1 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:09:34 +0200
Subject: [PATCH 027/514] =?UTF-8?q?refactor:=20=F0=9F=9A=9A=20Rename=20Yea?=
 =?UTF-8?q?rly=20->=20Annually?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php        |  4 +-
 .../Controllers/Admin/ProductController.php   |  4 +-
 .../views/admin/products/create.blade.php     |  8 +--
 resources/views/admin/products/edit.blade.php |  8 +--
 resources/views/servers/index.blade.php       | 62 +++++++++++--------
 5 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 45f18c2b1..dac01f0f8 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -61,10 +61,10 @@ public function handle()
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
                 switch($billing_period) {
-                    case 'yearly':
+                    case 'annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addYear();
                         break;
-                    case 'half-yearly':
+                    case 'half-annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
                         break;
                     case 'monthly':
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 9fb518015..b24c5cc6b 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -73,7 +73,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
@@ -140,7 +140,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index 578fa9104..f44f64f41 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -183,11 +183,11 @@ class="fas fa-info-circle"></i></label>
                                                      <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
-                                                    <option value="half-yearly">
-                                                        {{__('Half Yearly')}}
+                                                    <option value="half-annually">
+                                                        {{__('Half Annually')}}
                                                     </option>
-                                                    <option value="yearly">
-                                                        {{__('Yearly')}}
+                                                    <option value="annually">
+                                                        {{__('Annually')}}
                                                     </option>
                                             </select>
                                             @error('billing_period')
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php
index 3401577b5..9d3aec529 100644
--- a/resources/views/admin/products/edit.blade.php
+++ b/resources/views/admin/products/edit.blade.php
@@ -190,13 +190,13 @@ class="fas fa-info-circle"></i></label>
                                                      @endif>
                                                         {{__('Monthly')}}
                                                     </option>
-                                                    <option value="half-yearly" @if ($product->billing_period  == 'half-yearly') selected
+                                                    <option value="half-annually" @if ($product->billing_period  == 'half-annually') selected
                                                     @endif>
-                                                        {{__('Half Yearly')}}
+                                                        {{__('Half Annually')}}
                                                     </option>
-                                                    <option value="yearly" @if ($product->billing_period  == 'yearly') selected
+                                                    <option value="annually" @if ($product->billing_period  == 'annually') selected
                                                     @endif>
-                                                        {{__('Yearly')}}
+                                                        {{__('Annually')}}
                                                     </option>
                                             </select>
                                             @error('billing_period')
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 1d0edd657..fdcf2d104 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -72,9 +72,13 @@ class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }
                                 <div class="row mb-3">
                                     <div class="col my-auto">{{ __('Status') }}:</div>
                                     <div class="col-7 my-auto">
-                                        <i
-                                            class="fas {{ $server->isSuspended() ? 'text-danger' : 'text-success' }} fa-circle mr-2"></i>
-                                        {{ $server->isSuspended() ? 'Suspended' : 'Active' }}
+                                        @if($server->suspennded)
+                                            <span class="badge badge-danger">{{ __('Suspended') }}</span>
+                                        @elseif($server->cancelled)
+                                            <span class="badge badge-warning">{{ __('Cancelled') }}</span>
+                                        @else
+                                            <span class="badge badge-success">{{ __('Active') }}</span>
+                                        @endif
                                     </div>
                                 </div>
                                 <div class="row mb-2">
@@ -125,28 +129,32 @@ class="fas fa-info-circle"></i>
                                     </div>
                                     <div class="col-7 d-flex text-wrap align-items-center">
                                         <span>
-                                        @switch($server->product->billing_period)
-                                            @case('monthly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('weekly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('daily')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('hourly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('half-yearly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
-                                                @break
-                                            @case('yearly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
-                                                @break
-                                            @default
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
-                                        @endswitch
+                                        @if ($server->cancelled)
+                                            -
+                                        @else
+                                            @switch($server->product->billing_period)
+                                                @case('monthly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('weekly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('daily')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('hourly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('half-annually')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('annually')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
+                                                    @break
+                                                @default
+                                                    {{ __('Unknown') }}
+                                            @endswitch
+                                        @endif
                                         </span>
                                     </div>
                                 </div>
@@ -162,9 +170,9 @@ class="fas fa-info-circle"></i>
                                         <div class="text-muted">
                                         @if($server->product->billing_period == 'monthly')
                                             {{ __('per Month') }}
-                                        @elseif($server->product->billing_period == 'half-yearly')
+                                        @elseif($server->product->billing_period == 'half-annually')
                                             {{ __('per 6 Months') }}
-                                        @elseif($server->product->billing_period == 'yearly')
+                                        @elseif($server->product->billing_period == 'annually')
                                             {{ __('per Year') }}
                                         @elseif($server->product->billing_period == 'weekly')
                                             {{ __('per Week') }}

From dbbdfaa623f21e393bc30c54d49921ee3320a5c6 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:15:40 +0200
Subject: [PATCH 028/514] =?UTF-8?q?fix:=20=F0=9F=93=9D=20Undo=20Naming?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index ee9c47b76..167325887 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -210,7 +210,7 @@ public function destroy(Server $server)
             $server->delete();
             return redirect()->route('servers.index')->with('success', __('Server removed'));
         } catch (Exception $e) {
-            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to delete the server"') . $e->getMessage() . '"');
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to remove a resource"') . $e->getMessage() . '"');
         }
     }
 

From 737bf6e8e9564839dade4f47e1e7124c2217d518 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:25:23 +0200
Subject: [PATCH 029/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20Localization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/lang/de.json                  | 23 ++++++++++++++++++++++-
 resources/lang/en.json                  | 23 ++++++++++++++++++++++-
 resources/views/servers/index.blade.php |  6 +++---
 3 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/resources/lang/de.json b/resources/lang/de.json
index 364ae6078..811c0cea9 100644
--- a/resources/lang/de.json
+++ b/resources/lang/de.json
@@ -442,5 +442,26 @@
     "pl": "Polnisch",
     "zh": "Chinesisch",
     "tr": "Türkisch",
-    "ru": "Russisch"
+    "ru": "Russisch",
+    "hourly": "Stündlich",
+    "monthly": "Monatlich",
+    "yearly": "Jährlich",
+    "daily": "Täglich",
+    "weekly": "Wöchentlich",
+    "half-annually": "Halbjährlich",
+    "annually": "Jährlich",
+    "Cancelled": "Gekündigt",
+    "An exception has occurred while trying to cancel the server": "Ein Fehler ist aufgetreten beim Versuch, den Server zu kündigen",
+    "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "Dies wird Ihren aktuellen Server zur nächsten Abrechnungsperiode kündigen. Er wird beim Ablauf der aktuellen Periode gesperrt.",
+    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "Dies ist eine irreversibel Aktion, alle Dateien dieses Servers werden gelöscht. Keine Gelder werden zurückgezahlt. Wir empfehlen, den Server zu löschen, wenn er gesperrt ist.",
+    "Cancel Server?": "Server kündigen?",
+    "Delete Server?": "Server löschen?",
+    "Billing Period": "Abrechnungsperiode",
+    "Next Billing Cycle": "Nächste Abrechnungsperiode",
+    "Manage Server": "Server verwalten",
+    "Delete Server": "Server löschen",
+    "Cancel Server": "Server kündigen",
+    "Yes, cancel it!": "Ja, löschen!",
+    "No, abort!": "Abbrechen",
+    "Billing period": "Abrechnungsperiode"
 }
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 37beb2a3d..6a865f29d 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -444,5 +444,26 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Russian"
+    "ru": "Russian",
+    "hourly": "Hourly",
+    "monthly": "Monthly",
+    "yearly": "Yearly",
+    "daily": "Daily",
+    "weekly": "Weekly",
+    "half-annually": "Half-annually",
+    "annually": "Annually",
+    "Cancelled": "Cancelled",
+    "An exception has occurred while trying to cancel the server": "An exception has occurred while trying to cancel the server",
+    "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
+    "Cancel Server?": "Cancel Server?",
+    "Delete Server?": "Delete Server?",
+    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.",
+    "Billing Period": "Billing Period",
+    "Next Billing Cycle": "Next Billing Cycle",
+    "Manage Server": "Manage Server",
+    "Delete Server": "Delete Server",
+    "Cancel Server": "Cancel Server",
+    "Yes, cancel it!": "Yes, cancel it!",
+    "No, abort!": "No, abort!",
+    "Billing period": "Billing period"
 }
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index fdcf2d104..d907a2780 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -194,17 +194,17 @@ class="fas fa-info-circle"></i>
                             <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
                                 target="__blank"
                                 class="btn btn-info text-center float-left ml-2"
-                                data-toggle="tooltip" data-placement="bottom" title="Manage Server">
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
                                 <i class="fas fa-tools mx-4"></i>
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                data-toggle="tooltip" data-placement="bottom" title="Cancel Server">
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>
                             <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
                                 class="btn btn-danger  text-center float-right mr-2"
-                                data-toggle="tooltip" data-placement="bottom" title="Delete Server">
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
                                 <i class="fas fa-trash mx-4"></i>
                             </button>
                         </div>

From 23a890ecba73bcc9adbd9f53e110d1c83c27715f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:31:00 +0200
Subject: [PATCH 030/514] =?UTF-8?q?fix:=20=F0=9F=92=84=20Added=20hyphens?=
 =?UTF-8?q?=20at=20next=20billing=20cycle=20field?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index d907a2780..df7bd1789 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -124,7 +124,7 @@ class="fas fa-info-circle"></i>
                                 </div>
 
                                 <div class="row mb-4 ">
-                                    <div class="col-5 ">
+                                    <div class="col-5 word-break" style="hyphens: auto">
                                         {{ __('Next Billing Cycle') }}:
                                     </div>
                                     <div class="col-7 d-flex text-wrap align-items-center">

From 620a6b83e9878633618b28e7a2249c8c7144c56f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:33:54 +0200
Subject: [PATCH 031/514] =?UTF-8?q?style:=20=F0=9F=92=84=20Changed=20Next?=
 =?UTF-8?q?=20Billing=20Cycle=20behaviour?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index df7bd1789..9b5a3ac9d 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -129,7 +129,7 @@ class="fas fa-info-circle"></i>
                                     </div>
                                     <div class="col-7 d-flex text-wrap align-items-center">
                                         <span>
-                                        @if ($server->cancelled)
+                                        @if ($server->suspended)
                                             -
                                         @else
                                             @switch($server->product->billing_period)

From abd8bc6b9c3a2ff9250a58fe525e78c0e8eb787a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:40:03 +0200
Subject: [PATCH 032/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fiy=20suspended?=
 =?UTF-8?q?=20typo=20&=20localization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/lang/de.json                  | 1 +
 resources/lang/en.json                  | 1 +
 resources/views/servers/index.blade.php | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/resources/lang/de.json b/resources/lang/de.json
index 811c0cea9..184785c6b 100644
--- a/resources/lang/de.json
+++ b/resources/lang/de.json
@@ -450,6 +450,7 @@
     "weekly": "Wöchentlich",
     "half-annually": "Halbjährlich",
     "annually": "Jährlich",
+    "Suspended": "Gesperrt",
     "Cancelled": "Gekündigt",
     "An exception has occurred while trying to cancel the server": "Ein Fehler ist aufgetreten beim Versuch, den Server zu kündigen",
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "Dies wird Ihren aktuellen Server zur nächsten Abrechnungsperiode kündigen. Er wird beim Ablauf der aktuellen Periode gesperrt.",
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 6a865f29d..430bb7d29 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -452,6 +452,7 @@
     "weekly": "Weekly",
     "half-annually": "Half-annually",
     "annually": "Annually",
+    "Suspended": "Suspended",
     "Cancelled": "Cancelled",
     "An exception has occurred while trying to cancel the server": "An exception has occurred while trying to cancel the server",
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 9b5a3ac9d..0fdac5a2f 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -72,7 +72,7 @@ class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }
                                 <div class="row mb-3">
                                     <div class="col my-auto">{{ __('Status') }}:</div>
                                     <div class="col-7 my-auto">
-                                        @if($server->suspennded)
+                                        @if($server->suspended)
                                             <span class="badge badge-danger">{{ __('Suspended') }}</span>
                                         @elseif($server->cancelled)
                                             <span class="badge badge-warning">{{ __('Cancelled') }}</span>
@@ -199,6 +199,7 @@ class="btn btn-info text-center float-left ml-2"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
+                                disabled="{{ $server->suspended }}"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>

From f3856c88ba039d86cf309b84a1a3456654e25968 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:54:33 +0200
Subject: [PATCH 033/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Credt=20usage=20a?=
 =?UTF-8?q?t=20dashboard?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/HomeController.php |  2 +-
 app/Models/Product.php                  | 16 +++++++++++++++-
 app/Models/User.php                     |  8 +++++---
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index d6b2fd18d..80c1ff5ef 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -76,7 +76,7 @@ public function index(Request $request)
 
         /** Build our Time-Left-Box */
         if ($credits > 0.01 and $usage > 0) {
-            $daysLeft = number_format(($credits * 30) / $usage, 2, '.', '');
+            $daysLeft = number_format($credits / ($usage / 30), 2, '.', '');
             $hoursLeft = number_format($credits / ($usage / 30 / 24), 2, '.', '');
 
             $bg = $this->getTimeLeftBoxBackground($daysLeft);
diff --git a/app/Models/Product.php b/app/Models/Product.php
index 52a37c28c..2c23e9c90 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -37,7 +37,21 @@ public static function boot()
 
     public function getHourlyPrice()
     {
-        return ($this->price / 30) / 24;
+        // calculate the hourly price with the billing period
+        switch($this->billing_period) {
+            case 'daily':
+                return $this->price / 24;
+            case 'weekly':
+                return $this->price / 24 / 7;
+            case 'monthly':
+                return $this->price / 24 / 30;
+            case 'half-annually':
+                return $this->price / 24 / 30 / 6;
+            case 'annually':
+                return $this->price / 24 / 365;
+            default:
+                return $this->price;
+        }
     }
 
     public function getDailyPrice()
diff --git a/app/Models/User.php b/app/Models/User.php
index 5f8af0246..e4e3fc665 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -233,17 +233,19 @@ public function getAvatar()
      * @return string
      */
     public function creditUsage()
-    {            
+    {
         $usage = 0;
         foreach ($this->getServersWithProduct() as $server) {
-            $usage += $server->product->price;
+            $usage += $server->product->getHourlyPrice() * 24 * 30;
         }
 
         return number_format($usage, 2, '.', '');
-    }    
+    }
 
     private function getServersWithProduct() {
         return $this->servers()
+            ->whereNull('suspended')
+            ->whereNull('cancelled')
             ->with('product')
             ->get();
     }

From 4b276651502e4ac22151a00ded759684824a0ce2 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:06:38 +0200
Subject: [PATCH 034/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Disable=20Cancel?=
 =?UTF-8?q?=20Button?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 0fdac5a2f..862174f3d 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -199,7 +199,7 @@ class="btn btn-info text-center float-left ml-2"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                disabled="{{ $server->suspended }}"
+                                {{ $server->suspended? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>

From 3e4a4f32fcdad7fd6f3a5404a76630cccb1bb022 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:12:06 +0200
Subject: [PATCH 035/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Disable=20cancel?=
 =?UTF-8?q?=20button=20when=20cancelled?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 862174f3d..8ccffc874 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -199,7 +199,7 @@ class="btn btn-info text-center float-left ml-2"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                {{ $server->suspended? "disabled" : "" }}
+                                {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>

From 479ccdb92c5cc4746e9aa1c6597dc4d51854a565 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:26:48 +0200
Subject: [PATCH 036/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20Added=20Bold=20?=
 =?UTF-8?q?text=20for=20No=20refund?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/lang/de.json                  | 2 +-
 resources/lang/en.json                  | 2 +-
 resources/views/servers/index.blade.php | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/resources/lang/de.json b/resources/lang/de.json
index 184785c6b..1beefcc00 100644
--- a/resources/lang/de.json
+++ b/resources/lang/de.json
@@ -454,7 +454,7 @@
     "Cancelled": "Gekündigt",
     "An exception has occurred while trying to cancel the server": "Ein Fehler ist aufgetreten beim Versuch, den Server zu kündigen",
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "Dies wird Ihren aktuellen Server zur nächsten Abrechnungsperiode kündigen. Er wird beim Ablauf der aktuellen Periode gesperrt.",
-    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "Dies ist eine irreversibel Aktion, alle Dateien dieses Servers werden gelöscht. Keine Gelder werden zurückgezahlt. Wir empfehlen, den Server zu löschen, wenn er gesperrt ist.",
+    "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.": "Dies ist eine irreversiblen Aktion, alle Dateien dieses Servers werden gelöscht. <strong>Keine Rückerstattung!</strong>. Wir empfehlen, den Server zu löschen, wenn er gesperrt ist.",
     "Cancel Server?": "Server kündigen?",
     "Delete Server?": "Server löschen?",
     "Billing Period": "Abrechnungsperiode",
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 430bb7d29..035f66ac8 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -458,7 +458,7 @@
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
     "Cancel Server?": "Cancel Server?",
     "Delete Server?": "Delete Server?",
-    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.",
+    "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.",
     "Billing Period": "Billing Period",
     "Next Billing Cycle": "Next Billing Cycle",
     "Manage Server": "Manage Server",
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 8ccffc874..53490a292 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -248,7 +248,7 @@ class="btn btn-danger  text-center float-right mr-2"
         const handleServerDelete = (serverId) => {
             Swal.fire({
                 title: "{{ __('Delete Server?') }}",
-                text: "{{ __('This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.') }}",
+                html: "{{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}}",
                 icon: 'warning',
                 confirmButtonColor: '#d9534f',
                 showCancelButton: true,

From 1fb855a6840ba96436be7b23805827076ff588ac Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:31:05 +0200
Subject: [PATCH 037/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Quartely=20?=
 =?UTF-8?q?billing=20period?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php           | 3 +++
 app/Http/Controllers/Admin/ProductController.php | 4 ++--
 app/Models/Product.php                           | 2 ++
 resources/lang/de.json                           | 1 +
 resources/lang/en.json                           | 1 +
 resources/views/admin/products/create.blade.php  | 3 +++
 resources/views/admin/products/edit.blade.php    | 4 ++++
 resources/views/servers/index.blade.php          | 5 +++++
 8 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index dac01f0f8..72b5bab4d 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -67,6 +67,9 @@ public function handle()
                     case 'half-annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
                         break;
+                    case 'quarterly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addMonths(3);
+                        break;
                     case 'monthly':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index b24c5cc6b..9be326cdd 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -73,7 +73,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,quarterly,half-annually,annually",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
@@ -140,7 +140,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,quarterly,half-annually,annually",
         ]);
 
         $disabled = !is_null($request->input('disabled'));
diff --git a/app/Models/Product.php b/app/Models/Product.php
index 2c23e9c90..af8fd27a3 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -45,6 +45,8 @@ public function getHourlyPrice()
                 return $this->price / 24 / 7;
             case 'monthly':
                 return $this->price / 24 / 30;
+            case 'quarterly':
+                return $this->price / 24 / 30 / 3;
             case 'half-annually':
                 return $this->price / 24 / 30 / 6;
             case 'annually':
diff --git a/resources/lang/de.json b/resources/lang/de.json
index 1beefcc00..d0b5408ae 100644
--- a/resources/lang/de.json
+++ b/resources/lang/de.json
@@ -448,6 +448,7 @@
     "yearly": "Jährlich",
     "daily": "Täglich",
     "weekly": "Wöchentlich",
+    "quarterly": "Vierteljährlich",
     "half-annually": "Halbjährlich",
     "annually": "Jährlich",
     "Suspended": "Gesperrt",
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 035f66ac8..0157b0f9a 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -450,6 +450,7 @@
     "yearly": "Yearly",
     "daily": "Daily",
     "weekly": "Weekly",
+    "quarterly": "Quarterly",
     "half-annually": "Half-annually",
     "annually": "Annually",
     "Suspended": "Suspended",
diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php
index f44f64f41..81ccf32dd 100644
--- a/resources/views/admin/products/create.blade.php
+++ b/resources/views/admin/products/create.blade.php
@@ -183,6 +183,9 @@ class="fas fa-info-circle"></i></label>
                                                      <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="quarterly">
+                                                        {{__('Quarterly')}}
+                                                    </option>
                                                     <option value="half-annually">
                                                         {{__('Half Annually')}}
                                                     </option>
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php
index 9d3aec529..851142af3 100644
--- a/resources/views/admin/products/edit.blade.php
+++ b/resources/views/admin/products/edit.blade.php
@@ -190,6 +190,10 @@ class="fas fa-info-circle"></i></label>
                                                      @endif>
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="quarterly" @if ($product->billing_period  == 'quarterly') selected
+                                                    @endif>
+                                                        {{__('Quarterly')}}
+                                                    </option>
                                                     <option value="half-annually" @if ($product->billing_period  == 'half-annually') selected
                                                     @endif>
                                                         {{__('Half Annually')}}
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 53490a292..a9c57994e 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -145,6 +145,9 @@ class="fas fa-info-circle"></i>
                                                 @case('hourly')
                                                     {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
                                                     @break
+                                                @case('quarterly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(3)->toDayDateTimeString(); }}
+                                                    @break
                                                 @case('half-annually')
                                                     {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
                                                     @break
@@ -172,6 +175,8 @@ class="fas fa-info-circle"></i>
                                             {{ __('per Month') }}
                                         @elseif($server->product->billing_period == 'half-annually')
                                             {{ __('per 6 Months') }}
+                                        @elseif($server->product->billing_period == 'quarterly')
+                                            {{ __('per 3 Months') }}
                                         @elseif($server->product->billing_period == 'annually')
                                             {{ __('per Year') }}
                                         @elseif($server->product->billing_period == 'weekly')

From de96d6d6d3ceaaf6bc17b51693d9d8beba2253cb Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Wed, 27 Jul 2022 23:26:03 +0200
Subject: [PATCH 038/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20Fixed=20?=
 =?UTF-8?q?credits=20check=20at=20server=20creation=20&=20formatted=20pric?=
 =?UTF-8?q?es=20nicely?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php    |  2 +-
 app/Http/Controllers/ServerController.php |  4 +++-
 resources/views/servers/create.blade.php  | 15 ++++++++++++---
 resources/views/servers/index.blade.php   |  2 +-
 4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 72b5bab4d..014af9636 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -91,7 +91,7 @@ public function handle()
                 }
 
                 // check if the server is canceled or if user has enough credits to charge the server or
-                if ( $server->cancelled || $user->credits < $product->price) {
+                if ( $server->cancelled || $user->credits <= $product->price) {
                     try {
                         // suspend server
                         $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 167325887..a740fbdb3 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -105,11 +105,13 @@ private function validateConfigurationRules()
         // minimum credits
         if (FacadesRequest::has("product")) {
             $product = Product::findOrFail(FacadesRequest::input("product"));
+
             if (
                 Auth::user()->credits <
                 ($product->minimum_credits == -1
                     ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
-                    : $product->minimum_credits)
+                    : $product->minimum_credits) ||
+                Auth::user()->credits <= $product->price
             ) {
                 return redirect()->route('servers.index')->with('error', "You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product!");
             }
diff --git a/resources/views/servers/create.blade.php b/resources/views/servers/create.blade.php
index 02ab8915a..d91499e65 100644
--- a/resources/views/servers/create.blade.php
+++ b/resources/views/servers/create.blade.php
@@ -223,10 +223,10 @@ class="custom-select">
                                         </div>
                                     </div>
                                     <button type="submit" x-model="selectedProduct" name="product"
-                                        :disabled="product.minimum_credits > user.credits"
-                                        :class="product.minimum_credits > user.credits ? 'disabled' : ''"
+                                        :disabled="product.minimum_credits > user.credits || product.price > user.credits"
+                                        :class="product.minimum_credits > user.credits || product.price > user.credits ? 'disabled' : ''"
                                         class="btn btn-primary btn-block mt-2" @click="setProduct(product.id)"
-                                        x-text=" product.minimum_credits > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}'">
+                                        x-text="product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}'">
                                     </button>
                                 </div>
                             </div>
@@ -354,6 +354,7 @@ function serverApp() {
                         .catch(console.error)
 
                     this.fetchedProducts = true;
+
                     // TODO: Sortable by user chosen property (cpu, ram, disk...)
                     this.products = response.data.sort((p1, p2) => p1.price > p2.price && 1 || -1)
 
@@ -362,11 +363,19 @@ function serverApp() {
                         product.cpu = product.cpu / 100;
                     })
 
+                    //format price to have no decimals if it is a whole number
+                    this.products.forEach(product => {
+                        if (product.price % 1 === 0) {
+                            product.price = Math.round(product.price);
+                        }
+                    })
+
 
                     this.loading = false;
                     this.updateSelectedObjects()
                 },
 
+
                 /**
                  * @description map selected id's to selected objects
                  * @note being used in the server info box
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index a9c57994e..0e5d69505 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -188,7 +188,7 @@ class="fas fa-info-circle"></i>
                                         @endif
                                             </div>
                                         <span>
-                                            {{ $server->product->price }}
+                                            {{ number_format($server->product->price) }}
                                         </span>
                                     </div>
                                 </div>

From b80a8640deddeec7c6f2e5763d739e5cfcd957b5 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 28 Jul 2022 23:20:39 +0200
Subject: [PATCH 039/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Server=20creation?=
 =?UTF-8?q?=20fail=20when=20server.price=20=3D=20user.credits?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index a740fbdb3..e443f64ee 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -111,7 +111,7 @@ private function validateConfigurationRules()
                 ($product->minimum_credits == -1
                     ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
                     : $product->minimum_credits) ||
-                Auth::user()->credits <= $product->price
+                Auth::user()->credits < $product->price
             ) {
                 return redirect()->route('servers.index')->with('error', "You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product!");
             }

From e3e7329d312a6d9d73a52db4f1976b6917736f36 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 28 Jul 2022 23:33:04 +0200
Subject: [PATCH 040/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20See=20last=20comm?=
 =?UTF-8?q?it?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index e443f64ee..f51dfb5ba 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -106,11 +106,12 @@ private function validateConfigurationRules()
         if (FacadesRequest::has("product")) {
             $product = Product::findOrFail(FacadesRequest::input("product"));
 
+            error_log(Auth::user()->credits);
+            error_log($product->price);
+
+            error_log(Auth::user()->credits < $product->price ? "true" : "false");
             if (
-                Auth::user()->credits <
-                ($product->minimum_credits == -1
-                    ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
-                    : $product->minimum_credits) ||
+                Auth::user()->credits < $product->minimum_credits ||
                 Auth::user()->credits < $product->price
             ) {
                 return redirect()->route('servers.index')->with('error', "You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product!");

From fd216654930ddeafb402ad9765f51de807c29420 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Mon, 15 Aug 2022 14:52:49 +0200
Subject: [PATCH 041/514] =?UTF-8?q?fix:=20=F0=9F=92=84=20Styling=20of=20se?=
 =?UTF-8?q?rver=20buttons?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 43bdc558a..223bbab2c 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -200,23 +200,25 @@ class="fas fa-info-circle"></i>
                                 target="__blank"
                                 class="btn btn-info text-center float-left ml-2"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
-                                <i class="fas fa-tools mx-4"></i>
+                                <i class="fas fa-tools mx-2"></i>
                             </a>
-                            <a href="{{ route('servers.show', ['server' => $server->id])}}" 
-                            	class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex"
+                            @if(config("SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN"))
+                            <a href="{{ route('servers.show', ['server' => $server->id])}}"
+                            	class="btn btn-info text-center mr-3"
                             	data-toggle="tooltip" data-placement="bottom" title="{{ __('Server Settings') }}">
-                                <i class="fas fa-cog mr-2"></i>
+                                <i class="fas fa-cog mx-2"></i>
                             </a>
+                            @endif
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
                                 {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
-                                <i class="fas fa-ban mx-4"></i>
+                                <i class="fas fa-ban mx-2"></i>
                             </button>
                             <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
                                 class="btn btn-danger  text-center float-right mr-2"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
-                                <i class="fas fa-trash mx-4"></i>
+                                <i class="fas fa-trash mx-2"></i>
                             </button>
                         </div>
                     </div>

From b580e47cdf1e8c3eb3fb80ac20915453e5b38a2f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Mon, 15 Aug 2022 14:56:34 +0200
Subject: [PATCH 042/514] chore: Docs

---
 Addon-notes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index baf40c6aa..1d3887428 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,3 +1,3 @@
 Export diff files:
 
-git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf file.tgz -T -
+git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -

From bacab7bb18c47b7da39bc61355e5f20a9856a919 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Wed, 16 Nov 2022 18:10:00 +0100
Subject: [PATCH 043/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20cpgg=20bad?=
 =?UTF-8?q?=20code=20bug=20->=20doesNotFit=20can=20be=20undefined...?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/create.blade.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/resources/views/servers/create.blade.php b/resources/views/servers/create.blade.php
index cc0f95ddd..4b4c79593 100644
--- a/resources/views/servers/create.blade.php
+++ b/resources/views/servers/create.blade.php
@@ -228,8 +228,8 @@ class="custom-select">
                                         </div>
                                     </div>
                                     <button type="submit" x-model="selectedProduct" name="product"
-                                        :disabled="product.minimum_credits > user.credits || product.price > user.credits || product.doesNotFit"
-                                        :class="product.minimum_credits > user.credits || product.price > user.credits ? 'disabled' : ''"
+                                        :disabled="product.doesNotFit || product.minimum_credits > user.credits || product.price > user.credits"
+                                        :class="product.doesNotFit || product.minimum_credits > user.credits || product.price > user.credits ? 'disabled' : ''"
                                         class="btn btn-primary btn-block mt-2" @click="setProduct(product.id)"
                                         x-text="product.doesNotFit ?  '{{ __('Server cannot fit on this node') }}' :  product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}'">
                                     </button>

From 0f5450e01e27ad53326765434bc731377808b94d Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Tue, 22 Nov 2022 12:23:33 +0100
Subject: [PATCH 044/514] fix: Number formatting on server overview (price)

---
 Addon-notes.md                          | 3 ++-
 resources/views/servers/index.blade.php | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index 1d3887428..bed6f5a2e 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,3 +1,4 @@
 Export diff files:
+Commit Hash of lates Main commit
 
-git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -
+git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 4b334f51a..4aca432ce 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -189,7 +189,7 @@ class="fas fa-info-circle"></i>
                                         @endif
                                             </div>
                                         <span>
-                                            {{ number_format($server->product->price) }}
+                                            {{ $server->product->price == round($server->product->price) ? round($server->product->price) : $server->product->price }}
                                         </span>
                                     </div>
                                 </div>

From e5ae179b9d23e3d43e472ae1570c378c22923a15 Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Tue, 22 Nov 2022 13:42:46 +0100
Subject: [PATCH 045/514] Fixed Upgrade/Downgrade Credit withdrawal

---
 app/Http/Controllers/ServerController.php  | 61 ++++++++++++++++------
 resources/views/servers/settings.blade.php | 10 ++--
 2 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 00e2aea01..91ef195bd 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -9,6 +9,7 @@
 use App\Models\Node;
 use App\Models\Product;
 use App\Models\Server;
+use App\Models\User;
 use App\Models\Settings;
 use App\Notifications\ServerCreationError;
 use Carbon\Carbon;
@@ -219,8 +220,6 @@ private function noAllocationsError(Server $server)
      */
     private function serverCreationFailed(Response $response, Server $server)
     {
-        $server->delete();
-
         return redirect()->route('servers.index')->with('error', json_encode($response->json()));
     }
 
@@ -254,7 +253,7 @@ public function show(Server $server)
     {
 
 
-        if($server->user_id != Auth::user()->id){ return back()->with('error', __('´This is not your Server!'));}
+        if($server->user_id != Auth::user()->id){ return back()->with('error', __('This is not your Server!'));}
         $serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
         $serverRelationships = $serverAttributes['relationships'];
         $serverLocationAttributes = $serverRelationships['location']['attributes'];
@@ -293,7 +292,7 @@ public function show(Server $server)
 
     public function upgrade(Server $server, Request $request)
     {
-        if($server->user_id != Auth::user()->id) return redirect()->route('servers.index');
+        if($server->user_id != Auth::user()->id || $server->suspended) return redirect()->route('servers.index');
         if(!isset($request->product_upgrade))
         {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('this product is the only one'));
@@ -315,24 +314,54 @@ public function upgrade(Server $server, Request $request)
         $checkResponse = Pterodactyl::checkNodeResources($node, $requireMemory, $requiredisk);
         if ($checkResponse == False) return redirect()->route('servers.index')->with('error', __("The node '" . $nodeName . "' doesn't have the required memory or disk left to upgrade the server."));
 
-        $priceupgrade = $newProduct->getHourlyPrice();
-
-        if ($priceupgrade < $oldProduct->getHourlyPrice()) {
-        $priceupgrade = 0;
-        }
-        if ($user->credits >= $priceupgrade && $user->credits >= $newProduct->minimum_credits)
+        // calculate the amount of credits that the user overpayed for the old product when canceling the server right now
+        // billing periods are hourly, daily, weekly, monthly, quarterly, half-annually, annually
+        $billingPeriod = $oldProduct->billing_period;
+        // seconds
+        $billingPeriods = [
+            'hourly' => 3600,
+            'daily' => 86400,
+            'weekly' => 604800,
+            'monthly' => 2592000,
+            'quarterly' => 7776000,
+            'half-annually' => 15552000,
+            'annually' => 31104000
+        ];
+        // Get the amount of hours the user has been using the server
+        $billingPeriodMultiplier = $billingPeriods[$billingPeriod];
+        $timeDifference = now()->diffInSeconds($server->last_billed);
+
+        error_log("Time DIFFERENCE!!!! ",$timeDifference);
+        // Calculate the price for the time the user has been using the server
+        $overpayedCredits = $oldProduct->price - $oldProduct->price * ($timeDifference / $billingPeriodMultiplier);
+
+
+        if ($user->credits >= $newProduct->price && $user->credits >= $newProduct->minimum_credits)
         {
-
-            $server->product_id = $request->product_upgrade;
-            $server->update();
             $server->allocation = $serverAttributes['allocation'];
+            // Update the server on the panel
             $response = Pterodactyl::updateServer($server, $newProduct);
             if ($response->failed()) return $this->serverCreationFailed($response, $server);
-            //update user balance
-            $user->decrement('credits', $priceupgrade);
+
+            // Remove the allocation property from the server object as it is not a column in the database
+            unset($server->allocation);
+            // Update the server on controlpanel
+            $server->update([
+                'product_id' => $newProduct->id,
+                'updated_at' => now(),
+                'last_billed' => now(),
+                'cancelled' => null,
+            ]);
+
+            // Refund the user the overpayed credits
+            if ($overpayedCredits > 0) $user->increment('credits', $overpayedCredits);
+
+            // Withdraw the credits for the new product
+            $user->decrement('credits', $newProduct->price); 
+
             //restart the server
             $response = Pterodactyl::powerAction($server, "restart");
-            if ($response->failed()) return redirect()->route('servers.index')->with('error', $response->json()['errors'][0]['detail']);
+            if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   '.$response->json()['errors'][0]['detail']);
             return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
         }
         else
diff --git a/resources/views/servers/settings.blade.php b/resources/views/servers/settings.blade.php
index 1a1b269b9..edad1f7fb 100644
--- a/resources/views/servers/settings.blade.php
+++ b/resources/views/servers/settings.blade.php
@@ -242,10 +242,7 @@ class="btn btn-info btn-md">
                                         </button>
                                     </div>
                                     <div class="modal-body card-body">
-                                        <strong>{{__("FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN")}}</strong>
-                                        <br>
-                                        <br>
-                                        <strong>{{__("YOUR PRODUCT")}} : </strong> {{ $server->product->name }}
+                                        <strong>{{__("Current Product")}}: </strong> {{ $server->product->name }}
                                         <br>
                                         <br>
 
@@ -255,12 +252,13 @@ class="btn btn-info btn-md">
                                             <option value="">{{__("Select the product")}}</option>
                                               @foreach($products as $product)
                                                   @if(in_array($server->egg, $product->eggs) && $product->id != $server->product->id && $product->disabled == false)
-                                                    <option value="{{ $product->id }}" @if($product->doesNotFit)disabled @endif>{{ $product->name }} [ {{ CREDITS_DISPLAY_NAME }} {{ $product->price }} @if($product->doesNotFit)] {{__('Server can´t fit on this node')}} @else @if($product->minimum_credits!=-1) /
+                                                    <option value="{{ $product->id }}" @if($product->doesNotFit)disabled @endif>{{ $product->name }} [ {{ CREDITS_DISPLAY_NAME }} {{ $product->price }} @if($product->doesNotFit)] {{__('Server can\'t fit on this node')}} @else @if($product->minimum_credits!=-1) /
                                                         {{__("Required")}}: {{$product->minimum_credits}} {{ CREDITS_DISPLAY_NAME }}@endif ] @endif</option>
                                                   @endif
                                               @endforeach
                                           </select>
-                                          <br> {{__("Once the Upgrade button is pressed, we will automatically deduct the amount for the first hour according to the new product from your credits")}}. <br>
+                                          
+                                          <br> <strong>{{__("Caution") }}:</strong> {{__("Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed")}}. <br>
                                           <br> {{__("Server will be automatically restarted once upgraded")}}
                                     </div>
                                     <div class="modal-footer card-body">

From a7c47bff64cc862892b19e383bcb062b6a5776a1 Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Tue, 22 Nov 2022 13:43:06 +0100
Subject: [PATCH 046/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20localization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/lang/bg.json | 20 +++++++++++---------
 resources/lang/bs.json | 18 ++++++++++--------
 resources/lang/cs.json | 24 +++++++++++++-----------
 resources/lang/de.json | 18 ++++++++++--------
 resources/lang/en.json | 26 ++++++++++++++------------
 resources/lang/es.json | 22 ++++++++++++----------
 resources/lang/fr.json | 18 ++++++++++--------
 resources/lang/he.json | 42 ++++++++++++++++++++++--------------------
 resources/lang/hi.json | 18 ++++++++++--------
 resources/lang/hu.json | 18 ++++++++++--------
 resources/lang/it.json | 18 ++++++++++--------
 resources/lang/nl.json | 18 ++++++++++--------
 resources/lang/pl.json | 18 ++++++++++--------
 resources/lang/pt.json | 18 ++++++++++--------
 resources/lang/ro.json | 18 ++++++++++--------
 resources/lang/ru.json | 20 +++++++++++---------
 resources/lang/sh.json | 16 +++++++++-------
 resources/lang/sk.json | 18 ++++++++++--------
 resources/lang/sr.json | 18 ++++++++++--------
 resources/lang/sv.json | 18 ++++++++++--------
 resources/lang/tr.json | 18 ++++++++++--------
 resources/lang/zh.json | 18 ++++++++++--------
 22 files changed, 242 insertions(+), 198 deletions(-)

diff --git a/resources/lang/bg.json b/resources/lang/bg.json
index b710be84c..4c3340d33 100644
--- a/resources/lang/bg.json
+++ b/resources/lang/bg.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Грешка при създаване на сървър",
     "Your servers have been suspended!": "Сървърите ви са спрени!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "За да активирате автоматично вашия сървър\/и, трябва да закупите повече кредити.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "За да активирате автоматично вашия сървър/и, трябва да закупите повече кредити.",
     "Purchase credits": "Купете кредити",
     "If you have any questions please let us know.": "При допълнителни въпроси, моля свържете се с нас.",
     "Regards": "Поздрави",
@@ -93,7 +93,7 @@
     "Getting started!": "Приготвяме се да започнем!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Език по подразбиране",
     "The fallback Language, if something goes wrong": "Резервният език, ако нещо се обърка",
     "Datable language": "Език с данни",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Езиков код на таблиците с данни. <br><strong>Пример:<\/strong> en-gb, fr_fr, de_de<br>Повече информация: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Езиков код на таблиците с данни. <br><strong>Пример:</strong> en-gb, fr_fr, de_de<br>Повече информация: ",
     "Auto-translate": "Автоматичен превод",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Ако това е отметнато, таблото за управление ще се преведе на езика на клиентите, ако е наличен",
     "Client Language-Switch": "Превключване на клиентски език",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Таксува кредити за първия час при създаване на сървър.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Въведете URL адреса на вашата инсталация на PHPMyAdmin. <strong>Без крайна наклонена черта!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Въведете URL адреса на вашата инсталация на PHPMyAdmin. <strong>Без крайна наклонена черта!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Въведете URL адреса на вашата инсталация на Pterodactyl.<strong>Без крайна наклонена черта!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Въведете URL адреса на вашата инсталация на Pterodactyl.<strong>Без крайна наклонена черта!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Kлюч",
     "Enter the API Key to your Pterodactyl installation.": "Въведете API ключа към вашата инсталация на Pterodactyl.",
     "Force Discord verification": "Принудително потвърждаване на Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Ваучер може да се използва само веднъж на потребител. Uses определя броя на различните потребители, които могат да използват този ваучер.",
     "Max": "Макс",
     "Expires at": "Изтича на",
-    "Used \/ Uses": "Използван \/ Използвания",
+    "Used / Uses": "Използван / Използвания",
     "Expires": "Изтича",
     "Sign in to start your session": "Влезте, за да започнете сесията си",
     "Password": "Парола",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Няма свързани Node-ове!",
     "No nests available!": "Няма налични Nest-ове!",
     "No eggs have been linked!": "Няма свързани Egg-ове!",
-    "Software \/ Games": "Софтуер \/ Игри",
+    "Software / Games": "Софтуер / Игри",
     "Please select software ...": "Моля, изберете софтуер...",
     "---": "---",
     "Specification ": "Спецификация ",
@@ -460,5 +460,7 @@
     "tr": "Турски",
     "ru": "Руски",
     "sv": "Swedish",
-    "sk": "Slovakish"
-}
\ No newline at end of file
+    "sk": "Slovakish",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
+    "Caution": "Внимание"
+}
diff --git a/resources/lang/bs.json b/resources/lang/bs.json
index 1a5e73c37..1ee54bee1 100644
--- a/resources/lang/bs.json
+++ b/resources/lang/bs.json
@@ -80,7 +80,7 @@
     "User ID": "User ID",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -173,7 +173,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -214,9 +214,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -284,7 +284,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -354,7 +354,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -441,5 +441,7 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Russian"
-}
\ No newline at end of file
+    "ru": "Russian",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution"
+}
diff --git a/resources/lang/cs.json b/resources/lang/cs.json
index 6e4eb0064..04dc0090e 100644
--- a/resources/lang/cs.json
+++ b/resources/lang/cs.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Někdo se zaregistroval pomocí vašeho kódu!",
     "Server Creation Error": "Chyba při vytváření serveru",
     "Your servers have been suspended!": "Vaše servery byly pozastaveny!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Pro opětovné spuštění vašich serverů dobijte prosím kredity.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Pro opětovné spuštění vašich serverů dobijte prosím kredity.",
     "Purchase credits": "Zakoupit kredity",
     "If you have any questions please let us know.": "Máte-li jakékoli dotazy, dejte nám vědět.",
     "Regards": "S pozdravem",
@@ -93,7 +93,7 @@
     "Getting started!": "Začínáme!",
     "Welcome to our dashboard": "Vítejte v našem ovládacím panelu",
     "Verification": "Ověření",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Můžete ověřit svojí e-mail adresu a přiojit váš Discord účet.",
+    "You can verify your e-mail address and link/verify your Discord account.": "Můžete ověřit svojí e-mail adresu a přiojit váš Discord účet.",
     "Information": "Informace",
     "This dashboard can be used to create and delete servers": "Tento panel může použít pro vytvoření a mazání serverů",
     "These servers can be used and managed on our pterodactyl panel": "Tyto servery můžete používat a spravovat v našem pterodactyl panelu",
@@ -114,7 +114,7 @@
     "Token": "Token",
     "Last used": "Naposledy použito",
     "Are you sure you wish to delete?": "Opravdu si přejete odstranit?",
-    "Nests": "Software\/hra",
+    "Nests": "Software/hra",
     "Sync": "Synchronizovat",
     "Active": "Aktivní",
     "ID": "ID",
@@ -187,7 +187,7 @@
     "Default language": "Výchozí jazyk",
     "The fallback Language, if something goes wrong": "Záložní jazyk, kdyby se něco pokazilo",
     "Datable language": "Jazyk tabulek",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Kód jazyka datových tabulek. <br><strong>Příklad:<\/strong> en-gb, fr_fr, de_de<br>Více informací: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Kód jazyka datových tabulek. <br><strong>Příklad:</strong> en-gb, fr_fr, de_de<br>Více informací: ",
     "Auto-translate": "Automatický překlad",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Pokud je tohle zaškrtlé, Panel bude přeložen do Jazyka klienta (pokud to je možné)",
     "Client Language-Switch": "Povolit uživatelům změnu jazyka",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Po vytvoření služby náčtuje ihned první hodinu.",
     "Credits Display Name": "Název kreditů",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Vložte URL vaší instalace PHPmyAdmin. <strong>Bez koncového lomítka!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Vložte URL vaší instalace PHPmyAdmin. <strong>Bez koncového lomítka!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Vložte URL vaší instalace Pterodactyl. <strong>Bez koncového lomítka!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Vložte URL vaší instalace Pterodactyl. <strong>Bez koncového lomítka!</strong>",
     "Pterodactyl API Key": "Pterodactyl API klíč",
     "Enter the API Key to your Pterodactyl installation.": "Zadejte API klíč Vaší Pterodactyl instalace.",
     "Force Discord verification": "Vynutit ověření skrz Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Poukaz může být použit pouze jednou na uživatele. Počet použití upravuje počet různých uživatelů, kteří můžou poukaz použít.",
     "Max": "Maximum",
     "Expires at": "Vyprší",
-    "Used \/ Uses": "Použito",
+    "Used / Uses": "Použito",
     "Expires": "Vyprší",
     "Sign in to start your session": "Pro pokračování se prosím přihlašte",
     "Password": "Heslo",
@@ -386,9 +386,9 @@
     "Sync now": "Synchronizovat nyní",
     "No products available!": "Žádné dostupné balíčky!",
     "No nodes have been linked!": "Nebyly propojeny žádné uzly!",
-    "No nests available!": "Žádný dostupný software\/hry!",
+    "No nests available!": "Žádný dostupný software/hry!",
     "No eggs have been linked!": "Nebyly nastaveny žádné distribuce!",
-    "Software \/ Games": "Software\/hry",
+    "Software / Games": "Software/hry",
     "Please select software ...": "Prosím zvolte software ...",
     "---": "----",
     "Specification ": "Specifikace ",
@@ -460,5 +460,7 @@
     "tr": "Turečtina",
     "ru": "Ruština",
     "sv": "Švédština",
-    "sk": "Slovensky"
-}
\ No newline at end of file
+    "sk": "Slovensky",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
+    "Caution": "Upozornění"
+}
diff --git a/resources/lang/de.json b/resources/lang/de.json
index 97988290b..1e8a8402d 100644
--- a/resources/lang/de.json
+++ b/resources/lang/de.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Jemand hat sich mit deinem Code registriert!",
     "Server Creation Error": "Fehler beim erstellen des Servers",
     "Your servers have been suspended!": "Deine Server wurden pausiert",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Um deine Server zu reaktivieren, musst du mehr Credits kaufen!",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Um deine Server zu reaktivieren, musst du mehr Credits kaufen!",
     "Purchase credits": "Credits kaufen",
     "If you have any questions please let us know.": "Solltest du weiter fragen haben, melde dich gerne beim Support!",
     "Regards": "mit freundlichen Grüßen",
@@ -93,7 +93,7 @@
     "Getting started!": "Den Anfang machen!",
     "Welcome to our dashboard": "Willkommen in unserem Dashboard",
     "Verification": "Verifizierung",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Du kannst deine Email-Adresse und deinen Discord account verifizieren.",
+    "You can verify your e-mail address and link/verify your Discord account.": "Du kannst deine Email-Adresse und deinen Discord account verifizieren.",
     "Information": "Hinweis",
     "This dashboard can be used to create and delete servers": "Dieses Dashboard kann benutzt werden um Server zu erstellen und zu löschen",
     "These servers can be used and managed on our pterodactyl panel": "Die Server werden von unserem Pterodactyl-Panel aus gemanaged",
@@ -187,7 +187,7 @@
     "Default language": "Standardsprache",
     "The fallback Language, if something goes wrong": "Die Rückfall-Sprache, falls etwas schief geht",
     "Datable language": "Tabellensprache",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Der Sprachcode der Tabellensprache. <br><strong>Beispiel:<\/strong> en-gb, fr_fr, de_de<br>Weitere Informationen: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Der Sprachcode der Tabellensprache. <br><strong>Beispiel:</strong> en-gb, fr_fr, de_de<br>Weitere Informationen: ",
     "Auto-translate": "Automatisches übersetzen",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Wenn dies aktiviert ist, übersetzt sich das Dashboard selbst in die Sprache des Clients, sofern diese verfügbar ist",
     "Client Language-Switch": "Nutzer Sprachumschaltung",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Rechne den ersten stündlichen Anteil direkt bei Erstellung des Servers ab.",
     "Credits Display Name": "Credits Anzeigename",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Geben Sie die URL zu Ihrer PHPMyAdmin-Installation ein. <strong>Ohne abschließendendes Slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Geben Sie die URL zu Ihrer PHPMyAdmin-Installation ein. <strong>Ohne abschließendendes Slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Geben Sie die URL zu Ihrer Pterodactyl-Installation ein. <strong>Ohne abschließendendes Slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Geben Sie die URL zu Ihrer Pterodactyl-Installation ein. <strong>Ohne abschließendendes Slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Schlüssel",
     "Enter the API Key to your Pterodactyl installation.": "Geben Sie den API-Schlüssel zu Ihrer Pterodactyl-Installation ein.",
     "Force Discord verification": "Discord Verifikation erzwingen",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Ein Gutschein kann von einem User nur einmal eingelöst werden. \"Benutzungen\" setzt die Anzahl an Usern die diesen Gutschein einlösen können.",
     "Max": "Max",
     "Expires at": "Läuft ab am",
-    "Used \/ Uses": "Benutzungen",
+    "Used / Uses": "Benutzungen",
     "Expires": "Ablauf",
     "Sign in to start your session": "Melde dich an um das Dashboard zu benutzen",
     "Password": "Passwort",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Es wurde keine Nodes verknüpft",
     "No nests available!": "Keine Nests verfügbar",
     "No eggs have been linked!": "Es wurde keine Eggs verknüpft",
-    "Software \/ Games": "Software \/ Spiele",
+    "Software / Games": "Software / Spiele",
     "Please select software ...": "Bitte Software auswählen",
     "---": "--",
     "Specification ": "Spezifikation",
@@ -483,5 +483,7 @@
     "Cancel Server": "Server kündigen",
     "Yes, cancel it!": "Ja, löschen!",
     "No, abort!": "Abbrechen",
-    "Billing period": "Abrechnungsperiode"
+    "Billing period": "Abrechnungsperiode",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Das Upgrade/Downgrade Ihres Servers wird Ihre Abrechnungsperiode auf \"jetzt\" zurücksetzen. Ihre überzahlten Credits werden erstattet. Der Preis für die neue Abrechnungsperiode wird abgebucht.",
+    "Caution": "Achtung"
 }
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 0e557bb71..07d646083 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -100,7 +100,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -112,7 +112,7 @@
     "Getting started!": "Getting started!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -212,7 +212,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -269,9 +269,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Pterodactyl Admin-Account API Key": "Pterodactyl Admin-Account API Key",
@@ -352,7 +352,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -409,7 +409,7 @@
     "Actions": "Actions",
     "Add To Blacklist": "Add To Blacklist",
     "please make the best of it": "please make the best of it",
-    "Please note, the blacklist will make the user unable to make a ticket\/reply again": "Please note, the blacklist will make the user unable to make a ticket\/reply again",
+    "Please note, the blacklist will make the user unable to make a ticket/reply again": "Please note, the blacklist will make the user unable to make a ticket/reply again",
     "Ticket": "Ticket",
     "Category": "Category",
     "Last Updated": "Last Updated",
@@ -439,7 +439,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -472,9 +472,9 @@
     "Hourly Price": "Hourly Price",
     "Monthly Price": "Monthly Price",
     "MySQL Database": "MySQL Database",
-    "To enable the upgrade\/downgrade system, please set your Ptero Admin-User API Key in the Settings!": "To enable the upgrade\/downgrade system, please set your Ptero Admin-User API Key in the Settings!",
-    "Upgrade \/ Downgrade": "Upgrade \/ Downgrade",
-    "Upgrade\/Downgrade Server": "Upgrade\/Downgrade Server",
+    "To enable the upgrade/downgrade system, please set your Ptero Admin-User API Key in the Settings!": "To enable the upgrade/downgrade system, please set your Ptero Admin-User API Key in the Settings!",
+    "Upgrade / Downgrade": "Upgrade / Downgrade",
+    "Upgrade/Downgrade Server": "Upgrade/Downgrade Server",
     "FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN": "FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN",
     "YOUR PRODUCT": "YOUR PRODUCT",
     "Select the product": "Select the product",
@@ -551,5 +551,7 @@
     "Cancel Server": "Cancel Server",
     "Yes, cancel it!": "Yes, cancel it!",
     "No, abort!": "No, abort!",
-    "Billing period": "Billing period"
+    "Billing period": "Billing period",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution"
 }
diff --git a/resources/lang/es.json b/resources/lang/es.json
index af47f9bc3..818d8e132 100644
--- a/resources/lang/es.json
+++ b/resources/lang/es.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Error de creación del servidor",
     "Your servers have been suspended!": "¡Sus servidores han sido suspendidos!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Para volver a habilitar automáticamente sus servidores, debe comprar más créditos.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Para volver a habilitar automáticamente sus servidores, debe comprar más créditos.",
     "Purchase credits": "Comprar Créditos",
     "If you have any questions please let us know.": "Si tienes más preguntas, por favor háznoslas saber.",
     "Regards": "Atentamente",
@@ -93,7 +93,7 @@
     "Getting started!": "¡Empezando!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Idioma predeterminado",
     "The fallback Language, if something goes wrong": "El lenguaje alternativo, si algo sale mal",
     "Datable language": "Lenguaje de tabla de datos",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "El código de idioma de las tablas de datos. <br><strong>Ejemplo:<\/strong> en-gb, fr_fr, de_de<br>Más información: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "El código de idioma de las tablas de datos. <br><strong>Ejemplo:</strong> en-gb, fr_fr, de_de<br>Más información: ",
     "Auto-translate": "Traducir automáticamente",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Si está marcado, el Tablero se traducirá solo al idioma del Cliente, si está disponible",
     "Client Language-Switch": "Cambio de idioma del cliente",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Carga la primera hora de créditos al crear un servidor.",
     "Credits Display Name": "Nombre de los Créditos para mostrar",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Ingrese la URL de su instalación de PHPMyAdmin. <strong>¡Sin una barra diagonal final!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Ingrese la URL de su instalación de PHPMyAdmin. <strong>¡Sin una barra diagonal final!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Introduzca la URL de su instalación de Pterodactyl. <strong>¡Sin una barra diagonal final!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Introduzca la URL de su instalación de Pterodactyl. <strong>¡Sin una barra diagonal final!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Ingrese la API Key para su instalación de Pterodactyl.",
     "Force Discord verification": "Forzar verificación de Discord",
@@ -263,7 +263,7 @@
     "Select panel favicon": "Seleccionar favicon del panel",
     "Store": "Tienda",
     "Server Slots": "Server Slots",
-    "Currency code": "Código de divisa\/moneda",
+    "Currency code": "Código de divisa/moneda",
     "Checkout the paypal docs to select the appropriate code": "Consulte los documentos de PayPal para seleccionar el código apropiado",
     "Quantity": "Cantidad",
     "Amount given to the user after purchasing": "Importe dado al usuario después de la compra",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "El descuento solo se puede utilizar una vez por usuario. Los usos especifica el número de usuarios diferentes que pueden utilizar este cupón.",
     "Max": "Máx",
     "Expires at": "Expira el",
-    "Used \/ Uses": "Uso \/ Usos",
+    "Used / Uses": "Uso / Usos",
     "Expires": "Expira",
     "Sign in to start your session": "Iniciar sesión para comenzar",
     "Password": "Contraseña",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "¡No se han vinculado nodos!",
     "No nests available!": "¡No hay nidos disponibles!",
     "No eggs have been linked!": "¡No se han vinculado huevos!",
-    "Software \/ Games": "Software \/ Juegos",
+    "Software / Games": "Software / Juegos",
     "Please select software ...": "Seleccione el software...",
     "---": "---",
     "Specification ": "Especificación ",
@@ -460,5 +460,7 @@
     "tr": "Turco",
     "ru": "Ruso",
     "sv": "Sueco",
-    "sk": "Eslovaco"
-}
\ No newline at end of file
+    "sk": "Eslovaco",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Actualizar/Reducir el servidor restablecerá su ciclo de facturación a ahora. Se reembolsarán los créditos sobrepagados. El precio del nuevo ciclo de facturación se retirará",
+    "Caution": "Cuidado"
+}
diff --git a/resources/lang/fr.json b/resources/lang/fr.json
index 7c21a7359..c59959a98 100644
--- a/resources/lang/fr.json
+++ b/resources/lang/fr.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Erreur lors de la création de votre serveur",
     "Your servers have been suspended!": "Votre serveur à été suspendu !",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Pour réactiver automatiquement votre ou vos serveurs, vous devez racheter des crédits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Pour réactiver automatiquement votre ou vos serveurs, vous devez racheter des crédits.",
     "Purchase credits": "Acheter des crédits",
     "If you have any questions please let us know.": "N'hésitez pas à nous contacter si vous avez des questions.",
     "Regards": "Cordialement",
@@ -93,7 +93,7 @@
     "Getting started!": "Commencer !",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Langue par défaut",
     "The fallback Language, if something goes wrong": "La langue de repli, si quelque chose ne va pas",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Le code ne peut être utilisé qu'une seule fois. L'utilisation spécifie le nombre d'utilisateurs différents qui peuvent utiliser ce code.",
     "Max": "Max",
     "Expires at": "Expire à",
-    "Used \/ Uses": "Utilisé \/ Utilisations",
+    "Used / Uses": "Utilisé / Utilisations",
     "Expires": "Expire",
     "Sign in to start your session": "Identifiez-vous pour commencer votre session",
     "Password": "Mot de passe",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Aucune node n'a été lié !",
     "No nests available!": "Aucun nests disponible !",
     "No eggs have been linked!": "Aucun eggs n'a été lié !",
-    "Software \/ Games": "Logiciels \/ Jeux",
+    "Software / Games": "Logiciels / Jeux",
     "Please select software ...": "Veuillez sélectionner...",
     "---": "---",
     "Specification ": "Spécification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Montant en toutes lettres",
     "Please pay until": "Veuillez payer avant",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Mettre à niveau / Réduire votre serveur réinitialisera votre cycle de facturation à maintenant. Vos crédits surpayés seront remboursés. Le prix du nouveau cycle de facturation sera débité",
+    "Caution": "Attention",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -461,4 +463,4 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/he.json b/resources/lang/he.json
index da4d205bd..a64fde04a 100644
--- a/resources/lang/he.json
+++ b/resources/lang/he.json
@@ -60,8 +60,8 @@
     "You ran out of Credits": "נגמר לך המטבעות",
     "Profile updated": "הפרופיל עודכן",
     "Server limit reached!": "הגעת להגבלת השרתים!",
-    "You are required to verify your email address before you can create a server.": "אתה מדרש לאמת את כתובת המייל שלך לפני שתוכל\/י ליצור שרת",
-    "You are required to link your discord account before you can create a server.": "אתה חייב לקשר את החשבון דיסקורד שלך לפני שתוכל\/י ליצור שרת",
+    "You are required to verify your email address before you can create a server.": "אתה מדרש לאמת את כתובת המייל שלך לפני שתוכל/י ליצור שרת",
+    "You are required to link your discord account before you can create a server.": "אתה חייב לקשר את החשבון דיסקורד שלך לפני שתוכל/י ליצור שרת",
     "Server created": "השרת נוצר",
     "No allocations satisfying the requirements for automatic deployment on this node were found.": "לא נמצאו הקצאות העומדות בדרישות לפריסה אוטומטית בשרת זה.",
     "You are required to verify your email address before you can purchase credits.": "אתה נדרש לאמת את כתובת המייל שלך לפני רכישת מטבעות",
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "שגיאה ביצירת שרת",
     "Your servers have been suspended!": "השרת שלך מושעה!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "כדי להפעיל מחדש את השרתים שלך באופן אוטומטי, עליך לרכוש מטבעות נוספות.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "כדי להפעיל מחדש את השרתים שלך באופן אוטומטי, עליך לרכוש מטבעות נוספות.",
     "Purchase credits": "לרכישת מטבעות",
     "If you have any questions please let us know.": "אם יש לכם כל שאלה תיידעו אותנו",
     "Regards": "בברכה",
@@ -93,7 +93,7 @@
     "Getting started!": "מתחילים!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -125,7 +125,7 @@
     "Admin Overview": "סקירת מנהל",
     "Support server": "שרת תמיכה",
     "Documentation": "מדריך",
-    "Github": "Github\/גיטאהב",
+    "Github": "Github/גיטאהב",
     "Support ControlPanel": "תמיכת ControlPanel",
     "Servers": "שרתים",
     "Total": "בסך הכל",
@@ -156,7 +156,7 @@
     "Minimum": "מינימום",
     "Setting to -1 will use the value from configuration.": "הגדרות ל -1 ישתמש בערך מ configuration.",
     "IO": "IO",
-    "Databases": "Databases\/ממסד נתונים",
+    "Databases": "Databases/ממסד נתונים",
     "Backups": "גיבויים",
     "Allocations": "הקצאות",
     "Product Linking": "מוצרים מקושרים",
@@ -187,7 +187,7 @@
     "Default language": "שפת ברירת מחדל",
     "The fallback Language, if something goes wrong": "אם משהו משתבש",
     "Datable language": "שפה ניתנת לנתונים",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "טבלת הנתונים של השפות.<br><strong>לדוגמא:<\/strong> en-gb, fr_fr, de_de<br>למידע נוסף: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "טבלת הנתונים של השפות.<br><strong>לדוגמא:</strong> en-gb, fr_fr, de_de<br>למידע נוסף: ",
     "Auto-translate": "תרגום אוטומטי",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "אם זה מסומן, Dashboard יתרגם את עצמו לשפת הלקוח, אם זמין",
     "Client Language-Switch": "החלפת שפת לקוח",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Cגובה מטבעות בשווי השעה הראשונה בעת יצירת שרת.",
     "Credits Display Name": "שם המטבעות",
     "PHPMyAdmin URL": "קישור PHPMyAdmin",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "הכנס את הקישור to פיחפי. <strong>בלי צלייה נגררת!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "הכנס את הקישור to פיחפי. <strong>בלי צלייה נגררת!</strong>",
     "Pterodactyl URL": "קישור Pterodactyl",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API מפתח",
     "Enter the API Key to your Pterodactyl installation.": "הכנס את מפתח ה API Pterodactyl installation.",
     "Force Discord verification": "אימות דיסקורד חובה",
@@ -300,12 +300,12 @@
     "Notifications": "התראות",
     "All": "הכל",
     "Send via": "שליחה באמצאות",
-    "Database": "Database\/מאגר נתונים",
+    "Database": "Database/מאגר נתונים",
     "Content": "קשר",
     "Server limit": "הגבלת שרת",
-    "Discord": "Discord\/דיסקורד",
+    "Discord": "Discord/דיסקורד",
     "Usage": "נוהג",
-    "IP": "IP\/אייפי",
+    "IP": "IP/אייפי",
     "Referals": "Referals",
     "Vouchers": "קופונים",
     "Voucher details": "פרטי קופון",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "ניתן להשתמש בשובר פעם אחת בלבד לכל משתמש. שימושים מציינים את מספר המשתמשים השונים שיכולים להשתמש בשובר זה.",
     "Max": "מקסימום",
     "Expires at": "יפוג ב",
-    "Used \/ Uses": "משומש \/ שימושים",
+    "Used / Uses": "משומש / שימושים",
     "Expires": "פגי תוקף",
     "Sign in to start your session": "התחבר על מנת להתחיל",
     "Password": "סיסמה",
@@ -339,7 +339,7 @@
     "Before proceeding, please check your email for a verification link.": "לפני שתמשיך, אנא בדוק באימייל שלך קישור לאימות.",
     "If you did not receive the email": "אם לא קיבלת את המייל",
     "click here to request another": "לחץ כאן כדי לבקש אחר",
-    "per month": "\/חודש",
+    "per month": "/חודש",
     "Out of Credits in": "נגמרו המטבעות ב",
     "Home": "בית",
     "Language": "שפה",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "שרתים לא מקושרים!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "אין eggs מקושרים",
-    "Software \/ Games": "תוכנה \/ משחקים",
+    "Software / Games": "תוכנה / משחקים",
     "Please select software ...": "בבקשה תחבר תוכנה ...",
     "---": "---",
     "Specification ": "ציין ",
@@ -411,9 +411,9 @@
     "Specification": "לציין",
     "Resource plan": "תוכנית משאבים",
     "RAM": "RAM",
-    "MySQL Databases": "בסיס הנתונים <bdi dir=\"ltr\">MySQL<\/bdi>",
-    "per Hour": "\/שעה",
-    "per Month": "\/חודש",
+    "MySQL Databases": "בסיס הנתונים <bdi dir=\"ltr\">MySQL</bdi>",
+    "per Hour": "/שעה",
+    "per Month": "/חודש",
     "Manage": "לנהל",
     "Are you sure?": "האם אתה בטוח?",
     "This is an irreversible action, all files of this server will be removed.": "זוהי פעולה בלתי הפיכה, כל הקבצים של שרת זה יוסרו.",
@@ -460,5 +460,7 @@
     "tr": "טורקית",
     "ru": "רוסית",
     "sv": "שוודית",
-    "sk": "סלובקית"
-}
\ No newline at end of file
+    "sk": "סלובקית",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "שדרוג / הורדת שרת יאפס את מחזור החיוב שלך לעכשיו. הקרדיטים ששילמת יוחזרו. המחיר למחזור החיוב החדש יוחסם",
+    "Caution": "אזהרה"
+}
diff --git a/resources/lang/hi.json b/resources/lang/hi.json
index 68eba9f93..bdf5188a2 100644
--- a/resources/lang/hi.json
+++ b/resources/lang/hi.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "सर्वर निर्माण त्रुटि",
     "Your servers have been suspended!": "आपके सर्वर निलंबित कर दिए गए हैं!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "अपने सर्वर\/सर्वर को स्वचालित रूप से पुन: सक्षम करने के लिए, आपको अधिक क्रेडिट खरीदने की आवश्यकता है।",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "अपने सर्वर/सर्वर को स्वचालित रूप से पुन: सक्षम करने के लिए, आपको अधिक क्रेडिट खरीदने की आवश्यकता है।",
     "Purchase credits": "क्रेडिट खरीदें",
     "If you have any questions please let us know.": "यदि आपके पास कोई प्रश्न है, तो हमें बताएं।",
     "Regards": "सादर",
@@ -93,7 +93,7 @@
     "Getting started!": "शुरू करना!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "डिफ़ॉल्ट भाषा",
     "The fallback Language, if something goes wrong": "फ़ॉलबैक भाषा, अगर कुछ गलत हो जाता है",
     "Datable language": "डेटा योग्य भाषा",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "डेटाटेबल्स लैंग-कोड। <br><strong>उदाहरण:<\/strong> en-gb, fr_fr, de_de<br>अधिक जानकारी: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "डेटाटेबल्स लैंग-कोड। <br><strong>उदाहरण:</strong> en-gb, fr_fr, de_de<br>अधिक जानकारी: ",
     "Auto-translate": "ऑटो का अनुवाद",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "यदि यह चेक किया जाता है, तो डैशबोर्ड स्वयं को क्लाइंट भाषा में अनुवाद करेगा, यदि उपलब्ध हो",
     "Client Language-Switch": "क्लाइंट भाषा-स्विच",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "सर्वर बनाने पर पहले घंटे के क्रेडिट का शुल्क लेता है।",
     "Credits Display Name": "क्रेडिट प्रदर्शन नाम",
     "PHPMyAdmin URL": "PhpMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "अपने PHPMyAdmin इंस्टॉलेशन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "अपने PHPMyAdmin इंस्टॉलेशन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!</strong>",
     "Pterodactyl URL": "पटरोडैक्टाइल यूआरएल",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "अपने Pterodactyl संस्थापन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "अपने Pterodactyl संस्थापन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!</strong>",
     "Pterodactyl API Key": "पटरोडैक्टाइल एपीआई कुंजी",
     "Enter the API Key to your Pterodactyl installation.": "अपने Pterodactyl स्थापना के लिए API कुंजी दर्ज करें।",
     "Force Discord verification": "बल विवाद सत्यापन",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "वाउचर प्रति उपयोगकर्ता केवल एक बार उपयोग किया जा सकता है। उपयोग इस वाउचर का उपयोग करने वाले विभिन्न उपयोगकर्ताओं की संख्या को निर्दिष्ट करता है।",
     "Max": "मैक्स",
     "Expires at": "पर समाप्त हो रहा है",
-    "Used \/ Uses": "प्रयुक्त \/ उपयोग",
+    "Used / Uses": "प्रयुक्त / उपयोग",
     "Expires": "समय-सीमा समाप्त",
     "Sign in to start your session": "अपना सत्र शुरू करने के लिए साइन इन करें",
     "Password": "पासवर्ड",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "कोई नोड लिंक नहीं किया गया है!",
     "No nests available!": "कोई घोंसला उपलब्ध नहीं है!",
     "No eggs have been linked!": "कोई अंडे नहीं जोड़े गए हैं!",
-    "Software \/ Games": "सॉफ्टवेयर \/ खेल",
+    "Software / Games": "सॉफ्टवेयर / खेल",
     "Please select software ...": "कृपया सॉफ्टवेयर चुनें...",
     "---": "---",
     "Specification ": "विनिर्देश",
@@ -447,6 +447,8 @@
     "Notes": "टिप्पणियाँ",
     "Amount in words": "राशि शब्दों में",
     "Please pay until": "कृपया भुगतान करें",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "अपने सर्वर को अपग्रेड / डाउनग्रेड करने से आपका बिलिंग साइकिल अब तक रीसेट हो जाएगा। आपके ओवरपेड क्रेडिट वापस किया जाएगा। नए बिलिंग साइकिल के लिए की गई मूल्य निकाला जाएगा",
+    "Caution": "सावधान",
     "cs": "चेक",
     "de": "जर्मन",
     "en": "अंग्रेज़ी",
@@ -461,4 +463,4 @@
     "ru": "रूसी",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/hu.json b/resources/lang/hu.json
index d6fbef0c3..87c6c7fca 100644
--- a/resources/lang/hu.json
+++ b/resources/lang/hu.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Valaki regisztrált a te Kódoddal!",
     "Server Creation Error": "Hiba a szerver készítése közben",
     "Your servers have been suspended!": "A szervered fel lett függesztve!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "A szervered\/szervereid autómatikus újraengedélyezéséhez Kreditet kell vásárolnod.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "A szervered/szervereid autómatikus újraengedélyezéséhez Kreditet kell vásárolnod.",
     "Purchase credits": "Kreditek vásárlása",
     "If you have any questions please let us know.": "Ha kérdésed van, kérjük fordulj hozzánk.",
     "Regards": "Üdvözlettel",
@@ -93,7 +93,7 @@
     "Getting started!": "Kezdhetjük!",
     "Welcome to our dashboard": "Üdvözlünk az Irányítópultban",
     "Verification": "Hitelesítés",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Hitelesíteni tudod az email címedet és a Discord fiókodat.",
+    "You can verify your e-mail address and link/verify your Discord account.": "Hitelesíteni tudod az email címedet és a Discord fiókodat.",
     "Information": "Információk",
     "This dashboard can be used to create and delete servers": "Ebben az Irányítópultban szervereket tudsz létrehozni és törölni",
     "These servers can be used and managed on our pterodactyl panel": "Ezeket a szervereket a Pterodactyl panelben tudod kezelni",
@@ -187,7 +187,7 @@
     "Default language": "Alapértelmezett nyelv",
     "The fallback Language, if something goes wrong": "A tartalék nyelv, ha bármi rosszul működne",
     "Datable language": "Keltezhető nyelv",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Az adattáblák kódnyelve. <br><strong>Például:<\/strong> en-gb, fr_fr, de_de<br>Több információ: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Az adattáblák kódnyelve. <br><strong>Például:</strong> en-gb, fr_fr, de_de<br>Több információ: ",
     "Auto-translate": "Autómatikus fordítás",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Ha be van kapcsolva, akkor az Irányítópult autómatikusan le lesz fordítva a Kliens által használt nyelvre, ha az elérhető",
     "Client Language-Switch": "Kliens nyelv váltás",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Első óra kifizetése szerver létrehozásnál.",
     "Credits Display Name": "Kredit megnevezése",
     "PHPMyAdmin URL": "PHPMyAdmin Hivatkozás",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Írd be a hivatkozást a PHPMyAdmin telepítéséhez. <strong>A zárjó perjel nélkül!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Írd be a hivatkozást a PHPMyAdmin telepítéséhez. <strong>A zárjó perjel nélkül!</strong>",
     "Pterodactyl URL": "Pterodactyl Hivatkozás",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Írd be a hivatkozást a Pterodactyl telepítéséhez. <strong>A zárjó perjel nélkül!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Írd be a hivatkozást a Pterodactyl telepítéséhez. <strong>A zárjó perjel nélkül!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Kulcs",
     "Enter the API Key to your Pterodactyl installation.": "Írd be az API Kulcsot a Pterodactyl telepítéséhez.",
     "Force Discord verification": "Discord hitelesítés kötelezése",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Az utalványt egy felhasználó csak egyszer használhatja fel. Ezzel meg tudod adni, hogy hány felhasználó tudja felhasználni az utalványt.",
     "Max": "Max",
     "Expires at": "Lejárás ideje",
-    "Used \/ Uses": "Felhasználva \/ Felhasználások száma",
+    "Used / Uses": "Felhasználva / Felhasználások száma",
     "Expires": "Lejár",
     "Sign in to start your session": "Jelentkezz be a munkamenet elindításához",
     "Password": "Jelszó",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Nem lett csomópont hozzácsatolva!",
     "No nests available!": "Nincs elérhető fészek!",
     "No eggs have been linked!": "Nem lett tojás hozzácsatolva!",
-    "Software \/ Games": "Szoftver \/ Játékok",
+    "Software / Games": "Szoftver / Játékok",
     "Please select software ...": "Szoftver kiválasztása ...",
     "---": "---",
     "Specification ": "Specifikációk ",
@@ -447,6 +447,8 @@
     "Notes": "Jegyzetek",
     "Amount in words": "Mennyiség szavakban",
     "Please pay until": "Fizetési határidő",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "A szerver frissítése / lefrissítése visszaállítja a számlázási ciklust az aktuálisra. A túlfizetett Kreditet visszatérítjük. A számlázási ciklus új ára lesz kivonva",
+    "Caution": "Figyelem",
     "cs": "Cseh",
     "de": "Német",
     "en": "Angol",
@@ -461,4 +463,4 @@
     "ru": "Orosz",
     "sv": "Svéd",
     "sk": "Szlovák"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/it.json b/resources/lang/it.json
index 379bad4f3..21fabe898 100644
--- a/resources/lang/it.json
+++ b/resources/lang/it.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Errore di creazione del server",
     "Your servers have been suspended!": "I tuoi server sono stati sospesi!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Per ri-abilitare i tuoi server automaticamente, devi acquistare più crediti.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Per ri-abilitare i tuoi server automaticamente, devi acquistare più crediti.",
     "Purchase credits": "Acquista crediti",
     "If you have any questions please let us know.": "Se hai una domanda faccelo sapere.",
     "Regards": "Cordialmente",
@@ -93,7 +93,7 @@
     "Getting started!": "Come iniziare!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Lingua predefinita",
     "The fallback Language, if something goes wrong": "La lingua secondaria, se qualcosa va storto",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Il lang-code dei datatables. <br><strong>Esempio:<\/strong> en-gb, fr_fr, de_de<br>Piu informazioni: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Il lang-code dei datatables. <br><strong>Esempio:</strong> en-gb, fr_fr, de_de<br>Piu informazioni: ",
     "Auto-translate": "Traduzione-automatica",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Se questo è abilitato la dashboard si traducerà automaticamente alla lingua dei clienti, se disponibile",
     "Client Language-Switch": "Switch delle lingue dei clienti",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Addebita la prima ora in crediti alla creazione di un server.",
     "Credits Display Name": "Nome di Visualizzazione dei Crediti",
     "PHPMyAdmin URL": "URL PHPMyAdmin",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Inserisci l'URL alla tua installazione di PHPMyAdmin. <strong>Senza lo slash finale!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Inserisci l'URL alla tua installazione di PHPMyAdmin. <strong>Senza lo slash finale!</strong>",
     "Pterodactyl URL": "URL di Pterodactyl",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Inserisci l'URL alla tua installazione di Pterodactyl. <strong>Senza un trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Inserisci l'URL alla tua installazione di Pterodactyl. <strong>Senza un trailing slash!</strong>",
     "Pterodactyl API Key": "Chiave API di Pterodactyl",
     "Enter the API Key to your Pterodactyl installation.": "Inserisci la Chiave API alla tua installazione di Pterodactyl.",
     "Force Discord verification": "Forza la verifica di Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Un voucher può essere utilizzato solo una volta per utente. Il numero di usi specifica il numero di utenti diversi che possono utilizzare questo voucher.",
     "Max": "Massimo",
     "Expires at": "Scade il",
-    "Used \/ Uses": "Usato \/ Utilizzi",
+    "Used / Uses": "Usato / Utilizzi",
     "Expires": "Scade",
     "Sign in to start your session": "Accedi per iniziare la sessione",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Nessun nodo è stato connesso!",
     "No nests available!": "Nessun nido (nest) disponibile!",
     "No eggs have been linked!": "Nessun uovo (egg) è stato connesso!",
-    "Software \/ Games": "Software \/ Giochi",
+    "Software / Games": "Software / Giochi",
     "Please select software ...": "Per favore selezione il software...",
     "---": "---",
     "Specification ": "Specifiche ",
@@ -447,6 +447,8 @@
     "Notes": "Note",
     "Amount in words": "Numero in parole",
     "Please pay until": "Per favore paga fino",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "L’aggiornamento / riduzione del tuo server reimposterà il tuo ciclo di fatturazione a ora. I tuoi crediti in eccesso saranno rimborsati. Il prezzo per il nuovo ciclo di fatturazione sarà prelevato",
+    "Caution": "Attenzione",
     "cs": "Ceco",
     "de": "Tedesco",
     "en": "Inglese",
@@ -461,4 +463,4 @@
     "ru": "Russo",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/nl.json b/resources/lang/nl.json
index fa8eeed64..160bb0435 100644
--- a/resources/lang/nl.json
+++ b/resources/lang/nl.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Fout bij het maken van de server",
     "Your servers have been suspended!": "Uw servers zijn opgeschort!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Om uw server(s) automatisch opnieuw in te schakelen, moet u meer credits kopen.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Om uw server(s) automatisch opnieuw in te schakelen, moet u meer credits kopen.",
     "Purchase credits": "Credits kopen",
     "If you have any questions please let us know.": "Als u vragen heeft, laat het ons dan weten.",
     "Regards": "Met vriendelijke groet",
@@ -93,7 +93,7 @@
     "Getting started!": "Aan de slag!",
     "Welcome to our dashboard": "Welkom bij ons dashboard",
     "Verification": "Verificatie",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Informatie",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Standaard taal",
     "The fallback Language, if something goes wrong": "De terugval-taal, als er iets misgaat",
     "Datable language": "Dateerbare taal",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "De datatabellen lang-code. <br><strong>Voorbeeld:<\/strong> nl-gb, fr_fr, de_de<br>Meer informatie: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "De datatabellen lang-code. <br><strong>Voorbeeld:</strong> nl-gb, fr_fr, de_de<br>Meer informatie: ",
     "Auto-translate": "Automatisch vertalen",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Als dit is aangevinkt, zal het dashboard zichzelf vertalen naar de taal van de klant, indien beschikbaar",
     "Client Language-Switch": "Klant Taal-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Brengt het eerste uur aan credits in rekening bij het maken van een server.",
     "Credits Display Name": "Weergavenaam tegoed",
     "PHPMyAdmin URL": "PHPMyAdmin-URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Voer de URL naar uw PHPMyAdmin-installatie in. <strong>Zonder een slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Voer de URL naar uw PHPMyAdmin-installatie in. <strong>Zonder een slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Voer de URL naar uw Pterodactyl-installatie in. <strong>Zonder een slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Voer de URL naar uw Pterodactyl-installatie in. <strong>Zonder een slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API sleutel",
     "Enter the API Key to your Pterodactyl installation.": "Voer de API-sleutel in voor uw Pterodactyl-installatie.",
     "Force Discord verification": "Forceer Discord Verificatie",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Een voucher kan slechts één keer per gebruiker worden gebruikt. Gebruik geeft het aantal verschillende gebruikers aan dat deze voucher kan gebruiken.",
     "Max": "Maximum",
     "Expires at": "Verloopt om",
-    "Used \/ Uses": "Gebruikt \/ Toepassingen",
+    "Used / Uses": "Gebruikt / Toepassingen",
     "Expires": "Verloopt",
     "Sign in to start your session": "Login om te beginnen",
     "Password": "Wachtwoord",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Er zijn geen nodes gekoppeld!",
     "No nests available!": "Er zijn geen nesten beschikbaar!",
     "No eggs have been linked!": "Geen eieren gekoppeld!",
-    "Software \/ Games": "Software \/ Spellen",
+    "Software / Games": "Software / Spellen",
     "Please select software ...": "Selecteer software...",
     "---": "---",
     "Specification ": "Specificatie ",
@@ -447,6 +447,8 @@
     "Notes": "Notities",
     "Amount in words": "Hoeveelheid in eenheden",
     "Please pay until": "Gelieve te betalen tot",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgraden/downgraden van uw server zal uw facturatiecyclus resetten naar nu. Uw overbetalen krediet zal worden terugbetaald. De prijs voor de nieuwe facturatiecyclus zal worden afgeschreven",
+    "Caution": "Let op",
     "cs": "Tsjechisch",
     "de": "Duits",
     "en": "Engels",
@@ -461,4 +463,4 @@
     "ru": "Russisch",
     "sv": "Zweeds",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/pl.json b/resources/lang/pl.json
index df5538e94..ee3cf4995 100644
--- a/resources/lang/pl.json
+++ b/resources/lang/pl.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Błąd podczas tworzenia serwera",
     "Your servers have been suspended!": "Serwery zostały zawieszone!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Aby reaktywować swoje serwery, musisz kupić więcej kredytów.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Aby reaktywować swoje serwery, musisz kupić więcej kredytów.",
     "Purchase credits": "Zakup kredyty",
     "If you have any questions please let us know.": "W razie jakichkolwiek pytań prosimy o kontakt.",
     "Regards": "Z poważaniem",
@@ -93,7 +93,7 @@
     "Getting started!": "Zaczynajmy!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Domyślny język",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Domyślny język",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Automatyczne tłumaczenie",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Nazwa Waluty",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "URL Pterodactyl Panelu",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Klucz API Pterodactyl panelu",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Kupon może zostać zrealizowany tylko raz przez użytkownika. „Użycie” określa liczbę użytkowników, którzy mogą zrealizować ten kupon.",
     "Max": "Max",
     "Expires at": "Wygasa",
-    "Used \/ Uses": "Użyto \/ Użyć",
+    "Used / Uses": "Użyto / Użyć",
     "Expires": "Wygasa",
     "Sign in to start your session": "Zaloguj się, aby rozpocząć sesję",
     "Password": "Hasło",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Żaden węzeł nie został połączony!",
     "No nests available!": "Brak dostępnych gniazd!",
     "No eggs have been linked!": "Jajka nie zostały połaczone!",
-    "Software \/ Games": "Oprogramowanie \/ gry",
+    "Software / Games": "Oprogramowanie / gry",
     "Please select software ...": "Proszę wybrać oprogramowanie...",
     "---": "---",
     "Specification ": "Specyfikacja ",
@@ -447,6 +447,8 @@
     "Notes": "Uwagi",
     "Amount in words": "Wszystkie słowa",
     "Please pay until": "Zapłać w ciągu:",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizacja / degradacja twojego serwera spowoduje zresetowanie cyklu rozliczeniowego do teraz. Twoje nadpłacone kredyty zostaną zwrócone. Cena za nowy cykl rozliczeniowy zostanie pobrana",
+    "Caution": "Uwaga",
     "cs": "Czeski",
     "de": "Niemiecki",
     "en": "Angielski",
@@ -461,4 +463,4 @@
     "ru": "Rosyjski",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/pt.json b/resources/lang/pt.json
index 2313dc326..c301bcd8a 100644
--- a/resources/lang/pt.json
+++ b/resources/lang/pt.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Alguém se registrou usando seu código!",
     "Server Creation Error": "Erro de criação do servidor",
     "Your servers have been suspended!": "Os seus servidores foram suspensos!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Para reativar automaticamente o seu(s) servidor(es), é preciso comprar mais créditos.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Para reativar automaticamente o seu(s) servidor(es), é preciso comprar mais créditos.",
     "Purchase credits": "Compra de créditos",
     "If you have any questions please let us know.": "Se tiver alguma dúvida, por favor, nos avise.",
     "Regards": "Cumprimentos,",
@@ -93,7 +93,7 @@
     "Getting started!": "Começar",
     "Welcome to our dashboard": "Bem-vindo ao nosso painel",
     "Verification": "Verificação",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Você pode verificar o seu endereço de e-mail e link",
+    "You can verify your e-mail address and link/verify your Discord account.": "Você pode verificar o seu endereço de e-mail e link",
     "Information": "Informações",
     "This dashboard can be used to create and delete servers": "Este painel pode ser usado para criar e excluir servidores",
     "These servers can be used and managed on our pterodactyl panel": "Esses servidores podem ser usados e gerenciados no nosso painel pterodactyl ",
@@ -187,7 +187,7 @@
     "Default language": "Idioma padrão",
     "The fallback Language, if something goes wrong": "Um idioma padrão, se algo der errado",
     "Datable language": "Idioma de dados",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Os lang-codes disponíveis. <br><strong>Exemplo:<\/strong> en-gb, fr_fr, de_de<br>Mais informações:",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Os lang-codes disponíveis. <br><strong>Exemplo:</strong> en-gb, fr_fr, de_de<br>Mais informações:",
     "Auto-translate": "Traduzir Automaticamente",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Se isto for ativado, o Painel se traduzirá para o idioma do cliente, se disponível.",
     "Client Language-Switch": "Trocar Idioma do cliente",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Cobra a primeira hora de créditos ao criar um servidor.",
     "Credits Display Name": "Nome de exibição dos créditos",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Insira o URL do seu PHPMyAdmin. <strong>Sem barra de arrasto!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Insira o URL do seu PHPMyAdmin. <strong>Sem barra de arrasto!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Insira o URL do seu pterodactyl. <strong>Sem barra de arrasto!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Insira o URL do seu pterodactyl. <strong>Sem barra de arrasto!</strong>",
     "Pterodactyl API Key": "Chave API pterodactyl",
     "Enter the API Key to your Pterodactyl installation.": "Insira a chave API do seu painel pterodactyl.",
     "Force Discord verification": "Forçar verificação do Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Um vale só pode ser usado uma vez por utilizador. Os usos especificam o número de diferentes utilizadores que podem usar este comprovante.",
     "Max": "Máximo",
     "Expires at": "Expira em",
-    "Used \/ Uses": "Usados \/ Usos",
+    "Used / Uses": "Usados / Usos",
     "Expires": "Expira",
     "Sign in to start your session": "Entre para iniciar a sua sessão",
     "Password": "Senha",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Nenhum nó foi ligado!",
     "No nests available!": "Não há ninhos disponíveis!",
     "No eggs have been linked!": "Nenhum ovo foi ligado!",
-    "Software \/ Games": "“Software” \/ Jogos",
+    "Software / Games": "“Software” / Jogos",
     "Please select software ...": "Por favor, selecione o “software”...",
     "---": "—",
     "Specification ": "Especificação",
@@ -447,6 +447,8 @@
     "Notes": "Notas",
     "Amount in words": "Quantia em palavras",
     "Please pay until": "Favor pagar até",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Atualizar / Reduzir o seu servidor irá redefinir o seu ciclo de faturação para agora. Os seus créditos pagos a mais serão reembolsados. O preço para o novo ciclo de faturação será debitado",
+    "Caution": "Cuidado",
     "cs": "Tcheco",
     "de": "Alemão",
     "en": "Inglês",
@@ -461,4 +463,4 @@
     "ru": "Russo",
     "sv": "Sueco",
     "sk": "Eslovaco"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/ro.json b/resources/lang/ro.json
index b897bbd07..804eeb680 100644
--- a/resources/lang/ro.json
+++ b/resources/lang/ro.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -93,7 +93,7 @@
     "Getting started!": "Getting started!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -461,4 +463,4 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/ru.json b/resources/lang/ru.json
index 90daf537e..f99779a3e 100644
--- a/resources/lang/ru.json
+++ b/resources/lang/ru.json
@@ -39,7 +39,7 @@
     "Store item has been removed!": "Товар в магазине был удален!",
     "link has been created!": "Ссылка была создана!",
     "link has been updated!": "Ссылка была обновлена!",
-    "product has been removed!": "Продукт\/Товар был удалён!",
+    "product has been removed!": "Продукт/Товар был удалён!",
     "User does not exists on pterodactyl's panel": "Пользователь не был найден в панеле птеродактиль",
     "user has been removed!": "Пользователь был удален!",
     "Notification sent!": "Оповещение отправлено!",
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Ошибка создание сервера",
     "Your servers have been suspended!": "Ваши сервера были заблокированы!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Чтобы автоматически повторно включить ваш сервер \/ серверы, вам необходимо приобрести больше кредитов.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Чтобы автоматически повторно включить ваш сервер / серверы, вам необходимо приобрести больше кредитов.",
     "Purchase credits": "Приобрести кредиты",
     "If you have any questions please let us know.": "Пожалуйста, сообщите нам, если у Вас есть какие-либо вопросы.",
     "Regards": "С уважением,",
@@ -93,7 +93,7 @@
     "Getting started!": "Начало работы!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Язык по умолчанию",
     "The fallback Language, if something goes wrong": "Резервный язык, если что-то пойдет не так",
     "Datable language": "Датадатируемый язык",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Языковой код таблицы данных. <br><strong>Пример:<\/strong> en-gb, fr_fr, de_de<br>Дополнительная информация:",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Языковой код таблицы данных. <br><strong>Пример:</strong> en-gb, fr_fr, de_de<br>Дополнительная информация:",
     "Auto-translate": "Автоперевод",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Если этот флажок установлен, информационная панель будет переводиться на язык клиентов, если он доступен",
     "Client Language-Switch": "Переключение языка клиента",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Взимает кредиты за первый час при создании сервера.",
     "Credits Display Name": "Отображаемое имя кредитов",
     "PHPMyAdmin URL": "URL-адрес PHPMyAdmin",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Введите URL-адрес вашей установки PHPMyAdmin. <strong>Без косой черты в конце!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Введите URL-адрес вашей установки PHPMyAdmin. <strong>Без косой черты в конце!</strong>",
     "Pterodactyl URL": "URL-адрес птеродактиля",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Введите URL-адрес вашей установки Pterodactyl. <strong>Без косой черты в конце!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Введите URL-адрес вашей установки Pterodactyl. <strong>Без косой черты в конце!</strong>",
     "Pterodactyl API Key": "API-ключ птеродактиля",
     "Enter the API Key to your Pterodactyl installation.": "Введите ключ API для установки Pterodactyl.",
     "Force Discord verification": "Требуется верификация в Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Промокод можно использовать только один раз для каждого пользователя. Пользователь указывает количество различных пользователей, которые могут использовать этот промокод.",
     "Max": "Макс.",
     "Expires at": "Срок действия до",
-    "Used \/ Uses": "Используется \/ Использует",
+    "Used / Uses": "Используется / Использует",
     "Expires": "Истекает",
     "Sign in to start your session": "Войдите, чтобы начать сессию",
     "Password": "Пароль",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Ни один узел не был связан!",
     "No nests available!": "Гнезда в наличии нет!",
     "No eggs have been linked!": "Группы были связаны!",
-    "Software \/ Games": "Программное обеспечение \/ Игры",
+    "Software / Games": "Программное обеспечение / Игры",
     "Please select software ...": "Пожалуйста, выберите программное обеспечение...",
     "---": "---",
     "Specification ": "Характеристики ",
@@ -447,6 +447,8 @@
     "Notes": "Примечания",
     "Amount in words": "Сумма прописью",
     "Please pay until": "Пожалуйста, платите до",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Обновление/Уменьшение вашего сервера сбросит ваш цикл оплаты на текущий. Ваши переплаты будут возвращены. Цена за новый цикл оплаты будет списана",
+    "Caution": "Внимание",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -461,4 +463,4 @@
     "ru": "Русский",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/sh.json b/resources/lang/sh.json
index 56c63ac36..bdf0019ba 100644
--- a/resources/lang/sh.json
+++ b/resources/lang/sh.json
@@ -80,7 +80,7 @@
     "User ID": "User ID",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -173,7 +173,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -214,9 +214,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -284,7 +284,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -354,7 +354,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -430,6 +430,8 @@
     "The Language of the Datatables. Grab the Language-Codes from here": "The Language of the Datatables. Grab the Language-Codes from here",
     "Let the Client change the Language": "Let the Client change the Language",
     "Icons updated!": "Icons updated!",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -442,4 +444,4 @@
     "zh": "Chinese",
     "tr": "Turkish",
     "ru": "Russian"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/sk.json b/resources/lang/sk.json
index f002840db..eb2b01e39 100644
--- a/resources/lang/sk.json
+++ b/resources/lang/sk.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -93,7 +93,7 @@
     "Getting started!": "Getting started!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizácia alebo deaktualizácia servera resetuje Vašu fakturačnú dobu na aktuálny čas. Vaše nadbytočné kredity budú vrátené. Cena za novú fakturačnú dobu bude odobraná.",
+    "Caution": "Upozornenie",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -461,4 +463,4 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/sr.json b/resources/lang/sr.json
index 0c51bf979..d967bb306 100644
--- a/resources/lang/sr.json
+++ b/resources/lang/sr.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Greška pri kreiranju servera",
     "Your servers have been suspended!": "Vaši serveri su suspendovani!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Da biste automatski ponovo omogućili svoje servere, potrebno je da kupite još kredita.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Da biste automatski ponovo omogućili svoje servere, potrebno je da kupite još kredita.",
     "Purchase credits": "Kupite kredite",
     "If you have any questions please let us know.": "Ako imate bilo kakvih pitanja, molimo vas da nas obavestite.",
     "Regards": "Pozdravi",
@@ -93,7 +93,7 @@
     "Getting started!": "Početak!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Podrazumevani jezik",
     "The fallback Language, if something goes wrong": "Sekundarni jezik, u slučaju da bude problema",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Automatski prevod",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Korisnički izbor za jezik",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Naplaćuje kredite u vrednosti od prvog sata prilikom kreiranja servera.",
     "Credits Display Name": "Ime prikaza kredita",
     "PHPMyAdmin URL": "PHPMyAdmin Link",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Unesite URL adresu instalacije PHPMyAdmin. <strong>Bez kose crte!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Unesite URL adresu instalacije PHPMyAdmin. <strong>Bez kose crte!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Maksimalno",
     "Expires at": "Ističe",
-    "Used \/ Uses": "Upotrebljeno \/ Upotrebe",
+    "Used / Uses": "Upotrebljeno / Upotrebe",
     "Expires": "Ističe",
     "Sign in to start your session": "Prijavite se da biste započeli sesiju",
     "Password": "Lozinka",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Node-ovi nisu povezani!",
     "No nests available!": "Nema dostupnih gnezda!",
     "No eggs have been linked!": "Jaja nisu povezana!",
-    "Software \/ Games": "Softver \/ Igrice",
+    "Software / Games": "Softver / Igrice",
     "Please select software ...": "Molimo izaberite softver ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Napomena",
     "Amount in words": "Iznos u rečima",
     "Please pay until": "Molimo platite do",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -461,4 +463,4 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/sv.json b/resources/lang/sv.json
index f6a377f12..4d84781ae 100644
--- a/resources/lang/sv.json
+++ b/resources/lang/sv.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Serverskapande fel",
     "Your servers have been suspended!": "Ditt konto har blivit avstängt!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "För att automatiskt återaktivera din server\/s, så måste du köpa mer krediter.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "För att automatiskt återaktivera din server/s, så måste du köpa mer krediter.",
     "Purchase credits": "Köp krediter",
     "If you have any questions please let us know.": "Kontakta oss gärna om du har några eventuella frågor.",
     "Regards": "Hälsningar",
@@ -93,7 +93,7 @@
     "Getting started!": "Kom igång!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Förvalt språk",
     "The fallback Language, if something goes wrong": "Reservspråket, om något går fel",
     "Datable language": "Daterbart språk",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Datatabellernas språkkod. <br><strong>Exempel:<\/strong> en-gb, fr_fr, de_de<br>Mer information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Datatabellernas språkkod. <br><strong>Exempel:</strong> en-gb, fr_fr, de_de<br>Mer information: ",
     "Auto-translate": "Auto-översätt",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -461,4 +463,4 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/tr.json b/resources/lang/tr.json
index 385a8dffb..81cf7aab7 100644
--- a/resources/lang/tr.json
+++ b/resources/lang/tr.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Birileri senin kodunu kullanarak kayıt oldu!",
     "Server Creation Error": "Sunucu Oluşturma Hatası",
     "Your servers have been suspended!": "Sunucularınız askıya alındı!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Sunucularınızı\/sunucularınızı otomatik olarak yeniden etkinleştirmek için daha fazla kredi satın almanız gerekir.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Sunucularınızı/sunucularınızı otomatik olarak yeniden etkinleştirmek için daha fazla kredi satın almanız gerekir.",
     "Purchase credits": "Satın alma kredisi",
     "If you have any questions please let us know.": "Herhangi bir sorunuz varsa lütfen bize bildirin.",
     "Regards": "Saygılarımızla",
@@ -93,7 +93,7 @@
     "Getting started!": "Başlarken!",
     "Welcome to our dashboard": "Kontrol panelimize hoş geldiniz",
     "Verification": "Doğrulama",
-    "You can verify your e-mail address and link\/verify your Discord account.": "E-posta adresinizi doğrulayabilir ve Discord hesabınızı bağlayabilir\/doğrulayabilirsiniz.",
+    "You can verify your e-mail address and link/verify your Discord account.": "E-posta adresinizi doğrulayabilir ve Discord hesabınızı bağlayabilir/doğrulayabilirsiniz.",
     "Information": "Bilgi",
     "This dashboard can be used to create and delete servers": "Bu gösterge panosu, sunucular oluşturmak ve silmek için kullanılabilir",
     "These servers can be used and managed on our pterodactyl panel": "Bu sunucular pterodactyl panelimizde kullanılabilir ve yönetilebilir",
@@ -187,7 +187,7 @@
     "Default language": "Varsayılan Dil",
     "The fallback Language, if something goes wrong": "Yedek dil, eğer bir şeyler yanlış giderse",
     "Datable language": "Tarih Dili",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Tarihlerde kullanılacak dil kodu. <br><strong>Örnek:<\/strong> en-gb, fr_fr, de_de<br> Daha fazla bilgi: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Tarihlerde kullanılacak dil kodu. <br><strong>Örnek:</strong> en-gb, fr_fr, de_de<br> Daha fazla bilgi: ",
     "Auto-translate": "Otomatik çeviri",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Eğer bu seçili ise Yönetim paneli kendisini kullanıcının diline çevirecek, eğer kullanılabiliyorsa",
     "Client Language-Switch": "Müşteri Dil Değiştiricisi",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Kullanıcı sunucu oluşturduğumda ilk saatin ödemesini direkt olarak alır.",
     "Credits Display Name": "Kredi ismi",
     "PHPMyAdmin URL": "PHPMyAdmin linki",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "PHPMyAdmin kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "PHPMyAdmin kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan</strong>",
     "Pterodactyl URL": "Pterodactyl Linki",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Pterodactyl kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Pterodactyl kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Anahtarı",
     "Enter the API Key to your Pterodactyl installation.": "Pterodactyl kurulumunuzun API anahtarını girin.",
     "Force Discord verification": "Discord Doğrulamasını zorunlu yap",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Bir kupon, kullanıcı başına yalnızca bir kez kullanılabilir. Kullanımlar, bu kuponu kullanabilecek farklı kullanıcıların sayısını belirtir.",
     "Max": "Maks",
     "Expires at": "Sona eriyor",
-    "Used \/ Uses": "Kullanılmış \/ Kullanım Alanları",
+    "Used / Uses": "Kullanılmış / Kullanım Alanları",
     "Expires": "Sona eriyor",
     "Sign in to start your session": "Oturumunuzu başlatmak için oturum açın",
     "Password": "Parola",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Hiçbir makine bağlanmamış!",
     "No nests available!": "Hiçbir nest bulunamadı!",
     "No eggs have been linked!": "Hiçbir egg bağlanmamış!",
-    "Software \/ Games": "Yazılımlar \/ Oyunlar",
+    "Software / Games": "Yazılımlar / Oyunlar",
     "Please select software ...": "Lütfen bir yazılım seçin ...",
     "---": "---",
     "Specification ": "Özellikler ",
@@ -447,6 +447,8 @@
     "Notes": "Notlar",
     "Amount in words": "Yazı ile Tutar",
     "Please pay until": "Lütfen şu tarihe kadar ödeyin",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Sunucunuzu yükseltmek / düşürmek faturalandırma döngünüzü şimdiye sıfırlayacaktır. Aşırı ödenen kredileriniz iade edilecektir. Yeni faturalandırma döngüsü için ödenen tutar çekilecektir",
+    "Caution": "Dikkat",
     "cs": "Çekçe",
     "de": "Almanca",
     "en": "İngilizce",
@@ -461,4 +463,4 @@
     "ru": "Rusça",
     "sv": "İsveççe",
     "sk": "Slovakça"
-}
\ No newline at end of file
+}
diff --git a/resources/lang/zh.json b/resources/lang/zh.json
index efae58c6e..c534a612f 100644
--- a/resources/lang/zh.json
+++ b/resources/lang/zh.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "已经有人使用您的代码注册了",
     "Server Creation Error": "服务器创建错误",
     "Your servers have been suspended!": "您的服务器已被暂停",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "如需重新启用你的服务器,您需要购买更多的余额",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "如需重新启用你的服务器,您需要购买更多的余额",
     "Purchase credits": "购买余额",
     "If you have any questions please let us know.": "如果您有其他任何问题,欢迎联系我们。",
     "Regards": "此致",
@@ -93,7 +93,7 @@
     "Getting started!": "开始吧!",
     "Welcome to our dashboard": "欢迎访问 dashboard",
     "Verification": "验证",
-    "You can verify your e-mail address and link\/verify your Discord account.": "你可以验证你的邮箱地址或者连接到你的Discord账户",
+    "You can verify your e-mail address and link/verify your Discord account.": "你可以验证你的邮箱地址或者连接到你的Discord账户",
     "Information": "相关信息",
     "This dashboard can be used to create and delete servers": "此仪表板可用于创建和删除服务器",
     "These servers can be used and managed on our pterodactyl panel": "这些服务器可以在我们的pterodactyl面板上使用和管理",
@@ -187,7 +187,7 @@
     "Default language": "默认语言",
     "The fallback Language, if something goes wrong": "备用语言",
     "Datable language": "可用语言",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "数据表语言代码 <br><strong>示例:<\/strong> en-gb、fr_fr、de_de<br> 更多信息: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "数据表语言代码 <br><strong>示例:</strong> en-gb、fr_fr、de_de<br> 更多信息: ",
     "Auto-translate": "自动翻译",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "如果勾选此项,系统将把自己翻译成客户语言(如果有)",
     "Client Language-Switch": "客户语言切换",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "在创建服务器时收取第一个小时的费用",
     "Credits Display Name": "积分显示名称",
     "PHPMyAdmin URL": "PHPMyAdmin地址",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "输入你PHPMyAdmin的URL。<strong>不要有尾部斜线!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "输入你PHPMyAdmin的URL。<strong>不要有尾部斜线!</strong>",
     "Pterodactyl URL": "Pterodactyl地址",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "输入你Pterodactyl的URL。<strong>不要有尾部斜线!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "输入你Pterodactyl的URL。<strong>不要有尾部斜线!</strong>",
     "Pterodactyl API Key": "Pterodactyl API密钥",
     "Enter the API Key to your Pterodactyl installation.": "输入Pterodactyl API密钥",
     "Force Discord verification": "强制Discord验证",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "每个用户只能使用一次代金券。使用次数指定了可以使用此代金券的不同用户的数量。",
     "Max": "最大",
     "Expires at": "过期时间",
-    "Used \/ Uses": "已使用\/使用情况",
+    "Used / Uses": "已使用/使用情况",
     "Expires": "过期",
     "Sign in to start your session": "登录以开始您的会议",
     "Password": "密码",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "没有节点被链接!",
     "No nests available!": "没有可用的巢穴!",
     "No eggs have been linked!": "没有蛋被链接!",
-    "Software \/ Games": "软件\/游戏",
+    "Software / Games": "软件/游戏",
     "Please select software ...": "请选择软件...",
     "---": "---",
     "Specification ": "规格 ",
@@ -447,6 +447,8 @@
     "Notes": "笔记",
     "Amount in words": "税额的字数",
     "Please pay until": "请支付至",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "升级/降级你的服务器将重置你的账单周期。你的多余的点数将被退还。新的账单周期的价格将被扣除",
+    "Caution": "警告",
     "cs": "捷克语",
     "de": "德语",
     "en": "英语",
@@ -461,4 +463,4 @@
     "ru": "俄语",
     "sv": "乌克兰语",
     "sk": "斯洛伐克语"
-}
\ No newline at end of file
+}

From 056e41be1a9123b1adef4982f5a2503146dd8e27 Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Mon, 19 Dec 2022 15:08:09 +0100
Subject: [PATCH 047/514] chore: doc

---
 Addon-notes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index bed6f5a2e..ac00939be 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,4 +1,4 @@
 Export diff files:
 Commit Hash of lates Main commit
 
-git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -
+git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf \.\./controllpanelgg-monthly-addon/file.tgz -T -

From 25db97d0a434bad302076ab33a9e320a7aa250e9 Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Mon, 23 Jan 2023 16:27:32 +0100
Subject: [PATCH 048/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Merge=20missing?=
 =?UTF-8?q?=20hidden=20product=20in=20form?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/servers/create.blade.php | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 717e15b8f..b118ac822 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -223,13 +223,17 @@ class="custom-select">
                                     </div>
                                     <div class="mt-auto border rounded border-secondary">
                                         <div class="d-flex justify-content-between p-2">
-                                            <span class="d-inline-block mr-4" x-text="'{{ __('Price') }}' + ' (' + product.billing_period + ')'">
+                                            <span class="d-inline-block mr-4"
+                                                x-text="'{{ __('Price') }}' + ' (' + product.billing_period + ')'">
                                             </span>
                                             <span class="d-inline-block"
                                                 x-text="product.price + ' {{ CREDITS_DISPLAY_NAME }}'"></span>
                                         </div>
                                     </div>
-									<div>
+                                    <div>
+                                        <input type="hidden" name="product" x-model="selectedProduct">
+                                    </div>
+                                    <div>
                                         <button type="submit" x-model="selectedProduct" name="product"
                                             :disabled="product.minimum_credits > user.credits || product.doesNotFit == true ||
                                                 product.price > user.credits || submitClicked"
@@ -240,14 +244,14 @@ class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
                                         </button>
                                     </div>
 
+                                </div>
                             </div>
+                        </template>
                     </div>
-                    </template>
                 </div>
-        </div>
 
-        </form>
-        <!-- END FORM -->
+            </form>
+            <!-- END FORM -->
 
         </div>
     </section>

From 54325fbf3ea643c415730a2590df2247124a44bf Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:32:00 +0200
Subject: [PATCH 049/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Migration?=
 =?UTF-8?q?=20->=20Column=20Billing=20Period?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ..._092704_add_billing_period_to_products.php | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 database/migrations/2022_06_16_092704_add_billing_period_to_products.php

diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
new file mode 100644
index 000000000..4018fb473
--- /dev/null
+++ b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+class AddBillingPeriodToProducts extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->string('billing_period')->default("hourly");
+        });
+
+        DB::statement('UPDATE products SET billing_period="hourly"');
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->dropColumn('billing_period');
+        });
+    }
+}

From 88a85416232e6f0c2a13318cadfddd2c3137fdd4 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:55:34 +0200
Subject: [PATCH 050/514] =?UTF-8?q?fix:=20=E2=9C=A8=20Updated=20Migration?=
 =?UTF-8?q?=20to=20calculate=20hourly=20price=20from=20existing=20products?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2022_06_16_092704_add_billing_period_to_products.php  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
index 4018fb473..708e6e5e4 100644
--- a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
+++ b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
@@ -19,6 +19,14 @@ public function up()
         });
 
         DB::statement('UPDATE products SET billing_period="hourly"');
+
+        $products = DB::table('products')->get();
+        foreach ($products as $product) {
+            $price = $product->price;
+            $price = $price / 30 / 24;
+            DB::table('products')->where('id', $product->id)->update(['price' => $price]);
+        }
+
     }
 
     /**

From 23cc70d79ce3fa8147c99c2b5b096f56a5b75413 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:56:05 +0200
Subject: [PATCH 051/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Added=20Migration?=
 =?UTF-8?q?=20->=20Updated=20user=20credits=20column=20to=20be=20decimal?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...6_16_094402_update_user_price_datatype.php | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 database/migrations/2022_06_16_094402_update_user_price_datatype.php

diff --git a/database/migrations/2022_06_16_094402_update_user_price_datatype.php b/database/migrations/2022_06_16_094402_update_user_price_datatype.php
new file mode 100644
index 000000000..9b4abb9e7
--- /dev/null
+++ b/database/migrations/2022_06_16_094402_update_user_price_datatype.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class UpdateUserPriceDatatype extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->decimal('credits', 20, 10)->default(0)->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->unsignedFloat('credits')->default(250)->change();
+        });
+    }
+}

From 00e525a7645f550a61898c3c2165983284eb627c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 11:59:17 +0200
Subject: [PATCH 052/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Migration?=
 =?UTF-8?q?=20->=20last=20billed=20field=20to=20servers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...95818_add_last_billed_field_to_servers.php | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php

diff --git a/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php b/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php
new file mode 100644
index 000000000..6b05f3a5b
--- /dev/null
+++ b/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php
@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+class AddLastBilledFieldToServers extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->dateTime('last_billed')->default(DB::raw('CURRENT_TIMESTAMP'))->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->dropColumn('last_billed');
+        });
+    }
+}

From 195cadc6a5f5ec9668913d96c425b9eac50bf50d Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:01:53 +0200
Subject: [PATCH 053/514] =?UTF-8?q?feat:=20=F0=9F=93=9D=20Updated=20Produc?=
 =?UTF-8?q?tSeeder?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 database/seeders/Seeds/ProductSeeder.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/database/seeders/Seeds/ProductSeeder.php b/database/seeders/Seeds/ProductSeeder.php
index 4f5e43754..dc26a9a1e 100644
--- a/database/seeders/Seeds/ProductSeeder.php
+++ b/database/seeders/Seeds/ProductSeeder.php
@@ -16,7 +16,7 @@ public function run()
     {
         Product::create([
             'name' => 'Starter',
-            'description' => '64MB Ram, 1GB Disk, 1 Database, 140 credits monthly',
+            'description' => '64MB Ram, 1GB Disk, 1 Database, 140 credits hourly',
             'price' => 140,
             'memory' => 64,
             'disk' => 1000,
@@ -25,7 +25,7 @@ public function run()
 
         Product::create([
             'name' => 'Standard',
-            'description' => '128MB Ram, 2GB Disk, 2 Database,  210 credits monthly',
+            'description' => '128MB Ram, 2GB Disk, 2 Database,  210 credits hourly',
             'price' => 210,
             'memory' => 128,
             'disk' => 2000,
@@ -34,7 +34,7 @@ public function run()
 
         Product::create([
             'name' => 'Advanced',
-            'description' => '256MB Ram, 5GB Disk, 5 Database,  280 credits monthly',
+            'description' => '256MB Ram, 5GB Disk, 5 Database,  280 credits hourly',
             'price' => 280,
             'memory' => 256,
             'disk' => 5000,

From 9777e22eab4562b3bc7097e0ed7a63111f39646c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:04:52 +0200
Subject: [PATCH 054/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20billing=5Fp?=
 =?UTF-8?q?eriod=20to=20validation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Controllers/Admin/ProductController.php   | 62 ++++++++++---------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 5e9157d9f..53b1c7de3 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -57,21 +57,22 @@ public function clone(Request $request, Product $product)
     public function store(Request $request)
     {
         $request->validate([
-            'name' => 'required|max:30',
-            'price' => 'required|numeric|max:1000000|min:0',
-            'memory' => 'required|numeric|max:1000000|min:5',
-            'cpu' => 'required|numeric|max:1000000|min:0',
-            'swap' => 'required|numeric|max:1000000|min:0',
-            'description' => 'required|string|max:191',
-            'disk' => 'required|numeric|max:1000000|min:5',
-            'minimum_credits' => 'required|numeric|max:1000000|min:-1',
-            'io' => 'required|numeric|max:1000000|min:0',
-            'databases' => 'required|numeric|max:1000000|min:0',
-            'backups' => 'required|numeric|max:1000000|min:0',
-            'allocations' => 'required|numeric|max:1000000|min:0',
-            'nodes.*' => 'required|exists:nodes,id',
-            'eggs.*' => 'required|exists:eggs,id',
-            'disabled' => 'nullable',
+            "name" => "required|max:30",
+            "price" => "required|numeric|max:1000000|min:0",
+            "memory" => "required|numeric|max:1000000|min:5",
+            "cpu" => "required|numeric|max:1000000|min:0",
+            "swap" => "required|numeric|max:1000000|min:0",
+            "description" => "required|string|max:191",
+            "disk" => "required|numeric|max:1000000|min:5",
+            "minimum_credits" => "required|numeric|max:1000000|min:-1",
+            "io" => "required|numeric|max:1000000|min:0",
+            "databases" => "required|numeric|max:1000000|min:0",
+            "backups" => "required|numeric|max:1000000|min:0",
+            "allocations" => "required|numeric|max:1000000|min:0",
+            "nodes.*" => "required|exists:nodes,id",
+            "eggs.*" => "required|exists:eggs,id",
+            "disabled" => "nullable",
+            "billing_period" => "required|in:hourly,daily,monthly",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -123,21 +124,22 @@ public function edit(Product $product)
     public function update(Request $request, Product $product): RedirectResponse
     {
         $request->validate([
-            'name' => 'required|max:30',
-            'price' => 'required|numeric|max:1000000|min:0',
-            'memory' => 'required|numeric|max:1000000|min:5',
-            'cpu' => 'required|numeric|max:1000000|min:0',
-            'swap' => 'required|numeric|max:1000000|min:0',
-            'description' => 'required|string|max:191',
-            'disk' => 'required|numeric|max:1000000|min:5',
-            'io' => 'required|numeric|max:1000000|min:0',
-            'minimum_credits' => 'required|numeric|max:1000000|min:-1',
-            'databases' => 'required|numeric|max:1000000|min:0',
-            'backups' => 'required|numeric|max:1000000|min:0',
-            'allocations' => 'required|numeric|max:1000000|min:0',
-            'nodes.*' => 'required|exists:nodes,id',
-            'eggs.*' => 'required|exists:eggs,id',
-            'disabled' => 'nullable',
+            "name" => "required|max:30",
+            "price" => "required|numeric|max:1000000|min:0",
+            "memory" => "required|numeric|max:1000000|min:5",
+            "cpu" => "required|numeric|max:1000000|min:0",
+            "swap" => "required|numeric|max:1000000|min:0",
+            "description" => "required|string|max:191",
+            "disk" => "required|numeric|max:1000000|min:5",
+            "io" => "required|numeric|max:1000000|min:0",
+            "minimum_credits" => "required|numeric|max:1000000|min:-1",
+            "databases" => "required|numeric|max:1000000|min:0",
+            "backups" => "required|numeric|max:1000000|min:0",
+            "allocations" => "required|numeric|max:1000000|min:0",
+            "nodes.*" => "required|exists:nodes,id",
+            "eggs.*" => "required|exists:eggs,id",
+            "disabled" => "nullable",
+            "billing_period" => "required|in:hourly,daily,monthly",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));

From 7dab9d3c7e66d319ee5b209a5bddb3f8e4ca80dd Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:27:53 +0200
Subject: [PATCH 055/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20billing=20p?=
 =?UTF-8?q?eriod=20to=20edit,=20create=20and=20show=20of=20products?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../views/admin/products/create.blade.php     | 55 ++++++++++++++-----
 .../views/admin/products/edit.blade.php       | 54 +++++++++++++-----
 .../views/admin/products/index.blade.php      |  2 +
 3 files changed, 85 insertions(+), 26 deletions(-)

diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index c6d72f68b..d7257fcf5 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -116,6 +116,20 @@ class="form-control @error('swap') is-invalid @enderror"
                                             @enderror
                                         </div>
 
+                                        <div class="form-group">
+                                            <label for="allocations">{{__('Allocations')}}</label>
+                                            <input value="{{$product->allocations ?? old('allocations') ?? 0}}"
+                                                   id="allocations" name="allocations"
+                                                   type="number"
+                                                   class="form-control @error('allocations') is-invalid @enderror"
+                                                   required="required">
+                                            @error('allocations')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
+
                                         <div class="form-group">
                                             <label for="description">{{__('Description')}} <i data-toggle="popover"
                                                                                               data-trigger="hover"
@@ -148,6 +162,34 @@ class="form-control @error('disk') is-invalid @enderror"
                                             @enderror
                                         </div>
 
+                                        <div class="form-group">
+                                            <label for="billing_period">{{__('Billing Period')}} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{__('Period when the user will be charged for the given price')}}"
+                                                    class="fas fa-info-circle"></i></label>
+
+                                            <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
+                                                autocomplete="off" @error('billing_period') is-invalid @enderror>
+                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
+                                                    @endif>
+                                                        {{__('Hourly')}}
+                                                    </option>
+                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
+                                                    @endif>
+                                                        {{__('Daily')}}
+                                                    </option>
+                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
+                                                     @endif>
+                                                        {{__('Monthly')}}
+                                                    </option>
+                                            </select>
+                                            @error('billing_period')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
+
                                         <div class="form-group">
                                             <label for="minimum_credits">{{__('Minimum')}} {{ CREDITS_DISPLAY_NAME }} <i
                                                     data-toggle="popover" data-trigger="hover"
@@ -205,19 +247,6 @@ class="form-control @error('backups') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
-                                        <div class="form-group">
-                                            <label for="allocations">{{__('Allocations')}}</label>
-                                            <input value="{{$product->allocations ?? old('allocations') ?? 0}}"
-                                                   id="allocations" name="allocations"
-                                                   type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
-                                            @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
-                                            @enderror
-                                        </div>
                                     </div>
                                 </div>
 
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 61357c716..f23533bf0 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -122,7 +122,18 @@ class="form-control @error('swap') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
-
+                                        <div class="form-group">
+                                            <label for="allocations">{{__('Allocations')}}</label>
+                                            <input value="{{ $product->allocations }}" id="allocations"
+                                                   name="allocations" type="number"
+                                                   class="form-control @error('allocations') is-invalid @enderror"
+                                                   required="required">
+                                            @error('allocations')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
                                         <div class="form-group">
                                             <label for="description">{{__('Description')}} <i data-toggle="popover"
                                                                                               data-trigger="hover"
@@ -152,6 +163,35 @@ class="form-control @error('disk') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
+
+                                        <div class="form-group">
+                                            <label for="billing_period">{{__('Billing Period')}} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{__('Period when the user will be charged for the given price')}}"
+                                                    class="fas fa-info-circle"></i></label>
+
+                                            <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
+                                                autocomplete="off" @error('billing_period') is-invalid @enderror>
+                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
+                                                    @endif>
+                                                        {{__('Hourly')}}
+                                                    </option>
+                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
+                                                    @endif>
+                                                        {{__('Daily')}}
+                                                    </option>
+                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
+                                                     @endif>
+                                                        {{__('Monthly')}}
+                                                    </option>
+                                            </select>
+                                            @error('billing_period')
+                                            <div class="invalid-feedback">
+                                                {{ $message }}
+                                            </div>
+                                            @enderror
+                                        </div>
+
                                         <div class="form-group">
                                             <label for="minimum_credits">{{__('Minimum')}} {{ CREDITS_DISPLAY_NAME }} <i
                                                     data-toggle="popover" data-trigger="hover"
@@ -202,18 +242,6 @@ class="form-control @error('backups') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
-                                        <div class="form-group">
-                                            <label for="allocations">{{__('Allocations')}}</label>
-                                            <input value="{{ $product->allocations }}" id="allocations"
-                                                   name="allocations" type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
-                                            @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
-                                            @enderror
-                                        </div>
                                     </div>
                                 </div>
 
diff --git a/themes/default/views/admin/products/index.blade.php b/themes/default/views/admin/products/index.blade.php
index bc15a70b4..729e2d5c4 100644
--- a/themes/default/views/admin/products/index.blade.php
+++ b/themes/default/views/admin/products/index.blade.php
@@ -44,6 +44,7 @@ class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
                             <th>{{__('Active')}}</th>
                             <th>{{__('Name')}}</th>
                             <th>{{__('Price')}}</th>
+                            <th>{{__('Billing period')}}</th>
                             <th>{{__('Memory')}}</th>
                             <th>{{__('Cpu')}}</th>
                             <th>{{__('Swap')}}</th>
@@ -92,6 +93,7 @@ function submitResult() {
                     {data: "disabled"},
                     {data: "name"},
                     {data: "price"},
+                    {data: "billing_period"},
                     {data: "memory"},
                     {data: "cpu"},
                     {data: "swap"},

From f9d5238ea28c02d8ee3a92c93555b10fe02bf4af Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 12:36:01 +0200
Subject: [PATCH 056/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20billing=20p?=
 =?UTF-8?q?eriod=20to=20server=20creation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/servers/create.blade.php | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index a613c29f4..b184d4626 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -208,9 +208,14 @@ class="custom-select">
                                                     <span class="d-inline-block" x-text="product.allocations"></span>
                                                 </li>
                                                 <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-clock"></i>
+                                                        {{ __('Billing Period') }}</span>
+
+                                                    <span class="d-inline-block" x-text="product.billing_period"></span>
+                                                </li>
+                                                <li>
                                                     <span class="d-inline-block"><i class="fa fa-coins"></i>
-                                                        {{ __('Required') }} {{ CREDITS_DISPLAY_NAME }}
-                                                        {{ __('to create this server') }}</span>
+                                                        {{ __('Minimum') }} {{ CREDITS_DISPLAY_NAME }}</span>
                                                     <span class="d-inline-block"
                                                         x-text="product.minimum_credits == -1 ? {{ config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER') }} : product.minimum_credits"></span>
                                                 </li>
@@ -224,8 +229,7 @@ class="custom-select">
                                     </div>
                                     <div class="mt-auto border rounded border-secondary">
                                         <div class="d-flex justify-content-between p-2">
-                                            <span class="d-inline-block mr-4">
-                                                {{ __('Price') }}:
+                                            <span class="d-inline-block mr-4" x-text="'{{ __('Price') }}' + ' (' + product.billing_period + ')'">
                                             </span>
                                             <span class="d-inline-block"
                                                 x-text="product.price + ' {{ CREDITS_DISPLAY_NAME }}'"></span>

From 681928c3ad4ddb19a74aff2c260d2055c7982c9a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 14:54:06 +0200
Subject: [PATCH 057/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20weekly=20to?=
 =?UTF-8?q?=20billing=5Fperiod=20options?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/Admin/ProductController.php     | 4 ++--
 themes/default/views/admin/products/create.blade.php | 4 ++++
 themes/default/views/admin/products/edit.blade.php   | 4 ++++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 53b1c7de3..2893a262a 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -72,7 +72,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -139,7 +139,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index d7257fcf5..a4b477967 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -177,6 +177,10 @@ class="fas fa-info-circle"></i></label>
                                                     <option value="daily" @if ($product->billing_period  == 'daily') selected
                                                     @endif>
                                                         {{__('Daily')}}
+                                                    </option>
+                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
+                                                    @endif>
+                                                        {{__('Weekly')}}
                                                     </option>
                                                      <option value="monthly" @if ($product->billing_period  == 'monthly') selected
                                                      @endif>
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index f23533bf0..2de2e7df6 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -179,6 +179,10 @@ class="fas fa-info-circle"></i></label>
                                                     <option value="daily" @if ($product->billing_period  == 'daily') selected
                                                     @endif>
                                                         {{__('Daily')}}
+                                                    </option>
+                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
+                                                    @endif>
+                                                        {{__('Weekly')}}
                                                     </option>
                                                      <option value="monthly" @if ($product->billing_period  == 'monthly') selected
                                                      @endif>

From 7e17bb62ea02b2728c2cca0fe4b6b13b4e233671 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 14:54:42 +0200
Subject: [PATCH 058/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20ChargeServe?=
 =?UTF-8?q?rs=20command=20&=20updated=20laravel=20schedule=20command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php | 122 +++++++++++++++++++++++++
 app/Console/Kernel.php                 |  12 ++-
 2 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 app/Console/Commands/ChargeServers.php

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
new file mode 100644
index 000000000..678ab4b70
--- /dev/null
+++ b/app/Console/Commands/ChargeServers.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\Server;
+use App\Notifications\ServersSuspendedNotification;
+use Illuminate\Console\Command;
+
+class ChargeServers extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'servers:charge';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Charge all users with severs that are due to be charged';
+
+        /**
+     * A list of users that have to be notified
+     * @var array
+     */
+    protected $usersToNotify = [];
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        Server::whereNull('suspended')->with('users', 'products')->chunk(10, function ($servers) {
+            /** @var Server $server */
+            foreach ($servers as $server) {
+                /** @var Product $product */
+                $product = $server->product;
+                /** @var User $user */
+                $user = $server->user;
+
+                $billing_period = $product->billing_period;
+
+                // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
+                $newBillingDate = null;
+                switch($billing_period) {
+                    case 'monthly':
+                        $newBillingDate = $server->last_billed->addMonth();
+                        break;
+                    case 'weekly':
+                        $newBillingDate = $server->last_billed->addYear();
+                        break;
+                    case 'daily':
+                        $newBillingDate = $server->last_billed->addDay();
+                        break;
+                    default:
+                        $newBillingDate = $server->last_billed->addHour();
+                        break;
+                };
+                if (!($newBillingDate <= now())) return;
+
+                // check if user has enough credits to charge the server
+                if ($user->credits < $product->price) {
+                    try {
+                        #suspend server
+                        $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
+                        $server->suspend();
+
+                        #add user to notify list
+                        if (!in_array($user, $this->usersToNotify)) {
+                            array_push($this->usersToNotify, $user);
+                        }
+                    } catch (\Exception $exception) {
+                        $this->error($exception->getMessage());
+                    }
+                    return;
+                }
+
+                // charge credits to user
+                $this->line("<fg=blue>{$user->name}</> Current credits: <fg=green>{$user->credits}</> Credits to be removed: <fg=red>{$product->price}</>");
+                $user->decrement('credits', $product->price);
+
+                // update server last_billed date
+                $server->last_billed = $newBillingDate;
+            }
+
+            return $this->notifyUsers();
+        });
+    }
+
+    /**
+     * @return bool
+     */
+    public function notifyUsers()
+    {
+        if (!empty($this->usersToNotify)) {
+            /** @var User $user */
+            foreach ($this->usersToNotify as $user) {
+                $this->line("<fg=yellow>Notified user:</> <fg=blue>{$user->name}</>");
+                $user->notify(new ServersSuspendedNotification());
+            }
+        }
+
+        #reset array
+        $this->usersToNotify = array();
+        return true;
+    }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 28d1d36ae..64af565f9 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -8,6 +8,16 @@
 
 class Kernel extends ConsoleKernel
 {
+    /**
+     * The Artisan commands provided by your application.
+     *
+     * @var array
+     */
+    protected $commands = [
+        Commands\ChargeCreditsCommand::class,
+        Commands\ChargeServers::class,
+    ];
+
     /**
      * Define the application's command schedule.
      *
@@ -16,7 +26,7 @@ class Kernel extends ConsoleKernel
      */
     protected function schedule(Schedule $schedule)
     {
-        $schedule->command('credits:charge')->hourly();
+        $schedule->command('servers:charge')->everyMinute();
         $schedule->command('cp:versioncheck:get')->daily();
         $schedule->command('payments:open:clear')->daily();
 

From 3723b527f52eb949ffed1bfefd2d3d3983880fbc Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 15:32:42 +0200
Subject: [PATCH 059/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20decimal?=
 =?UTF-8?q?=20input=20steps=20to=20number=20inputs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/admin/products/create.blade.php | 1 +
 themes/default/views/admin/products/edit.blade.php   | 6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index a4b477967..913fda1f0 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -66,6 +66,7 @@ class="form-control @error('name') is-invalid @enderror"
                                             <label for="price">{{__('Price in')}} {{CREDITS_DISPLAY_NAME}}</label>
                                             <input value="{{$product->price ??  old('price')}}" id="price" name="price" step=".01"
                                                    type="number"
+                                                   step="0.0001"
                                                    class="form-control @error('price') is-invalid @enderror"
                                                    required="required">
                                             @error('price')
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 2de2e7df6..cedbc72c8 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -75,8 +75,10 @@ class="form-control @error('name') is-invalid @enderror"
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="price">{{__('Price in')}} {{ CREDITS_DISPLAY_NAME }}</label>
-                                            <input value="{{ $product->price }}" id="price" name="price" type="number" step=".01"
+                                            <label for="price">{{__('Price in')}} {{CREDITS_DISPLAY_NAME}}</label>
+                                            <input value="{{$product->price}}" id="price" name="price"
+                                                   type="number"
+                                                   step="0.0001"
                                                    class="form-control @error('price') is-invalid @enderror"
                                                    required="required">
                                             @error('price')

From 5b738be6e142afd1190d2f610221db398af0fd77 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 15:33:44 +0200
Subject: [PATCH 060/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Renamed=20Migrati?=
 =?UTF-8?q?on=20&=20changed=20precision=20on=20decimals=20to=20more=20reas?=
 =?UTF-8?q?onable=20number?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2022_06_16_092704_add_billing_period_to_products.php     | 5 +++++
 ...hp => 2022_06_16_094402_update_user_credits_datatype.php} | 5 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)
 rename database/migrations/{2022_06_16_094402_update_user_price_datatype.php => 2022_06_16_094402_update_user_credits_datatype.php} (82%)

diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
index 708e6e5e4..ceed9362f 100644
--- a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
+++ b/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
@@ -16,6 +16,9 @@ public function up()
     {
         Schema::table('products', function (Blueprint $table) {
             $table->string('billing_period')->default("hourly");
+            $table->decimal('price', 15, 4)->change();
+            $table->decimal('minimum_credits', 15, 4)->change();
+
         });
 
         DB::statement('UPDATE products SET billing_period="hourly"');
@@ -38,6 +41,8 @@ public function down()
     {
         Schema::table('products', function (Blueprint $table) {
             $table->dropColumn('billing_period');
+            $table->decimal('price', 10, 0)->change();
+            $table->float('minimum_credits')->change();
         });
     }
 }
diff --git a/database/migrations/2022_06_16_094402_update_user_price_datatype.php b/database/migrations/2022_06_16_094402_update_user_credits_datatype.php
similarity index 82%
rename from database/migrations/2022_06_16_094402_update_user_price_datatype.php
rename to database/migrations/2022_06_16_094402_update_user_credits_datatype.php
index 9b4abb9e7..ed5922e86 100644
--- a/database/migrations/2022_06_16_094402_update_user_price_datatype.php
+++ b/database/migrations/2022_06_16_094402_update_user_credits_datatype.php
@@ -4,7 +4,7 @@
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Support\Facades\Schema;
 
-class UpdateUserPriceDatatype extends Migration
+class UpdateUserCreditsDatatype extends Migration
 {
     /**
      * Run the migrations.
@@ -14,7 +14,7 @@ class UpdateUserPriceDatatype extends Migration
     public function up()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->decimal('credits', 20, 10)->default(0)->change();
+            $table->decimal('credits', 15, 4)->default(0)->change();
         });
     }
 
@@ -27,6 +27,7 @@ public function down()
     {
         Schema::table('users', function (Blueprint $table) {
             $table->unsignedFloat('credits')->default(250)->change();
+
         });
     }
 }

From da0dd37559a9ba985def73ab677ffb1e97c51d7c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 16:15:57 +0200
Subject: [PATCH 061/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20last=5Fbill?=
 =?UTF-8?q?ed=20to=20server=20model=20&=20always=20charge=20first=20&=20fi?=
 =?UTF-8?q?xed=20Charge=20Server=20command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php    | 24 +++++++++++++++--------
 app/Http/Controllers/ServerController.php |  9 ++++-----
 app/Models/Server.php                     | 13 ++++++------
 3 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 678ab4b70..877cb8a5a 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -4,7 +4,9 @@
 
 use App\Models\Server;
 use App\Notifications\ServersSuspendedNotification;
+use Carbon\Carbon;
 use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
 
 class ChargeServers extends Command
 {
@@ -45,7 +47,7 @@ public function __construct()
      */
     public function handle()
     {
-        Server::whereNull('suspended')->with('users', 'products')->chunk(10, function ($servers) {
+        Server::whereNull('suspended')->with('user', 'product')->chunk(10, function ($servers) {
             /** @var Server $server */
             foreach ($servers as $server) {
                 /** @var Product $product */
@@ -55,23 +57,29 @@ public function handle()
 
                 $billing_period = $product->billing_period;
 
+
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
                 switch($billing_period) {
                     case 'monthly':
-                        $newBillingDate = $server->last_billed->addMonth();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
                     case 'weekly':
-                        $newBillingDate = $server->last_billed->addYear();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addYear();
                         break;
                     case 'daily':
-                        $newBillingDate = $server->last_billed->addDay();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addDay();
                         break;
+                    case 'hourly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addHour();
                     default:
-                        $newBillingDate = $server->last_billed->addHour();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addHour();
                         break;
                 };
-                if (!($newBillingDate <= now())) return;
+
+                if (!($newBillingDate->isPast())) {
+                    continue;
+                }
 
                 // check if user has enough credits to charge the server
                 if ($user->credits < $product->price) {
@@ -94,8 +102,8 @@ public function handle()
                 $this->line("<fg=blue>{$user->name}</> Current credits: <fg=green>{$user->credits}</> Credits to be removed: <fg=red>{$product->price}</>");
                 $user->decrement('credits', $product->price);
 
-                // update server last_billed date
-                $server->last_billed = $newBillingDate;
+                // update server last_billed date in db
+                DB::table('servers')->where('id', $server->id)->update(['last_billed' => $newBillingDate]);
             }
 
             return $this->notifyUsers();
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 656064c39..b066e77d6 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -10,6 +10,7 @@
 use App\Models\Product;
 use App\Models\Server;
 use App\Notifications\ServerCreationError;
+use Carbon\Carbon;
 use Exception;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Client\Response;
@@ -180,6 +181,7 @@ public function store(Request $request)
         $server = $request->user()->servers()->create([
             'name' => $request->input('name'),
             'product_id' => $request->input('product'),
+            'last_billed' => Carbon::now()->toDateTimeString(),
         ]);
 
         //get free allocation ID
@@ -201,11 +203,8 @@ public function store(Request $request)
             'identifier' => $serverAttributes['identifier'],
         ]);
 
-        if (config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
-            if ($request->user()->credits >= $server->product->getHourlyPrice()) {
-                $request->user()->decrement('credits', $server->product->getHourlyPrice());
-            }
-        }
+        // Charge first billing cycle
+        $request->user()->decrement('credits', $server->product->price);
 
         return redirect()->route('servers.index')->with('success', __('Server created'));
     }
diff --git a/app/Models/Server.php b/app/Models/Server.php
index 94365dd47..cf71f040e 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -47,12 +47,13 @@ public function getActivitylogOptions(): LogOptions
      * @var string[]
      */
     protected $fillable = [
-        'name',
-        'description',
-        'suspended',
-        'identifier',
-        'product_id',
-        'pterodactyl_id',
+        "name",
+        "description",
+        "suspended",
+        "identifier",
+        "product_id",
+        "pterodactyl_id",
+        "last_billed"
     ];
 
     /**

From 2e6c03e3cccfa1b93ed65c0ab814fde442ee6dcc Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 16:18:27 +0200
Subject: [PATCH 062/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Update=20last=5Fbil?=
 =?UTF-8?q?led=20to=20current=20time=20on=20unsuspend=20server?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Models/Server.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/app/Models/Server.php b/app/Models/Server.php
index cf71f040e..c3ea621a3 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -3,6 +3,7 @@
 namespace App\Models;
 
 use App\Classes\Pterodactyl;
+use Carbon\Carbon;
 use Exception;
 use GuzzleHttp\Promise\PromiseInterface;
 use Hidehalo\Nanoid\Client;
@@ -126,9 +127,11 @@ public function unSuspend()
         if ($response->successful()) {
             $this->update([
                 'suspended' => null,
+                'last_billed' => Carbon::now()->toDateTimeString(),
             ]);
         }
 
+
         return $this;
     }
 

From 907fb747347ab7ebe980ede1361bc04c651db5ae Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 16 Jun 2022 19:03:59 +0200
Subject: [PATCH 063/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20ChargeSe?=
 =?UTF-8?q?rver=20Command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 877cb8a5a..769909c32 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -65,7 +65,7 @@ public function handle()
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
                     case 'weekly':
-                        $newBillingDate = Carbon::parse($server->last_billed)->addYear();
+                        $newBillingDate = Carbon::parse($server->last_billed)->addWeek();
                         break;
                     case 'daily':
                         $newBillingDate = Carbon::parse($server->last_billed)->addDay();

From 117b75d3b75d21c88639030c2e175184ad25a414 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sat, 18 Jun 2022 23:41:40 +0200
Subject: [PATCH 064/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20different?=
 =?UTF-8?q?=20billing=20periods=20to=20servers=20overview=20page?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 208 ++++++++++++++++++++++++
 1 file changed, 208 insertions(+)
 create mode 100644 resources/views/servers/index.blade.php

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
new file mode 100644
index 000000000..517c3f1ea
--- /dev/null
+++ b/resources/views/servers/index.blade.php
@@ -0,0 +1,208 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{ __('Servers') }}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('servers.index') }}">{{ __('Servers') }}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+
+            <!-- CUSTOM CONTENT -->
+            <div class="d-flex justify-content-md-start justify-content-center mb-3 ">
+                <a @if (Auth::user()->Servers->count() >= Auth::user()->server_limit)
+                    disabled="disabled" title="Server limit reached!"
+                    @endif href="{{ route('servers.create') }}"
+                    class="btn
+                    @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled
+                    @endif btn-primary"><i
+                        class="fa fa-plus mr-2"></i>
+                    {{ __('Create Server') }}
+                </a>
+            </div>
+
+            <div class="row d-flex flex-row justify-content-center justify-content-md-start">
+                @foreach ($servers as $server)
+
+                    <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
+                        style="max-width: 350px">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between align-items-center">
+                                <h5 class="card-title mt-1">{{ $server->name }}
+                                </h5>
+                                <div class="card-tools mt-1">
+                                    <div class="dropdown no-arrow">
+                                        <a href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown"
+                                            aria-haspopup="true" aria-expanded="false">
+                                            <i class="fas fa-ellipsis-v fa-sm fa-fw text-white-50"></i>
+                                        </a>
+                                        <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
+                                            aria-labelledby="dropdownMenuLink">
+                                            @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
+                                                <a href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
+                                                    class="dropdown-item text-info" target="__blank"><i title="manage"
+                                                        class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
+                                            @endif
+                                            <div class="dropdown-divider"></div>
+                                            <span class="dropdown-item"><i title="Created at"
+                                                    class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }}</span></span>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="card-body">
+                            <div class="container mt-1">
+                                <div class="row mb-3">
+                                    <div class="col my-auto">{{ __('Status') }}:</div>
+                                    <div class="col-7 my-auto">
+                                        <i
+                                            class="fas {{ $server->isSuspended() ? 'text-danger' : 'text-success' }} fa-circle mr-2"></i>
+                                        {{ $server->isSuspended() ? 'Suspended' : 'Active' }}
+                                    </div>
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5">
+                                        {{ __('Location') }}:
+                                    </div>
+                                    <div class="col-7 d-flex justify-content-between align-items-center">
+                                        <span class="">{{ $server->location }}</span>
+                                        <i data-toggle="popover" data-trigger="hover"
+                                            data-content="{{ __('Node') }}: {{ $server->node }}"
+                                            class="fas fa-info-circle"></i>
+                                    </div>
+
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5 ">
+                                        {{ __('Software') }}:
+                                    </div>
+                                    <div class="col-7 text-wrap">
+                                        <span>{{ $server->nest }}</span>
+                                    </div>
+
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5 ">
+                                        {{ __('Specification') }}:
+                                    </div>
+                                    <div class="col-7 text-wrap">
+                                        <span>{{ $server->egg }}</span>
+                                    </div>
+                                </div>
+                                <div class="row mb-4">
+                                    <div class="col-5 ">
+                                        {{ __('Resource plan') }}:
+                                    </div>
+                                    <div class="col-7 text-wrap d-flex justify-content-between align-items-center">
+                                        <span>{{ $server->product->name }}
+                                        </span>
+                                        <i data-toggle="popover" data-trigger="hover" data-html="true"
+                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>"
+                                            class="fas fa-info-circle"></i>
+                                    </div>
+
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-4">
+                                        {{ __('Price') }}:
+                                        <span class="text-muted">
+                                            ({{ CREDITS_DISPLAY_NAME }})
+                                        </span>
+                                    </div>
+                                    <div class="col-8 text-center">
+                                        <div class="text-muted">
+                                        @if($server->product->billing_period == 'monthly')
+                                            {{ __('per Month') }}
+                                        @elseif($server->product->billing_period == 'weekly')
+                                            {{ __('per Week') }}
+                                        @elseif($server->product->billing_period == 'daily')
+                                            {{ __('per Day') }}
+                                        @elseif($server->product->billing_period == 'hourly')
+                                            {{ __('per Hour') }}
+                                        @endif
+                                            </div>
+                                        <span>
+                                            {{ $server->product->price }}
+                                        </span>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="card-footer d-flex align-items-center justify-content-between">
+                            <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
+                                target="__blank"
+                                class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex">
+                                <i class="fas fa-tools mr-2"></i>
+                                <span>{{ __('Manage') }}</span>
+                            </a>
+                            <button onclick="confirmSubmit('{{ $server->id }}', handleServerDelete);" target="__blank"
+                                class="btn btn-danger mx-3 w-100 align-items-center justify-content-center d-flex">
+                                <i class="fas fa-trash mr-2"></i>
+                                <span>{{ __('Delete') }}</span>
+                            </button>
+                        </div>
+                    </div>
+                @endforeach
+            </div>
+            <!-- END CUSTOM CONTENT -->
+        </div>
+    </section>
+    <!-- END CONTENT -->
+
+    <script>
+        const confirmSubmit = (serverId, handleServerDelete) => {
+            // Confirm delete submit with sweetalert
+            Swal.fire({
+                title: "{{ __('Are you sure?') }}",
+                text: "{{ __('This is an irreversible action, all files of this server will be removed.') }}",
+                icon: 'warning',
+                confirmButtonColor: '#d9534f',
+                showCancelButton: true,
+                confirmButtonText: "{{ __('Yes, delete it!') }}",
+                cancelButtonText: "{{ __('No, cancel!') }}",
+                reverseButtons: true
+            }).then((result) => {
+                if (result.value) {
+                    handleServerDelete(serverId);
+                    return
+                }
+                Swal.fire("{{ __('Canceled ...') }}", `{{ __('Deletion has been canceled.') }}`, 'info');
+            });
+        }
+
+        const handleServerDelete = (serverId) => {
+            // Delete server
+            fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
+                method: 'DELETE',
+                headers: {
+                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                }
+            }).then(() => {
+                window.location.reload();
+            });
+        }
+
+        document.addEventListener('DOMContentLoaded', () => {
+            $('[data-toggle="popover"]').popover();
+        });
+    </script>
+@endsection

From b1fc1f8fab496a867b2dde5e01f812a059db7e11 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sat, 18 Jun 2022 23:55:43 +0200
Subject: [PATCH 065/514] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Added=20Addon=20?=
 =?UTF-8?q?Docs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Addon-notes.md | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 Addon-notes.md

diff --git a/Addon-notes.md b/Addon-notes.md
new file mode 100644
index 000000000..3c335a7f6
--- /dev/null
+++ b/Addon-notes.md
@@ -0,0 +1,3 @@
+Export diff files:
+
+cp -pv --parents $(git diff <commit> --name-only) "..\controllpanelgg-monthly-addon\files-git-diff\"

From 35e54be1557981e2ab63c2b03ed6132caa1cf400 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Sun, 19 Jun 2022 00:13:54 +0200
Subject: [PATCH 066/514] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Updated=20Export?=
 =?UTF-8?q?=20doc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Addon-notes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index 3c335a7f6..baf40c6aa 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,3 +1,3 @@
 Export diff files:
 
-cp -pv --parents $(git diff <commit> --name-only) "..\controllpanelgg-monthly-addon\files-git-diff\"
+git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf file.tgz -T -

From dfdba1e26ee6e1d85646255e2f1c4aa6d198a40f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Wed, 22 Jun 2022 12:01:47 +0200
Subject: [PATCH 067/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20No=20pro?=
 =?UTF-8?q?duct=20available=20at=20creation=20time?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/admin/products/create.blade.php | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index 913fda1f0..fa8884d22 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -171,20 +171,16 @@ class="fas fa-info-circle"></i></label>
 
                                             <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
                                                 autocomplete="off" @error('billing_period') is-invalid @enderror>
-                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
-                                                    @endif>
+                                                    <option value="hourly" selected>
                                                         {{__('Hourly')}}
                                                     </option>
-                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
-                                                    @endif>
+                                                    <option value="daily">
                                                         {{__('Daily')}}
                                                     </option>
-                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
-                                                    @endif>
+                                                    <option value="weekly">
                                                         {{__('Weekly')}}
                                                     </option>
-                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
-                                                     @endif>
+                                                     <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
                                             </select>

From 994314dbe4673e25bae89c057130c2766edc675b Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 01:50:45 +0200
Subject: [PATCH 068/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20migrations?=
 =?UTF-8?q?=20undo=20last=20patch=20db=20update=20&=20add=20cancelation=20?=
 =?UTF-8?q?of=20servers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...34527_add_cancelation_to_servers_table.php | 32 +++++++++++++++++++
 ...022_07_21_234818_undo_decimal_in_price.php | 32 +++++++++++++++++++
 2 files changed, 64 insertions(+)
 create mode 100644 database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
 create mode 100644 database/migrations/2022_07_21_234818_undo_decimal_in_price.php

diff --git a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
new file mode 100644
index 000000000..b9f758391
--- /dev/null
+++ b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddCancelationToServersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->boolean('canceled')->default(false);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->dropColumn('canceled');
+        });
+    }
+}
diff --git a/database/migrations/2022_07_21_234818_undo_decimal_in_price.php b/database/migrations/2022_07_21_234818_undo_decimal_in_price.php
new file mode 100644
index 000000000..cf4abb69b
--- /dev/null
+++ b/database/migrations/2022_07_21_234818_undo_decimal_in_price.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class UndoDecimalInPrice extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->decimal('price', 15, 4)->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->decimal('price',['11','2'])->change();
+        });
+    }
+}

From 642fef6864ca119577fb008d0368d8a41350eec3 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 02:58:08 +0200
Subject: [PATCH 069/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Cancel=20Bu?=
 =?UTF-8?q?tton=20&=20Next=20Billing=20Cycle=20field?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 116 ++++++++++++++++++------
 1 file changed, 89 insertions(+), 27 deletions(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 517c3f1ea..9c9d81b06 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -40,7 +40,6 @@ class="fa fa-plus mr-2"></i>
 
             <div class="row d-flex flex-row justify-content-center justify-content-md-start">
                 @foreach ($servers as $server)
-
                     <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
                         style="max-width: 350px">
                         <div class="card-header">
@@ -107,7 +106,7 @@ class="fas fa-info-circle"></i>
                                         <span>{{ $server->egg }}</span>
                                     </div>
                                 </div>
-                                <div class="row mb-4">
+                                <div class="row mb-2">
                                     <div class="col-5 ">
                                         {{ __('Resource plan') }}:
                                     </div>
@@ -115,11 +114,43 @@ class="fas fa-info-circle"></i>
                                         <span>{{ $server->product->name }}
                                         </span>
                                         <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>"
+                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
                                             class="fas fa-info-circle"></i>
                                     </div>
+                                </div>
 
+                                <div class="row mb-4 ">
+                                    <div class="col-5 ">
+                                        {{ __('Next Billing Cycle') }}:
+                                    </div>
+                                    <div class="col-7 d-flex text-wrap align-items-center">
+                                        <span>
+                                        @switch($server->product->billing_period)
+                                            @case('monthly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('weekly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('daily')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('hourly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                                @break
+                                            @case('half-yearly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
+                                                @break
+                                            @case('yearly')
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
+                                                @break
+                                            @default
+                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                        @endswitch
+                                        </span>
+                                    </div>
                                 </div>
+
                                 <div class="row mb-2">
                                     <div class="col-4">
                                         {{ __('Price') }}:
@@ -147,17 +178,22 @@ class="fas fa-info-circle"></i>
                             </div>
                         </div>
 
-                        <div class="card-footer d-flex align-items-center justify-content-between">
+                        <div class="card-footer text-center">
                             <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
                                 target="__blank"
-                                class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex">
-                                <i class="fas fa-tools mr-2"></i>
-                                <span>{{ __('Manage') }}</span>
+                                class="btn btn-info text-center float-left ml-2"
+                                data-toggle="tooltip" data-placement="bottom" title="Manage Server">
+                                <i class="fas fa-tools mx-4"></i>
                             </a>
-                            <button onclick="confirmSubmit('{{ $server->id }}', handleServerDelete);" target="__blank"
-                                class="btn btn-danger mx-3 w-100 align-items-center justify-content-center d-flex">
-                                <i class="fas fa-trash mr-2"></i>
-                                <span>{{ __('Delete') }}</span>
+                            <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
+                                class="btn btn-warning  text-center"
+                                data-toggle="tooltip" data-placement="bottom" title="Cancel Server">
+                                <i class="fas fa-ban mx-4"></i>
+                            </button>
+                            <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
+                                class="btn btn-danger  text-center float-right mr-2"
+                                data-toggle="tooltip" data-placement="bottom" title="Delete Server">
+                                <i class="fas fa-trash mx-4"></i>
                             </button>
                         </div>
                     </div>
@@ -169,40 +205,66 @@ class="btn btn-danger mx-3 w-100 align-items-center justify-content-center d-fle
     <!-- END CONTENT -->
 
     <script>
-        const confirmSubmit = (serverId, handleServerDelete) => {
-            // Confirm delete submit with sweetalert
+        const handleServerCancel = (serverId) => {
+            // Handle server cancel with sweetalert
             Swal.fire({
-                title: "{{ __('Are you sure?') }}",
-                text: "{{ __('This is an irreversible action, all files of this server will be removed.') }}",
+                title: "{{ __('Cancel Server?') }}",
+                text: "{{ __('This will cancel your current server to the next billing period. It will get suspended when the current period runs out.') }}",
                 icon: 'warning',
                 confirmButtonColor: '#d9534f',
                 showCancelButton: true,
-                confirmButtonText: "{{ __('Yes, delete it!') }}",
-                cancelButtonText: "{{ __('No, cancel!') }}",
+                confirmButtonText: "{{ __('Yes, cancel it!') }}",
+                cancelButtonText: "{{ __('No, abort!') }}",
                 reverseButtons: true
             }).then((result) => {
                 if (result.value) {
-                    handleServerDelete(serverId);
+                    // Delete server
+                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
+                        method: 'DELETE',
+                        headers: {
+                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                        }
+                    }).then(() => {
+                        window.location.reload();
+                    });
                     return
                 }
-                Swal.fire("{{ __('Canceled ...') }}", `{{ __('Deletion has been canceled.') }}`, 'info');
-            });
+            })
         }
 
         const handleServerDelete = (serverId) => {
-            // Delete server
-            fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
-                method: 'DELETE',
-                headers: {
-                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
+            Swal.fire({
+                title: "{{ __('Delete Server?') }}",
+                text: "{{ __('This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.') }}",
+                icon: 'warning',
+                confirmButtonColor: '#d9534f',
+                showCancelButton: true,
+                confirmButtonText: "{{ __('Yes, delete it!') }}",
+                cancelButtonText: "{{ __('No, abort!') }}",
+                reverseButtons: true
+            }).then((result) => {
+                if (result.value) {
+                    // Delete server
+                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
+                        method: 'DELETE',
+                        headers: {
+                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                        }
+                    }).then(() => {
+                        window.location.reload();
+                    });
+                    return
                 }
-            }).then(() => {
-                window.location.reload();
             });
+
         }
 
         document.addEventListener('DOMContentLoaded', () => {
             $('[data-toggle="popover"]').popover();
         });
+
+        $(function () {
+            $('[data-toggle="tooltip"]').tooltip()
+        })
     </script>
 @endsection

From f8c33d43befbde99866b9bdb4a290661ad91d4e6 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 03:51:05 +0200
Subject: [PATCH 070/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Typo?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2022_07_21_234527_add_cancelation_to_servers_table.php    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
index b9f758391..15fafb168 100644
--- a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
+++ b/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
@@ -14,7 +14,7 @@ class AddCancelationToServersTable extends Migration
     public function up()
     {
         Schema::table('servers', function (Blueprint $table) {
-            $table->boolean('canceled')->default(false);
+            $table->dateTime('cancelled')->nullable();
         });
     }
 
@@ -26,7 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('servers', function (Blueprint $table) {
-            $table->dropColumn('canceled');
+            $table->dropColumn('cancelled');
         });
     }
 }

From 7fa9bf206243af2dab4c51d74d781ae0f73048c0 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 03:52:49 +0200
Subject: [PATCH 071/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Server=20Ca?=
 =?UTF-8?q?ncelation=20route=20method=20and=20charging?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php        |  8 ++++----
 .../Controllers/Admin/ServerController.php    | 20 ++++++++++++++++++-
 app/Http/Controllers/ServerController.php     | 16 ++++++++++++++-
 app/Models/Server.php                         |  3 ++-
 resources/views/servers/index.blade.php       |  4 ++--
 routes/web.php                                |  2 ++
 6 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 769909c32..2a5d8a5ad 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -81,14 +81,14 @@ public function handle()
                     continue;
                 }
 
-                // check if user has enough credits to charge the server
-                if ($user->credits < $product->price) {
+                // check if the server is canceled or if user has enough credits to charge the server or
+                if ( $server->cancelled || $user->credits < $product->price) {
                     try {
-                        #suspend server
+                        // suspend server
                         $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
                         $server->suspend();
 
-                        #add user to notify list
+                        // add user to notify list
                         if (!in_array($user, $this->usersToNotify)) {
                             array_push($this->usersToNotify, $user);
                         }
diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index 06d2cc22b..b4e06ed1d 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -133,7 +133,25 @@ public function destroy(Server $server)
     }
 
     /**
-     * @param  Server  $server
+     * Cancel the Server billing cycle.
+     *
+     * @param Server $server
+     * @return RedirectResponse|Response
+     */
+    public function cancel (Server $server)
+    {
+        try {
+            error_log($server->update([
+                'cancelled' => now(),
+            ]));
+            return redirect()->route('servers.index')->with('success', __('Server cancelled'));
+        } catch (Exception $e) {
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
+        }
+    }
+
+    /**
+     * @param Server $server
      * @return RedirectResponse
      */
     public function toggleSuspended(Server $server)
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index b066e77d6..bef8338a1 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -246,7 +246,21 @@ public function destroy(Server $server)
 
             return redirect()->route('servers.index')->with('success', __('Server removed'));
         } catch (Exception $e) {
-            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to remove a resource "').$e->getMessage().'"');
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to delete the server"') . $e->getMessage() . '"');
+        }
+    }
+
+    /** Cancel Server */
+    public function cancel (Server $server)
+    {
+        try {
+            error_log($server->update([
+                'cancelled' => now(),
+            ]));
+
+            return redirect()->route('servers.index')->with('success', __('Server cancelled'));
+        } catch (Exception $e) {
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
         }
     }
 
diff --git a/app/Models/Server.php b/app/Models/Server.php
index c3ea621a3..b2c19b8be 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -54,7 +54,8 @@ public function getActivitylogOptions(): LogOptions
         "identifier",
         "product_id",
         "pterodactyl_id",
-        "last_billed"
+        "last_billed",
+        "cancelled"
     ];
 
     /**
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 9c9d81b06..e96b46b12 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -219,8 +219,8 @@ class="btn btn-danger  text-center float-right mr-2"
             }).then((result) => {
                 if (result.value) {
                     // Delete server
-                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
-                        method: 'DELETE',
+                    fetch("{{ route('servers.cancel', '') }}" + '/' + serverId, {
+                        method: 'PATCH',
                         headers: {
                             'X-CSRF-TOKEN': '{{ csrf_token() }}'
                         }
diff --git a/routes/web.php b/routes/web.php
index c86a0c66c..d980e3a4e 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -72,6 +72,7 @@
     //normal routes
     Route::get('notifications/readAll', [NotificationController::class, 'readAll'])->name('notifications.readAll');
     Route::resource('notifications', NotificationController::class);
+    Route::patch('/servers/cancel/{server}', [ServerController::class, 'cancel'])->name('servers.cancel');
     Route::resource('servers', ServerController::class);
     if (config('SETTINGS::SYSTEM:ENABLE_UPGRADE')) {
         Route::post('servers/{server}/upgrade', [ServerController::class, 'upgrade'])->name('servers.upgrade');
@@ -140,6 +141,7 @@
         //servers
         Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');
         Route::post('servers/togglesuspend/{server}', [AdminServerController::class, 'toggleSuspended'])->name('servers.togglesuspend');
+        Route::patch('/servers/cancel/{server}', [AdminServerController::class, 'cancel'])->name('servers.cancel');
         Route::get('servers/sync', [AdminServerController::class, 'syncServers'])->name('servers.sync');
         Route::resource('servers', AdminServerController::class);
 

From 759ba599881463b530dcbc33b6f1bcb3d9335265 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:00:23 +0200
Subject: [PATCH 072/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20yearly=20an?=
 =?UTF-8?q?d=20half-yearly=20billing=20periods?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php               | 6 ++++++
 app/Http/Controllers/Admin/ProductController.php     | 4 ++--
 resources/views/servers/index.blade.php              | 4 ++++
 themes/default/views/admin/products/create.blade.php | 6 ++++++
 themes/default/views/admin/products/edit.blade.php   | 8 ++++++++
 5 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 2a5d8a5ad..45f18c2b1 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -61,6 +61,12 @@ public function handle()
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
                 switch($billing_period) {
+                    case 'yearly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addYear();
+                        break;
+                    case 'half-yearly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
+                        break;
                     case 'monthly':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 2893a262a..9e6c6dc2c 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -72,7 +72,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -139,7 +139,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index e96b46b12..1d0edd657 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -162,6 +162,10 @@ class="fas fa-info-circle"></i>
                                         <div class="text-muted">
                                         @if($server->product->billing_period == 'monthly')
                                             {{ __('per Month') }}
+                                        @elseif($server->product->billing_period == 'half-yearly')
+                                            {{ __('per 6 Months') }}
+                                        @elseif($server->product->billing_period == 'yearly')
+                                            {{ __('per Year') }}
                                         @elseif($server->product->billing_period == 'weekly')
                                             {{ __('per Week') }}
                                         @elseif($server->product->billing_period == 'daily')
diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index fa8884d22..324c03c5f 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -183,6 +183,12 @@ class="fas fa-info-circle"></i></label>
                                                      <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="half-yearly">
+                                                        {{__('Half Yearly')}}
+                                                    </option>
+                                                    <option value="yearly">
+                                                        {{__('Yearly')}}
+                                                    </option>
                                             </select>
                                             @error('billing_period')
                                             <div class="invalid-feedback">
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index cedbc72c8..3401577b5 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -190,6 +190,14 @@ class="fas fa-info-circle"></i></label>
                                                      @endif>
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="half-yearly" @if ($product->billing_period  == 'half-yearly') selected
+                                                    @endif>
+                                                        {{__('Half Yearly')}}
+                                                    </option>
+                                                    <option value="yearly" @if ($product->billing_period  == 'yearly') selected
+                                                    @endif>
+                                                        {{__('Yearly')}}
+                                                    </option>
                                             </select>
                                             @error('billing_period')
                                             <div class="invalid-feedback">

From 34bd88a4f607e892b2fb5219eb75ceeabccaed9b Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:09:34 +0200
Subject: [PATCH 073/514] =?UTF-8?q?refactor:=20=F0=9F=9A=9A=20Rename=20Yea?=
 =?UTF-8?q?rly=20->=20Annually?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php        |  4 +-
 .../Controllers/Admin/ProductController.php   |  4 +-
 resources/views/servers/index.blade.php       | 62 +++++++++++--------
 .../views/admin/products/create.blade.php     |  8 +--
 .../views/admin/products/edit.blade.php       |  8 +--
 5 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 45f18c2b1..dac01f0f8 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -61,10 +61,10 @@ public function handle()
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
                 switch($billing_period) {
-                    case 'yearly':
+                    case 'annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addYear();
                         break;
-                    case 'half-yearly':
+                    case 'half-annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
                         break;
                     case 'monthly':
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 9e6c6dc2c..78ad6c997 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -72,7 +72,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -139,7 +139,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-yearly,yearly",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 1d0edd657..fdcf2d104 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -72,9 +72,13 @@ class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }
                                 <div class="row mb-3">
                                     <div class="col my-auto">{{ __('Status') }}:</div>
                                     <div class="col-7 my-auto">
-                                        <i
-                                            class="fas {{ $server->isSuspended() ? 'text-danger' : 'text-success' }} fa-circle mr-2"></i>
-                                        {{ $server->isSuspended() ? 'Suspended' : 'Active' }}
+                                        @if($server->suspennded)
+                                            <span class="badge badge-danger">{{ __('Suspended') }}</span>
+                                        @elseif($server->cancelled)
+                                            <span class="badge badge-warning">{{ __('Cancelled') }}</span>
+                                        @else
+                                            <span class="badge badge-success">{{ __('Active') }}</span>
+                                        @endif
                                     </div>
                                 </div>
                                 <div class="row mb-2">
@@ -125,28 +129,32 @@ class="fas fa-info-circle"></i>
                                     </div>
                                     <div class="col-7 d-flex text-wrap align-items-center">
                                         <span>
-                                        @switch($server->product->billing_period)
-                                            @case('monthly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('weekly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('daily')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('hourly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
-                                                @break
-                                            @case('half-yearly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
-                                                @break
-                                            @case('yearly')
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
-                                                @break
-                                            @default
-                                                {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
-                                        @endswitch
+                                        @if ($server->cancelled)
+                                            -
+                                        @else
+                                            @switch($server->product->billing_period)
+                                                @case('monthly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('weekly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('daily')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('hourly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('half-annually')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('annually')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
+                                                    @break
+                                                @default
+                                                    {{ __('Unknown') }}
+                                            @endswitch
+                                        @endif
                                         </span>
                                     </div>
                                 </div>
@@ -162,9 +170,9 @@ class="fas fa-info-circle"></i>
                                         <div class="text-muted">
                                         @if($server->product->billing_period == 'monthly')
                                             {{ __('per Month') }}
-                                        @elseif($server->product->billing_period == 'half-yearly')
+                                        @elseif($server->product->billing_period == 'half-annually')
                                             {{ __('per 6 Months') }}
-                                        @elseif($server->product->billing_period == 'yearly')
+                                        @elseif($server->product->billing_period == 'annually')
                                             {{ __('per Year') }}
                                         @elseif($server->product->billing_period == 'weekly')
                                             {{ __('per Week') }}
diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index 324c03c5f..ed490c2e0 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -183,11 +183,11 @@ class="fas fa-info-circle"></i></label>
                                                      <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
-                                                    <option value="half-yearly">
-                                                        {{__('Half Yearly')}}
+                                                    <option value="half-annually">
+                                                        {{__('Half Annually')}}
                                                     </option>
-                                                    <option value="yearly">
-                                                        {{__('Yearly')}}
+                                                    <option value="annually">
+                                                        {{__('Annually')}}
                                                     </option>
                                             </select>
                                             @error('billing_period')
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 3401577b5..9d3aec529 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -190,13 +190,13 @@ class="fas fa-info-circle"></i></label>
                                                      @endif>
                                                         {{__('Monthly')}}
                                                     </option>
-                                                    <option value="half-yearly" @if ($product->billing_period  == 'half-yearly') selected
+                                                    <option value="half-annually" @if ($product->billing_period  == 'half-annually') selected
                                                     @endif>
-                                                        {{__('Half Yearly')}}
+                                                        {{__('Half Annually')}}
                                                     </option>
-                                                    <option value="yearly" @if ($product->billing_period  == 'yearly') selected
+                                                    <option value="annually" @if ($product->billing_period  == 'annually') selected
                                                     @endif>
-                                                        {{__('Yearly')}}
+                                                        {{__('Annually')}}
                                                     </option>
                                             </select>
                                             @error('billing_period')

From 9ad2954f0e10b398d66e93b793cc1287664b3e08 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:15:40 +0200
Subject: [PATCH 074/514] =?UTF-8?q?fix:=20=F0=9F=93=9D=20Undo=20Naming?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index bef8338a1..41644158f 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -246,7 +246,7 @@ public function destroy(Server $server)
 
             return redirect()->route('servers.index')->with('success', __('Server removed'));
         } catch (Exception $e) {
-            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to delete the server"') . $e->getMessage() . '"');
+            return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to remove a resource"') . $e->getMessage() . '"');
         }
     }
 

From 2c4b3ea03ec272ab14bb9cd27dbe676f91dd833c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:25:23 +0200
Subject: [PATCH 075/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20Localization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lang/de.json                            | 21 +++++++++++++++++++++
 lang/sh.json                            | 23 ++++++++++++++++++++++-
 resources/views/servers/index.blade.php |  6 +++---
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/lang/de.json b/lang/de.json
index 9107634ba..8c193fae4 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -459,6 +459,27 @@
     "zh": "Chinesisch",
     "tr": "Türkisch",
     "ru": "Russisch",
+    "hourly": "Stündlich",
+    "monthly": "Monatlich",
+    "yearly": "Jährlich",
+    "daily": "Täglich",
+    "weekly": "Wöchentlich",
+    "half-annually": "Halbjährlich",
+    "annually": "Jährlich",
+    "Cancelled": "Gekündigt",
+    "An exception has occurred while trying to cancel the server": "Ein Fehler ist aufgetreten beim Versuch, den Server zu kündigen",
+    "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "Dies wird Ihren aktuellen Server zur nächsten Abrechnungsperiode kündigen. Er wird beim Ablauf der aktuellen Periode gesperrt.",
+    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "Dies ist eine irreversibel Aktion, alle Dateien dieses Servers werden gelöscht. Keine Gelder werden zurückgezahlt. Wir empfehlen, den Server zu löschen, wenn er gesperrt ist.",
+    "Cancel Server?": "Server kündigen?",
+    "Delete Server?": "Server löschen?",
+    "Billing Period": "Abrechnungsperiode",
+    "Next Billing Cycle": "Nächste Abrechnungsperiode",
+    "Manage Server": "Server verwalten",
+    "Delete Server": "Server löschen",
+    "Cancel Server": "Server kündigen",
+    "Yes, cancel it!": "Ja, löschen!",
+    "No, abort!": "Abbrechen",
+    "Billing period": "Abrechnungsperiode",
     "sv": "Schwedisch",
     "sk": "Slowakisch",
     "Imprint": "Impressum",
diff --git a/lang/sh.json b/lang/sh.json
index 2755ad282..2badf679a 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -441,5 +441,26 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Russian"
+    "ru": "Russian",
+    "hourly": "Hourly",
+    "monthly": "Monthly",
+    "yearly": "Yearly",
+    "daily": "Daily",
+    "weekly": "Weekly",
+    "half-annually": "Half-annually",
+    "annually": "Annually",
+    "Cancelled": "Cancelled",
+    "An exception has occurred while trying to cancel the server": "An exception has occurred while trying to cancel the server",
+    "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
+    "Cancel Server?": "Cancel Server?",
+    "Delete Server?": "Delete Server?",
+    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.",
+    "Billing Period": "Billing Period",
+    "Next Billing Cycle": "Next Billing Cycle",
+    "Manage Server": "Manage Server",
+    "Delete Server": "Delete Server",
+    "Cancel Server": "Cancel Server",
+    "Yes, cancel it!": "Yes, cancel it!",
+    "No, abort!": "No, abort!",
+    "Billing period": "Billing period"
 }
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index fdcf2d104..d907a2780 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -194,17 +194,17 @@ class="fas fa-info-circle"></i>
                             <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
                                 target="__blank"
                                 class="btn btn-info text-center float-left ml-2"
-                                data-toggle="tooltip" data-placement="bottom" title="Manage Server">
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
                                 <i class="fas fa-tools mx-4"></i>
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                data-toggle="tooltip" data-placement="bottom" title="Cancel Server">
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>
                             <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
                                 class="btn btn-danger  text-center float-right mr-2"
-                                data-toggle="tooltip" data-placement="bottom" title="Delete Server">
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
                                 <i class="fas fa-trash mx-4"></i>
                             </button>
                         </div>

From ecfa16045030b748a4fabd0578494be7e4fc0e4f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:31:00 +0200
Subject: [PATCH 076/514] =?UTF-8?q?fix:=20=F0=9F=92=84=20Added=20hyphens?=
 =?UTF-8?q?=20at=20next=20billing=20cycle=20field?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index d907a2780..df7bd1789 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -124,7 +124,7 @@ class="fas fa-info-circle"></i>
                                 </div>
 
                                 <div class="row mb-4 ">
-                                    <div class="col-5 ">
+                                    <div class="col-5 word-break" style="hyphens: auto">
                                         {{ __('Next Billing Cycle') }}:
                                     </div>
                                     <div class="col-7 d-flex text-wrap align-items-center">

From 8a4273a8fbefd94181d6f426c2607d90503d9ed0 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:33:54 +0200
Subject: [PATCH 077/514] =?UTF-8?q?style:=20=F0=9F=92=84=20Changed=20Next?=
 =?UTF-8?q?=20Billing=20Cycle=20behaviour?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index df7bd1789..9b5a3ac9d 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -129,7 +129,7 @@ class="fas fa-info-circle"></i>
                                     </div>
                                     <div class="col-7 d-flex text-wrap align-items-center">
                                         <span>
-                                        @if ($server->cancelled)
+                                        @if ($server->suspended)
                                             -
                                         @else
                                             @switch($server->product->billing_period)

From 54e14d5f2b9b5b3b80d19011a2f06418622854d1 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:40:03 +0200
Subject: [PATCH 078/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fiy=20suspended?=
 =?UTF-8?q?=20typo=20&=20localization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lang/de.json                            | 1 +
 lang/sh.json                            | 1 +
 resources/views/servers/index.blade.php | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/lang/de.json b/lang/de.json
index 8c193fae4..a9a5061b4 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -466,6 +466,7 @@
     "weekly": "Wöchentlich",
     "half-annually": "Halbjährlich",
     "annually": "Jährlich",
+    "Suspended": "Gesperrt",
     "Cancelled": "Gekündigt",
     "An exception has occurred while trying to cancel the server": "Ein Fehler ist aufgetreten beim Versuch, den Server zu kündigen",
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "Dies wird Ihren aktuellen Server zur nächsten Abrechnungsperiode kündigen. Er wird beim Ablauf der aktuellen Periode gesperrt.",
diff --git a/lang/sh.json b/lang/sh.json
index 2badf679a..fc9457eb7 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -449,6 +449,7 @@
     "weekly": "Weekly",
     "half-annually": "Half-annually",
     "annually": "Annually",
+    "Suspended": "Suspended",
     "Cancelled": "Cancelled",
     "An exception has occurred while trying to cancel the server": "An exception has occurred while trying to cancel the server",
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 9b5a3ac9d..0fdac5a2f 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -72,7 +72,7 @@ class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }
                                 <div class="row mb-3">
                                     <div class="col my-auto">{{ __('Status') }}:</div>
                                     <div class="col-7 my-auto">
-                                        @if($server->suspennded)
+                                        @if($server->suspended)
                                             <span class="badge badge-danger">{{ __('Suspended') }}</span>
                                         @elseif($server->cancelled)
                                             <span class="badge badge-warning">{{ __('Cancelled') }}</span>
@@ -199,6 +199,7 @@ class="btn btn-info text-center float-left ml-2"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
+                                disabled="{{ $server->suspended }}"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>

From e310dba243f10d0ebe704d66dd581a8aa7be227b Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 04:54:33 +0200
Subject: [PATCH 079/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Credt=20usage=20a?=
 =?UTF-8?q?t=20dashboard?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/HomeController.php |  2 +-
 app/Models/Product.php                  | 16 +++++++++++++++-
 app/Models/User.php                     | 10 +++++++++-
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 5a5117589..db00d18d1 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -97,7 +97,7 @@ public function index(Request $request)
 
         /** Build our Time-Left-Box */
         if ($credits > 0.01 and $usage > 0) {
-            $daysLeft = number_format(($credits * 30) / $usage, 2, '.', '');
+            $daysLeft = number_format($credits / ($usage / 30), 2, '.', '');
             $hoursLeft = number_format($credits / ($usage / 30 / 24), 2, '.', '');
 
             $bg = $this->getTimeLeftBoxBackground($daysLeft);
diff --git a/app/Models/Product.php b/app/Models/Product.php
index a31ebf50a..c55d3be85 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -43,7 +43,21 @@ public static function boot()
 
     public function getHourlyPrice()
     {
-        return ($this->price / 30) / 24;
+        // calculate the hourly price with the billing period
+        switch($this->billing_period) {
+            case 'daily':
+                return $this->price / 24;
+            case 'weekly':
+                return $this->price / 24 / 7;
+            case 'monthly':
+                return $this->price / 24 / 30;
+            case 'half-annually':
+                return $this->price / 24 / 30 / 6;
+            case 'annually':
+                return $this->price / 24 / 365;
+            default:
+                return $this->price;
+        }
     }
 
     public function getDailyPrice()
diff --git a/app/Models/User.php b/app/Models/User.php
index 85e2b2405..91e15cab3 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -251,12 +251,20 @@ public function creditUsage()
     {
         $usage = 0;
         foreach ($this->getServersWithProduct() as $server) {
-            $usage += $server->product->price;
+            $usage += $server->product->getHourlyPrice() * 24 * 30;
         }
 
         return number_format($usage, 2, '.', '');
     }
 
+    private function getServersWithProduct() {
+        return $this->servers()
+            ->whereNull('suspended')
+            ->whereNull('cancelled')
+            ->with('product')
+            ->get();
+    }
+
     /**
      * @return array|string|string[]
      */

From e4165181fed498f94992f86902163da3db8d337d Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:06:38 +0200
Subject: [PATCH 080/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Disable=20Cancel?=
 =?UTF-8?q?=20Button?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 0fdac5a2f..862174f3d 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -199,7 +199,7 @@ class="btn btn-info text-center float-left ml-2"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                disabled="{{ $server->suspended }}"
+                                {{ $server->suspended? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>

From 3f4cae352a10855152c6da332aa2e37076573b3f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:12:06 +0200
Subject: [PATCH 081/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Disable=20cancel?=
 =?UTF-8?q?=20button=20when=20cancelled?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 862174f3d..8ccffc874 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -199,7 +199,7 @@ class="btn btn-info text-center float-left ml-2"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                {{ $server->suspended? "disabled" : "" }}
+                                {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-4"></i>
                             </button>

From 8565faa40b0dffd10e04da234afe04d520773107 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:26:48 +0200
Subject: [PATCH 082/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20Added=20Bold=20?=
 =?UTF-8?q?text=20for=20No=20refund?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lang/de.json                            | 2 +-
 lang/sh.json                            | 2 +-
 resources/views/servers/index.blade.php | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lang/de.json b/lang/de.json
index a9a5061b4..45f1cc826 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -470,7 +470,7 @@
     "Cancelled": "Gekündigt",
     "An exception has occurred while trying to cancel the server": "Ein Fehler ist aufgetreten beim Versuch, den Server zu kündigen",
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "Dies wird Ihren aktuellen Server zur nächsten Abrechnungsperiode kündigen. Er wird beim Ablauf der aktuellen Periode gesperrt.",
-    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "Dies ist eine irreversibel Aktion, alle Dateien dieses Servers werden gelöscht. Keine Gelder werden zurückgezahlt. Wir empfehlen, den Server zu löschen, wenn er gesperrt ist.",
+    "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.": "Dies ist eine irreversiblen Aktion, alle Dateien dieses Servers werden gelöscht. <strong>Keine Rückerstattung!</strong>. Wir empfehlen, den Server zu löschen, wenn er gesperrt ist.",
     "Cancel Server?": "Server kündigen?",
     "Delete Server?": "Server löschen?",
     "Billing Period": "Abrechnungsperiode",
diff --git a/lang/sh.json b/lang/sh.json
index fc9457eb7..14c206ff5 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -455,7 +455,7 @@
     "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
     "Cancel Server?": "Cancel Server?",
     "Delete Server?": "Delete Server?",
-    "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.",
+    "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.",
     "Billing Period": "Billing Period",
     "Next Billing Cycle": "Next Billing Cycle",
     "Manage Server": "Manage Server",
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 8ccffc874..53490a292 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -248,7 +248,7 @@ class="btn btn-danger  text-center float-right mr-2"
         const handleServerDelete = (serverId) => {
             Swal.fire({
                 title: "{{ __('Delete Server?') }}",
-                text: "{{ __('This is an irreversible action, all files of this server will be removed. No funds will get refunded. We recommend deleting the server when server is suspended.') }}",
+                html: "{{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}}",
                 icon: 'warning',
                 confirmButtonColor: '#d9534f',
                 showCancelButton: true,

From e254b2acfed7da2911acbfb0a04e8e800b73a024 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Fri, 22 Jul 2022 05:31:05 +0200
Subject: [PATCH 083/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Quartely=20?=
 =?UTF-8?q?billing=20period?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php               | 3 +++
 app/Http/Controllers/Admin/ProductController.php     | 4 ++--
 app/Models/Product.php                               | 2 ++
 lang/de.json                                         | 1 +
 lang/sh.json                                         | 1 +
 resources/views/servers/index.blade.php              | 5 +++++
 themes/default/views/admin/products/create.blade.php | 3 +++
 themes/default/views/admin/products/edit.blade.php   | 4 ++++
 8 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index dac01f0f8..72b5bab4d 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -67,6 +67,9 @@ public function handle()
                     case 'half-annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
                         break;
+                    case 'quarterly':
+                        $newBillingDate = Carbon::parse($server->last_billed)->addMonths(3);
+                        break;
                     case 'monthly':
                         $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
                         break;
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 78ad6c997..ca997ee82 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -72,7 +72,7 @@ public function store(Request $request)
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,quarterly,half-annually,annually",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -139,7 +139,7 @@ public function update(Request $request, Product $product): RedirectResponse
             "nodes.*" => "required|exists:nodes,id",
             "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
-            "billing_period" => "required|in:hourly,daily,weekly,monthly,half-annually,annually",
+            "billing_period" => "required|in:hourly,daily,weekly,monthly,quarterly,half-annually,annually",
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
diff --git a/app/Models/Product.php b/app/Models/Product.php
index c55d3be85..fbd16803a 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -51,6 +51,8 @@ public function getHourlyPrice()
                 return $this->price / 24 / 7;
             case 'monthly':
                 return $this->price / 24 / 30;
+            case 'quarterly':
+                return $this->price / 24 / 30 / 3;
             case 'half-annually':
                 return $this->price / 24 / 30 / 6;
             case 'annually':
diff --git a/lang/de.json b/lang/de.json
index 45f1cc826..b01d61b70 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -464,6 +464,7 @@
     "yearly": "Jährlich",
     "daily": "Täglich",
     "weekly": "Wöchentlich",
+    "quarterly": "Vierteljährlich",
     "half-annually": "Halbjährlich",
     "annually": "Jährlich",
     "Suspended": "Gesperrt",
diff --git a/lang/sh.json b/lang/sh.json
index 14c206ff5..cd3b0e50f 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -447,6 +447,7 @@
     "yearly": "Yearly",
     "daily": "Daily",
     "weekly": "Weekly",
+    "quarterly": "Quarterly",
     "half-annually": "Half-annually",
     "annually": "Annually",
     "Suspended": "Suspended",
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 53490a292..a9c57994e 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -145,6 +145,9 @@ class="fas fa-info-circle"></i>
                                                 @case('hourly')
                                                     {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
                                                     @break
+                                                @case('quarterly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(3)->toDayDateTimeString(); }}
+                                                    @break
                                                 @case('half-annually')
                                                     {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
                                                     @break
@@ -172,6 +175,8 @@ class="fas fa-info-circle"></i>
                                             {{ __('per Month') }}
                                         @elseif($server->product->billing_period == 'half-annually')
                                             {{ __('per 6 Months') }}
+                                        @elseif($server->product->billing_period == 'quarterly')
+                                            {{ __('per 3 Months') }}
                                         @elseif($server->product->billing_period == 'annually')
                                             {{ __('per Year') }}
                                         @elseif($server->product->billing_period == 'weekly')
diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index ed490c2e0..45216c256 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -183,6 +183,9 @@ class="fas fa-info-circle"></i></label>
                                                      <option value="monthly">
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="quarterly">
+                                                        {{__('Quarterly')}}
+                                                    </option>
                                                     <option value="half-annually">
                                                         {{__('Half Annually')}}
                                                     </option>
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 9d3aec529..851142af3 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -190,6 +190,10 @@ class="fas fa-info-circle"></i></label>
                                                      @endif>
                                                         {{__('Monthly')}}
                                                     </option>
+                                                    <option value="quarterly" @if ($product->billing_period  == 'quarterly') selected
+                                                    @endif>
+                                                        {{__('Quarterly')}}
+                                                    </option>
                                                     <option value="half-annually" @if ($product->billing_period  == 'half-annually') selected
                                                     @endif>
                                                         {{__('Half Annually')}}

From 87ec49008d377812c70ef1036298a99f985fea42 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Wed, 27 Jul 2022 23:26:03 +0200
Subject: [PATCH 084/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20Fixed=20?=
 =?UTF-8?q?credits=20check=20at=20server=20creation=20&=20formatted=20pric?=
 =?UTF-8?q?es=20nicely?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php        |  2 +-
 app/Http/Controllers/ServerController.php     |  3 ++-
 resources/views/servers/index.blade.php       |  2 +-
 themes/default/views/servers/create.blade.php | 25 +++++++++++++------
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 72b5bab4d..014af9636 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -91,7 +91,7 @@ public function handle()
                 }
 
                 // check if the server is canceled or if user has enough credits to charge the server or
-                if ( $server->cancelled || $user->credits < $product->price) {
+                if ( $server->cancelled || $user->credits <= $product->price) {
                     try {
                         // suspend server
                         $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 41644158f..f793ac3bf 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -131,7 +131,8 @@ private function validateConfigurationRules()
                 Auth::user()->credits <
                 ($product->minimum_credits == -1
                     ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
-                    : $product->minimum_credits)
+                    : $product->minimum_credits) ||
+                Auth::user()->credits <= $product->price
             ) {
                 return redirect()->route('servers.index')->with('error', 'You do not have the required amount of '.CREDITS_DISPLAY_NAME.' to use this product!');
             }
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index a9c57994e..0e5d69505 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -188,7 +188,7 @@ class="fas fa-info-circle"></i>
                                         @endif
                                             </div>
                                         <span>
-                                            {{ $server->product->price }}
+                                            {{ number_format($server->product->price) }}
                                         </span>
                                     </div>
                                 </div>
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index b184d4626..2a0a3d841 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -239,14 +239,14 @@ class="custom-select">
                                         <input type="hidden" name="product" x-model="selectedProduct">
                                     </div>
                                     <div>
-                                        <button type="submit" x-model="selectedProduct" name="product"
-                                            :disabled="product.minimum_credits > user.credits || product.doesNotFit == true ||
-                                                submitClicked"
-                                            :class="product.minimum_credits > user.credits || product.doesNotFit == true ||
-                                                submitClicked ? 'disabled' : ''"
-                                            class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
-                                            x-text=" product.doesNotFit == true ? '{{ __('Server cant fit on this Node') }}' : (product.minimum_credits > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}')">
-                                        </button>
+										<button type="submit" x-model="selectedProduct" name="product"
+        									:disabled="product.minimum_credits > user.credits || product.price > user.credits || product.doesNotFit == true ||
+            									submitClicked"
+       										:class="product.minimum_credits > user.credits || product.price > user.credits || product.doesNotFit == true ||
+            									submitClicked ? 'disabled' : ''"
+        									class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
+        									x-text="product.doesNotFit == true ? '{{ __('Server cant fit on this Node') }}' : (product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}')">
+    									</button>
                                     </div>
                                 </div>
                             </div>
@@ -376,6 +376,7 @@ function serverApp() {
                         .catch(console.error)
 
                     this.fetchedProducts = true;
+
                     // TODO: Sortable by user chosen property (cpu, ram, disk...)
                     this.products = response.data.sort((p1, p2) => parseInt(p1.price, 10) > parseInt(p2.price, 10) &&
                         1 || -1)
@@ -385,11 +386,19 @@ function serverApp() {
                         product.cpu = product.cpu / 100;
                     })
 
+                    //format price to have no decimals if it is a whole number
+                    this.products.forEach(product => {
+                        if (product.price % 1 === 0) {
+                            product.price = Math.round(product.price);
+                        }
+                    })
+
 
                     this.loading = false;
                     this.updateSelectedObjects()
                 },
 
+
                 /**
                  * @description map selected id's to selected objects
                  * @note being used in the server info box

From 35734579ae23eb0399684e3a64eab5af21982a14 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 28 Jul 2022 23:20:39 +0200
Subject: [PATCH 085/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Server=20creation?=
 =?UTF-8?q?=20fail=20when=20server.price=20=3D=20user.credits?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index f793ac3bf..982e01f50 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -132,7 +132,7 @@ private function validateConfigurationRules()
                 ($product->minimum_credits == -1
                     ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
                     : $product->minimum_credits) ||
-                Auth::user()->credits <= $product->price
+                Auth::user()->credits < $product->price
             ) {
                 return redirect()->route('servers.index')->with('error', 'You do not have the required amount of '.CREDITS_DISPLAY_NAME.' to use this product!');
             }

From cf62cdef1ff6f9b34d20222c08ed27d3d3d41ba7 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Thu, 28 Jul 2022 23:33:04 +0200
Subject: [PATCH 086/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20See=20last=20comm?=
 =?UTF-8?q?it?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 982e01f50..7a6e93d37 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -128,10 +128,7 @@ private function validateConfigurationRules()
 
             // Min. Credits
             if (
-                Auth::user()->credits <
-                ($product->minimum_credits == -1
-                    ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
-                    : $product->minimum_credits) ||
+                Auth::user()->credits < $product->minimum_credits ||
                 Auth::user()->credits < $product->price
             ) {
                 return redirect()->route('servers.index')->with('error', 'You do not have the required amount of '.CREDITS_DISPLAY_NAME.' to use this product!');

From d56bc09ac5608b4e1eab9809c4b359bae9382043 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Mon, 15 Aug 2022 14:52:49 +0200
Subject: [PATCH 087/514] =?UTF-8?q?fix:=20=F0=9F=92=84=20Styling=20of=20se?=
 =?UTF-8?q?rver=20buttons?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 resources/views/servers/index.blade.php | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 0e5d69505..223bbab2c 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -200,18 +200,25 @@ class="fas fa-info-circle"></i>
                                 target="__blank"
                                 class="btn btn-info text-center float-left ml-2"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
-                                <i class="fas fa-tools mx-4"></i>
+                                <i class="fas fa-tools mx-2"></i>
                             </a>
+                            @if(config("SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN"))
+                            <a href="{{ route('servers.show', ['server' => $server->id])}}"
+                            	class="btn btn-info text-center mr-3"
+                            	data-toggle="tooltip" data-placement="bottom" title="{{ __('Server Settings') }}">
+                                <i class="fas fa-cog mx-2"></i>
+                            </a>
+                            @endif
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
                                 {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
-                                <i class="fas fa-ban mx-4"></i>
+                                <i class="fas fa-ban mx-2"></i>
                             </button>
                             <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
                                 class="btn btn-danger  text-center float-right mr-2"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
-                                <i class="fas fa-trash mx-4"></i>
+                                <i class="fas fa-trash mx-2"></i>
                             </button>
                         </div>
                     </div>

From 973e77569af1aa7443ca3b961d6bb43aedaafb5c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.cloud>
Date: Mon, 15 Aug 2022 14:56:34 +0200
Subject: [PATCH 088/514] chore: Docs

---
 Addon-notes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index baf40c6aa..1d3887428 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,3 +1,3 @@
 Export diff files:
 
-git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf file.tgz -T -
+git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -

From 56aad2a7cb30b0953e1b8110cea8b25d07604bbf Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Tue, 22 Nov 2022 12:23:33 +0100
Subject: [PATCH 089/514] fix: Number formatting on server overview (price)

---
 Addon-notes.md                          | 3 ++-
 resources/views/servers/index.blade.php | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index 1d3887428..bed6f5a2e 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,3 +1,4 @@
 Export diff files:
+Commit Hash of lates Main commit
 
-git diff -r --no-commit-id --name-only --diff-filter=ACMR <commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -
+git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
index 223bbab2c..7910a30af 100644
--- a/resources/views/servers/index.blade.php
+++ b/resources/views/servers/index.blade.php
@@ -188,7 +188,7 @@ class="fas fa-info-circle"></i>
                                         @endif
                                             </div>
                                         <span>
-                                            {{ number_format($server->product->price) }}
+                                            {{ $server->product->price == round($server->product->price) ? round($server->product->price) : $server->product->price }}
                                         </span>
                                     </div>
                                 </div>

From 94cbea528c1c68bfcbcaf2b1f41125ebbc50f919 Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Tue, 22 Nov 2022 13:42:46 +0100
Subject: [PATCH 090/514] Fixed Upgrade/Downgrade Credit withdrawal

---
 app/Http/Controllers/ServerController.php     | 79 ++++++++++++-------
 .../default/views/servers/settings.blade.php  | 10 +--
 2 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 7a6e93d37..61ac4218a 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -9,6 +9,8 @@
 use App\Models\Node;
 use App\Models\Product;
 use App\Models\Server;
+use App\Models\User;
+use App\Models\Settings;
 use App\Notifications\ServerCreationError;
 use Carbon\Carbon;
 use Exception;
@@ -231,8 +233,6 @@ private function noAllocationsError(Server $server)
      */
     private function serverCreationFailed(Response $response, Server $server)
     {
-        $server->delete();
-
         return redirect()->route('servers.index')->with('error', json_encode($response->json()));
     }
 
@@ -265,9 +265,9 @@ public function cancel (Server $server)
     /** Show Server Settings */
     public function show(Server $server)
     {
-        if ($server->user_id != Auth::user()->id) {
-            return back()->with('error', __('´This is not your Server!'));
-        }
+
+
+        if($server->user_id != Auth::user()->id){ return back()->with('error', __('This is not your Server!'));}
         $serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
         $serverRelationships = $serverAttributes['relationships'];
         $serverLocationAttributes = $serverRelationships['location']['attributes'];
@@ -308,10 +308,9 @@ public function show(Server $server)
 
     public function upgrade(Server $server, Request $request)
     {
-        if ($server->user_id != Auth::user()->id) {
-            return redirect()->route('servers.index');
-        }
-        if (! isset($request->product_upgrade)) {
+        if($server->user_id != Auth::user()->id || $server->suspended) return redirect()->route('servers.index');
+        if(!isset($request->product_upgrade))
+        {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('this product is the only one'));
         }
         $user = Auth::user();
@@ -333,27 +332,53 @@ public function upgrade(Server $server, Request $request)
             return redirect()->route('servers.index')->with('error', __("The node '".$nodeName."' doesn't have the required memory or disk left to upgrade the server."));
         }
 
-        $priceupgrade = $newProduct->getHourlyPrice();
-
-        if ($priceupgrade < $oldProduct->getHourlyPrice()) {
-            $priceupgrade = 0;
-        }
-        if ($user->credits >= $priceupgrade && $user->credits >= $newProduct->minimum_credits) {
-            $server->product_id = $request->product_upgrade;
-            $server->update();
+        // calculate the amount of credits that the user overpayed for the old product when canceling the server right now
+        // billing periods are hourly, daily, weekly, monthly, quarterly, half-annually, annually
+        $billingPeriod = $oldProduct->billing_period;
+        // seconds
+        $billingPeriods = [
+            'hourly' => 3600,
+            'daily' => 86400,
+            'weekly' => 604800,
+            'monthly' => 2592000,
+            'quarterly' => 7776000,
+            'half-annually' => 15552000,
+            'annually' => 31104000
+        ];
+        // Get the amount of hours the user has been using the server
+        $billingPeriodMultiplier = $billingPeriods[$billingPeriod];
+        $timeDifference = now()->diffInSeconds($server->last_billed);
+
+        // Calculate the price for the time the user has been using the server
+        $overpayedCredits = $oldProduct->price - $oldProduct->price * ($timeDifference / $billingPeriodMultiplier);
+
+
+        if ($user->credits >= $newProduct->price && $user->credits >= $newProduct->minimum_credits)
+        {
             $server->allocation = $serverAttributes['allocation'];
+            // Update the server on the panel
             $response = Pterodactyl::updateServer($server, $newProduct);
-            if ($response->failed()) {
-                return $this->serverCreationFailed($response, $server);
-            }
-            //update user balance
-            $user->decrement('credits', $priceupgrade);
-            //restart the server
-            $response = Pterodactyl::powerAction($server, 'restart');
-            if ($response->failed()) {
-                return redirect()->route('servers.index')->with('error', $response->json()['errors'][0]['detail']);
-            }
+            if ($response->failed()) return $this->serverCreationFailed($response, $server);
+
+            // Remove the allocation property from the server object as it is not a column in the database
+            unset($server->allocation);
+            // Update the server on controlpanel
+            $server->update([
+                'product_id' => $newProduct->id,
+                'updated_at' => now(),
+                'last_billed' => now(),
+                'cancelled' => null,
+            ]);
 
+            // Refund the user the overpayed credits
+            if ($overpayedCredits > 0) $user->increment('credits', $overpayedCredits);
+
+            // Withdraw the credits for the new product
+            $user->decrement('credits', $newProduct->price); 
+
+            //restart the server
+            $response = Pterodactyl::powerAction($server, "restart");
+            if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   '.$response->json()['errors'][0]['detail']);
             return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
         } else {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('Not Enough Balance for Upgrade'));
diff --git a/themes/default/views/servers/settings.blade.php b/themes/default/views/servers/settings.blade.php
index 9fead6814..c03eeade7 100644
--- a/themes/default/views/servers/settings.blade.php
+++ b/themes/default/views/servers/settings.blade.php
@@ -243,10 +243,7 @@ class="btn btn-info btn-md">
                                         </button>
                                     </div>
                                     <div class="modal-body card-body">
-                                        <strong>{{__("FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN")}}</strong>
-                                        <br>
-                                        <br>
-                                        <strong>{{__("YOUR PRODUCT")}} : </strong> {{ $server->product->name }}
+                                        <strong>{{__("Current Product")}}: </strong> {{ $server->product->name }}
                                         <br>
                                         <br>
 
@@ -256,12 +253,13 @@ class="btn btn-info btn-md">
                                             <option value="">{{__("Select the product")}}</option>
                                               @foreach($products as $product)
                                                   @if(in_array($server->egg, $product->eggs) && $product->id != $server->product->id && $product->disabled == false)
-                                                    <option value="{{ $product->id }}" @if($product->doesNotFit)disabled @endif>{{ $product->name }} [ {{ CREDITS_DISPLAY_NAME }} {{ $product->price }} @if($product->doesNotFit)] {{__('Server can´t fit on this node')}} @else @if($product->minimum_credits!=-1) /
+                                                    <option value="{{ $product->id }}" @if($product->doesNotFit)disabled @endif>{{ $product->name }} [ {{ CREDITS_DISPLAY_NAME }} {{ $product->price }} @if($product->doesNotFit)] {{__('Server can\'t fit on this node')}} @else @if($product->minimum_credits!=-1) /
                                                         {{__("Required")}}: {{$product->minimum_credits}} {{ CREDITS_DISPLAY_NAME }}@endif ] @endif</option>
                                                   @endif
                                               @endforeach
                                           </select>
-                                          <br> {{__("Once the Upgrade button is pressed, we will automatically deduct the amount for the first hour according to the new product from your credits")}}. <br>
+                                          
+                                          <br> <strong>{{__("Caution") }}:</strong> {{__("Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed")}}. <br>
                                           <br> {{__("Server will be automatically restarted once upgraded")}}
                                     </div>
                                     <div class="modal-footer card-body">

From ae787dfc4c68ffd0f1b8606dcfb479622d9c876a Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Tue, 22 Nov 2022 13:43:06 +0100
Subject: [PATCH 091/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20localization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lang/bg.json |  18 +++--
 lang/bs.json |  16 ++--
 lang/cs.json |  28 ++++---
 lang/de.json |  15 ++--
 lang/en.json | 222 ++++++++++++++-------------------------------------
 lang/es.json |  26 +++---
 lang/fr.json |  16 ++--
 lang/he.json |  46 ++++++-----
 lang/hi.json |  16 ++--
 lang/hu.json |  16 ++--
 lang/it.json |  16 ++--
 lang/nl.json |  16 ++--
 lang/pl.json |  16 ++--
 lang/pt.json |  16 ++--
 lang/ro.json |  16 ++--
 lang/ru.json |  18 +++--
 lang/sh.json |  45 +++--------
 lang/sk.json |  16 ++--
 lang/sr.json |  16 ++--
 lang/sv.json |  16 ++--
 lang/tr.json |  16 ++--
 lang/zh.json |  16 ++--
 22 files changed, 279 insertions(+), 363 deletions(-)

diff --git a/lang/bg.json b/lang/bg.json
index dbd6881a4..bc1ab41ac 100644
--- a/lang/bg.json
+++ b/lang/bg.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Грешка при създаване на сървър",
     "Your servers have been suspended!": "Сървърите ви са спрени!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "За да активирате автоматично вашия сървър\/и, трябва да закупите повече кредити.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "За да активирате автоматично вашия сървър/и, трябва да закупите повече кредити.",
     "Purchase credits": "Купете кредити",
     "If you have any questions please let us know.": "При допълнителни въпроси, моля свържете се с нас.",
     "Regards": "Поздрави",
@@ -93,7 +93,7 @@
     "Getting started!": "Приготвяме се да започнем!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Език по подразбиране",
     "The fallback Language, if something goes wrong": "Резервният език, ако нещо се обърка",
     "Datable language": "Език с данни",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Езиков код на таблиците с данни. <br><strong>Пример:<\/strong> en-gb, fr_fr, de_de<br>Повече информация: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Езиков код на таблиците с данни. <br><strong>Пример:</strong> en-gb, fr_fr, de_de<br>Повече информация: ",
     "Auto-translate": "Автоматичен превод",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Ако това е отметнато, таблото за управление ще се преведе на езика на клиентите, ако е наличен",
     "Client Language-Switch": "Превключване на клиентски език",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Таксува кредити за първия час при създаване на сървър.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Въведете URL адреса на вашата инсталация на PHPMyAdmin. <strong>Без крайна наклонена черта!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Въведете URL адреса на вашата инсталация на PHPMyAdmin. <strong>Без крайна наклонена черта!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Въведете URL адреса на вашата инсталация на Pterodactyl.<strong>Без крайна наклонена черта!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Въведете URL адреса на вашата инсталация на Pterodactyl.<strong>Без крайна наклонена черта!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Kлюч",
     "Enter the API Key to your Pterodactyl installation.": "Въведете API ключа към вашата инсталация на Pterodactyl.",
     "Force Discord verification": "Принудително потвърждаване на Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Ваучер може да се използва само веднъж на потребител. Uses определя броя на различните потребители, които могат да използват този ваучер.",
     "Max": "Макс",
     "Expires at": "Изтича на",
-    "Used \/ Uses": "Използван \/ Използвания",
+    "Used / Uses": "Използван / Използвания",
     "Expires": "Изтича",
     "Sign in to start your session": "Влезте, за да започнете сесията си",
     "Password": "Парола",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Няма свързани Node-ове!",
     "No nests available!": "Няма налични Nest-ове!",
     "No eggs have been linked!": "Няма свързани Egg-ове!",
-    "Software \/ Games": "Софтуер \/ Игри",
+    "Software / Games": "Софтуер / Игри",
     "Please select software ...": "Моля, изберете софтуер...",
     "---": "---",
     "Specification ": "Спецификация ",
@@ -460,5 +460,7 @@
     "tr": "Турски",
     "ru": "Руски",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
+    "Caution": "Внимание"
 }
diff --git a/lang/bs.json b/lang/bs.json
index 8a84b67a3..cb014f873 100644
--- a/lang/bs.json
+++ b/lang/bs.json
@@ -80,7 +80,7 @@
     "User ID": "User ID",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -173,7 +173,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -214,9 +214,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -284,7 +284,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -354,7 +354,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -441,5 +441,7 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Russian"
+    "ru": "Russian",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution"
 }
diff --git a/lang/cs.json b/lang/cs.json
index 7f7235420..04dc0090e 100644
--- a/lang/cs.json
+++ b/lang/cs.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Někdo se zaregistroval pomocí vašeho kódu!",
     "Server Creation Error": "Chyba při vytváření serveru",
     "Your servers have been suspended!": "Vaše servery byly pozastaveny!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Pro opětovné spuštění vašich serverů dobijte prosím kredity.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Pro opětovné spuštění vašich serverů dobijte prosím kredity.",
     "Purchase credits": "Zakoupit kredity",
     "If you have any questions please let us know.": "Máte-li jakékoli dotazy, dejte nám vědět.",
     "Regards": "S pozdravem",
@@ -93,7 +93,7 @@
     "Getting started!": "Začínáme!",
     "Welcome to our dashboard": "Vítejte v našem ovládacím panelu",
     "Verification": "Ověření",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Můžete ověřit svojí e-mail adresu a přiojit váš Discord účet.",
+    "You can verify your e-mail address and link/verify your Discord account.": "Můžete ověřit svojí e-mail adresu a přiojit váš Discord účet.",
     "Information": "Informace",
     "This dashboard can be used to create and delete servers": "Tento panel může použít pro vytvoření a mazání serverů",
     "These servers can be used and managed on our pterodactyl panel": "Tyto servery můžete používat a spravovat v našem pterodactyl panelu",
@@ -114,7 +114,7 @@
     "Token": "Token",
     "Last used": "Naposledy použito",
     "Are you sure you wish to delete?": "Opravdu si přejete odstranit?",
-    "Nests": "Software\/hra",
+    "Nests": "Software/hra",
     "Sync": "Synchronizovat",
     "Active": "Aktivní",
     "ID": "ID",
@@ -174,10 +174,10 @@
     "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "prosím vytvoř soubor který bude pojmenován install.lock v Kontrolním panelu (hlavní složka)\nPokud tak neuděláš, žádné změny nebudou načteny!",
     "or click here": "nebo klikněte sem",
     "Company Name": "Název společnosti",
-    "Company Address": "Adresa Firmy",
+    "Company Adress": "Adresa Firmy",
     "Company Phonenumber": "Telefon společnosti",
     "VAT ID": "DIČ",
-    "Company E-Mail Address": "E-mailová adresa společnosti",
+    "Company E-Mail Adress": "E-mailová adresa společnosti",
     "Company Website": "Web společnosti",
     "Invoice Prefix": "Prefix pro faktury",
     "Enable Invoices": "Povolit faktury",
@@ -187,7 +187,7 @@
     "Default language": "Výchozí jazyk",
     "The fallback Language, if something goes wrong": "Záložní jazyk, kdyby se něco pokazilo",
     "Datable language": "Jazyk tabulek",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Kód jazyka datových tabulek. <br><strong>Příklad:<\/strong> en-gb, fr_fr, de_de<br>Více informací: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Kód jazyka datových tabulek. <br><strong>Příklad:</strong> en-gb, fr_fr, de_de<br>Více informací: ",
     "Auto-translate": "Automatický překlad",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Pokud je tohle zaškrtlé, Panel bude přeložen do Jazyka klienta (pokud to je možné)",
     "Client Language-Switch": "Povolit uživatelům změnu jazyka",
@@ -199,7 +199,7 @@
     "Mail Username": "Uživatelské jméno pro e-mail",
     "Mail Password": "E-mailové heslo",
     "Mail Encryption": "Šifrování e-mailu",
-    "Mail From Address": "E-mail odesílatele",
+    "Mail From Adress": "E-mail odesílatele",
     "Mail From Name": "Název odešílatele",
     "Discord Client-ID": "Discord Client-ID",
     "Discord Client-Secret": "Discord Client-Secret",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Po vytvoření služby náčtuje ihned první hodinu.",
     "Credits Display Name": "Název kreditů",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Vložte URL vaší instalace PHPmyAdmin. <strong>Bez koncového lomítka!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Vložte URL vaší instalace PHPmyAdmin. <strong>Bez koncového lomítka!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Vložte URL vaší instalace Pterodactyl. <strong>Bez koncového lomítka!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Vložte URL vaší instalace Pterodactyl. <strong>Bez koncového lomítka!</strong>",
     "Pterodactyl API Key": "Pterodactyl API klíč",
     "Enter the API Key to your Pterodactyl installation.": "Zadejte API klíč Vaší Pterodactyl instalace.",
     "Force Discord verification": "Vynutit ověření skrz Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Poukaz může být použit pouze jednou na uživatele. Počet použití upravuje počet různých uživatelů, kteří můžou poukaz použít.",
     "Max": "Maximum",
     "Expires at": "Vyprší",
-    "Used \/ Uses": "Použito",
+    "Used / Uses": "Použito",
     "Expires": "Vyprší",
     "Sign in to start your session": "Pro pokračování se prosím přihlašte",
     "Password": "Heslo",
@@ -386,9 +386,9 @@
     "Sync now": "Synchronizovat nyní",
     "No products available!": "Žádné dostupné balíčky!",
     "No nodes have been linked!": "Nebyly propojeny žádné uzly!",
-    "No nests available!": "Žádný dostupný software\/hry!",
+    "No nests available!": "Žádný dostupný software/hry!",
     "No eggs have been linked!": "Nebyly nastaveny žádné distribuce!",
-    "Software \/ Games": "Software\/hry",
+    "Software / Games": "Software/hry",
     "Please select software ...": "Prosím zvolte software ...",
     "---": "----",
     "Specification ": "Specifikace ",
@@ -460,5 +460,7 @@
     "tr": "Turečtina",
     "ru": "Ruština",
     "sv": "Švédština",
-    "sk": "Slovensky"
+    "sk": "Slovensky",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
+    "Caution": "Upozornění"
 }
diff --git a/lang/de.json b/lang/de.json
index b01d61b70..1e8a8402d 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -174,10 +174,10 @@
     "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "Bitte erstellen Sie eine Datei mit dem Namen \"install.lock\" in Ihrem Dashboard-Root-Verzeichnis. Sonst werden keine Einstellungen geladen!",
     "or click here": "oder klicke hier",
     "Company Name": "Firmenname",
-    "Company Address": "Firmenadresse",
+    "Company Adress": "Firmenadresse",
     "Company Phonenumber": "Firmen Telefonnummer",
     "VAT ID": "Umsatzsteuer-ID",
-    "Company E-Mail Address": "Firmen E-Mail Adresse",
+    "Company E-Mail Adress": "Firmen E-Mail Adresse",
     "Company Website": "Firmenwebseite",
     "Invoice Prefix": "Rechnungspräfix",
     "Enable Invoices": "Rechnungen aktivieren",
@@ -199,7 +199,7 @@
     "Mail Username": "E-Mail Nutzername",
     "Mail Password": "E-Mail Passwort",
     "Mail Encryption": "E-Mail Verschlüsselungsart",
-    "Mail From Address": "Absender E-Mailadresse",
+    "Mail From Adress": "Absender E-Mailadresse",
     "Mail From Name": "Absender E-Mailname",
     "Discord Client-ID": "Discord Client-ID",
     "Discord Client-Secret": "DIscord Client-Secret",
@@ -459,6 +459,8 @@
     "zh": "Chinesisch",
     "tr": "Türkisch",
     "ru": "Russisch",
+    "sv": "Schwedisch",
+    "sk": "Slowakisch",
     "hourly": "Stündlich",
     "monthly": "Monatlich",
     "yearly": "Jährlich",
@@ -482,9 +484,6 @@
     "Yes, cancel it!": "Ja, löschen!",
     "No, abort!": "Abbrechen",
     "Billing period": "Abrechnungsperiode",
-    "sv": "Schwedisch",
-    "sk": "Slowakisch",
-    "Imprint": "Impressum",
-    "Privacy": "Datenschutz",
-    "Privacy Policy": "Datenschutzerklärung"
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Das Upgrade/Downgrade Ihres Servers wird Ihre Abrechnungsperiode auf \"jetzt\" zurücksetzen. Ihre überzahlten Credits werden erstattet. Der Preis für die neue Abrechnungsperiode wird abgebucht.",
+    "Caution": "Achtung"
 }
diff --git a/lang/en.json b/lang/en.json
index c0aa64314..07d646083 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -10,10 +10,6 @@
     "Everything is good!": "Everything is good!",
     "System settings have not been updated!": "System settings have not been updated!",
     "System settings updated!": "System settings updated!",
-    "Discount": "Discount",
-    "The product you chose can't be purchased with this payment method. The total amount is too small. Please buy a bigger amount or try a different payment method.": "The product you chose can't be purchased with this payment method. The total amount is too small. Please buy a bigger amount or try a different payment method.",
-    "Tax": "Tax",
-    "Your payment has been canceled!": "Your payment has been canceled!",
     "api key created!": "api key created!",
     "api key updated!": "api key updated!",
     "api key has been removed!": "api key has been removed!",
@@ -24,9 +20,11 @@
     "Invoice does not exist on filesystem!": "Invoice does not exist on filesystem!",
     "unknown": "unknown",
     "Pterodactyl synced": "Pterodactyl synced",
-    "An error ocured. Please try again.": "An error ocured. Please try again.",
     "Your credit balance has been increased!": "Your credit balance has been increased!",
-    "Unknown user": "Unknown user",
+    "Your payment is being processed!": "Your payment is being processed!",
+    "Your payment has been canceled!": "Your payment has been canceled!",
+    "Payment method": "Payment method",
+    "Invoice": "Invoice",
     "Download": "Download",
     "Product has been created!": "Product has been created!",
     "Product has been updated!": "Product has been updated!",
@@ -36,10 +34,6 @@
     "Server removed": "Server removed",
     "An exception has occurred while trying to remove a resource \"": "An exception has occurred while trying to remove a resource \"",
     "Server has been updated!": "Server has been updated!",
-    "renamed": "renamed",
-    "servers": "servers",
-    "deleted": "deleted",
-    "old servers": "old servers",
     "Unsuspend": "Unsuspend",
     "Suspend": "Suspend",
     "Store item has been created!": "Store item has been created!",
@@ -75,15 +69,10 @@
     "Close": "Close",
     "Target User already in blacklist. Reason updated": "Target User already in blacklist. Reason updated",
     "Change Status": "Change Status",
-    "partner has been created!": "partner has been created!",
-    "partner has been updated!": "partner has been updated!",
-    "partner has been removed!": "partner has been removed!",
-    "Default": "Default",
-    "Account permanently deleted!": "Account permanently deleted!",
     "Profile updated": "Profile updated",
     "Server limit reached!": "Server limit reached!",
+    "The node '\" . $nodeName . \"' doesn't have the required memory or disk left to allocate this product.": "The node '\" . $nodeName . \"' doesn't have the required memory or disk left to allocate this product.",
     "You are required to verify your email address before you can create a server.": "You are required to verify your email address before you can create a server.",
-    "The system administrator has blocked the creation of new servers.": "The system administrator has blocked the creation of new servers.",
     "You are required to link your discord account before you can create a server.": "You are required to link your discord account before you can create a server.",
     "Server created": "Server created",
     "No allocations satisfying the requirements for automatic deployment on this node were found.": "No allocations satisfying the requirements for automatic deployment on this node were found.",
@@ -93,7 +82,9 @@
     "Not Enough Balance for Upgrade": "Not Enough Balance for Upgrade",
     "You are required to verify your email address before you can purchase credits.": "You are required to verify your email address before you can purchase credits.",
     "You are required to link your discord account before you can purchase Credits": "You are required to link your discord account before you can purchase Credits",
+    "You can't make a ticket because you're on the blacklist for a reason: '\" . $check->reason . \"": "You can't make a ticket because you're on the blacklist for a reason: '\" . $check->reason . \"",
     "A ticket has been opened, ID: #": "A ticket has been opened, ID: #",
+    "You can't reply a ticket because you're on the blacklist for a reason: '\" . $check->reason . \"": "You can't reply a ticket because you're on the blacklist for a reason: '\" . $check->reason . \"",
     "EXPIRED": "EXPIRED",
     "Payment Confirmation": "Payment Confirmation",
     "Payment Confirmed!": "Payment Confirmed!",
@@ -109,7 +100,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -121,14 +112,12 @@
     "Getting started!": "Getting started!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
     "If you have any questions, please join our Discord server and #create-a-ticket": "If you have any questions, please join our Discord server and #create-a-ticket",
     "We hope you can enjoy this hosting experience and if you have any suggestions please let us know": "We hope you can enjoy this hosting experience and if you have any suggestions please let us know",
-    "Payment method": "Payment method",
-    "Invoice": "Invoice",
     "Activity Logs": "Activity Logs",
     "Dashboard": "Dashboard",
     "No recent activity from cronjobs": "No recent activity from cronjobs",
@@ -153,10 +142,6 @@
     "Nodes": "Nodes",
     "Location": "Location",
     "Admin Overview": "Admin Overview",
-    "Version Outdated:": "Version Outdated:",
-    "You are running on": "You are running on",
-    "The latest Version is": "The latest Version is",
-    "Consider updating now": "Consider updating now",
     "Support server": "Support server",
     "Documentation": "Documentation",
     "Github": "Github",
@@ -165,59 +150,11 @@
     "Total": "Total",
     "Payments": "Payments",
     "Pterodactyl": "Pterodactyl",
-    "Warning!": "Warning!",
-    "Some nodes got deleted on pterodactyl only. Please click the sync button above.": "Some nodes got deleted on pterodactyl only. Please click the sync button above.",
     "Resources": "Resources",
     "Count": "Count",
     "Locations": "Locations",
     "Eggs": "Eggs",
     "Last updated :date": "Last updated :date",
-    "Latest tickets": "Latest tickets",
-    "There are no tickets": "There are no tickets",
-    "Title": "Title",
-    "User": "User",
-    "Last updated": "Last updated",
-    "Controlpanel.gg": "Controlpanel.gg",
-    "Version": "Version",
-    "Individual nodes": "Individual nodes",
-    "You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.": "You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.",
-    "You can do that in settings.": "You can do that in settings.",
-    "Note": "Note",
-    "If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel. Try clicking the button below.": "If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel. Try clicking the button below.",
-    "Sync servers": "Sync servers",
-    "Node": "Node",
-    "Server count": "Server count",
-    "Resource usage": "Resource usage",
-    "Usage": "Usage",
-    "active": "active",
-    "total": "total",
-    "Latest payments": "Latest payments",
-    "Last month": "Last month",
-    "Payments in this time window": "Payments in this time window",
-    "Currency": "Currency",
-    "Number of payments": "Number of payments",
-    "Total amount": "Total amount",
-    "This month": "This month",
-    "Tax overview": "Tax overview",
-    "Last year": "Last year",
-    "Base amount": "Base amount",
-    "Total taxes": "Total taxes",
-    "This year": "This year",
-    "Vouchers": "Vouchers",
-    "Partner details": "Partner details",
-    "Partner discount": "Partner discount",
-    "The discount in percent given to the partner when purchasing credits.": "The discount in percent given to the partner when purchasing credits.",
-    "Discount in percent": "Discount in percent",
-    "Registered user discount": "Registered user discount",
-    "The discount in percent given to all users registered using the partners referral link when purchasing credits.": "The discount in percent given to all users registered using the partners referral link when purchasing credits.",
-    "Referral system commission": "Referral system commission",
-    "Override value for referral system commission. You can set it to -1 to get the default commission from settings.": "Override value for referral system commission. You can set it to -1 to get the default commission from settings.",
-    "Commission in percent": "Commission in percent",
-    "Partners": "Partners",
-    "The discount in percent given to the partner at checkout.": "The discount in percent given to the partner at checkout.",
-    "The discount in percent given to all users registered using the partners referral link.": "The discount in percent given to all users registered using the partners referral link.",
-    "Created": "Created",
-    "Actions": "Actions",
     "Download all Invoices": "Download all Invoices",
     "Product Price": "Product Price",
     "Tax Value": "Tax Value",
@@ -245,9 +182,6 @@
     "Link your products to nodes and eggs to create dynamic pricing for each option": "Link your products to nodes and eggs to create dynamic pricing for each option",
     "This product will only be available for these nodes": "This product will only be available for these nodes",
     "This product will only be available for these eggs": "This product will only be available for these eggs",
-    "No Eggs or Nodes shown?": "No Eggs or Nodes shown?",
-    "Sync now": "Sync now",
-    "Min Credits": "Min Credits",
     "Product": "Product",
     "CPU": "CPU",
     "Updated at": "Updated at",
@@ -256,9 +190,7 @@
     "You usually do not need to change anything here": "You usually do not need to change anything here",
     "Edit Server": "Edit Server",
     "Server identifier": "Server identifier",
-    "Change the server identifier on controlpanel to match a pterodactyl server.": "Change the server identifier on controlpanel to match a pterodactyl server.",
-    "Server owner": "Server owner",
-    "Change the current server owner on controlpanel and pterodactyl.": "Change the current server owner on controlpanel and pterodactyl.",
+    "User": "User",
     "Server id": "Server id",
     "Config": "Config",
     "Suspended at": "Suspended at",
@@ -267,10 +199,10 @@
     "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!",
     "or click here": "or click here",
     "Company Name": "Company Name",
-    "Company Address": "Company Address",
+    "Company Adress": "Company Adress",
     "Company Phonenumber": "Company Phonenumber",
     "VAT ID": "VAT ID",
-    "Company E-Mail Address": "Company E-Mail Address",
+    "Company E-Mail Adress": "Company E-Mail Adress",
     "Company Website": "Company Website",
     "Invoice Prefix": "Invoice Prefix",
     "Enable Invoices": "Enable Invoices",
@@ -280,7 +212,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -292,7 +224,7 @@
     "Mail Username": "Mail Username",
     "Mail Password": "Mail Password",
     "Mail Encryption": "Mail Encryption",
-    "Mail From Address": "Mail From Address",
+    "Mail From Adress": "Mail From Adress",
     "Mail From Name": "Mail From Name",
     "Discord Client-ID": "Discord Client-ID",
     "Discord Client-Secret": "Discord Client-Secret",
@@ -303,11 +235,7 @@
     "Enable ReCaptcha": "Enable ReCaptcha",
     "ReCaptcha Site-Key": "ReCaptcha Site-Key",
     "ReCaptcha Secret-Key": "ReCaptcha Secret-Key",
-    "Your Recaptcha": "Your Recaptcha",
-    "Referral System": "Referral System",
     "Enable Referral": "Enable Referral",
-    "Always give commission": "Always give commission",
-    "Should users recieve the commission only for the first payment, or for every payment?": "Should users recieve the commission only for the first payment, or for every payment?",
     "Mode": "Mode",
     "Should a reward be given if a new User registers or if a new user buys credits": "Should a reward be given if a new User registers or if a new user buys credits",
     "Commission": "Commission",
@@ -323,10 +251,6 @@
     "Everyone": "Everyone",
     "Clients": "Clients",
     "Enable Ticketsystem": "Enable Ticketsystem",
-    "Notify on Ticket creation": "Notify on Ticket creation",
-    "Who will receive an E-Mail when a new Ticket is created": "Who will receive an E-Mail when a new Ticket is created",
-    "Admins": "Admins",
-    "Moderators": "Moderators",
     "PayPal Client-ID": "PayPal Client-ID",
     "PayPal Secret-Key": "PayPal Secret-Key",
     "PayPal Sandbox Client-ID": "PayPal Sandbox Client-ID",
@@ -339,20 +263,15 @@
     "Payment Methods": "Payment Methods",
     "Tax Value in %": "Tax Value in %",
     "System": "System",
-    "Show Terms of Service": "Show Terms of Service",
-    "Show Imprint": "Show Imprint",
-    "Show Privacy Policy": "Show Privacy Policy",
     "Register IP Check": "Register IP Check",
     "Prevent users from making multiple accounts using the same IP address.": "Prevent users from making multiple accounts using the same IP address.",
     "Charge first hour at creation": "Charge first hour at creation",
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
-    "Pterodactyl API perPage limit": "Pterodactyl API perPage limit",
-    "The Pterodactyl API perPage limit. It is necessary to set it higher than your server count.": "The Pterodactyl API perPage limit. It is necessary to set it higher than your server count.",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Pterodactyl Admin-Account API Key": "Pterodactyl Admin-Account API Key",
@@ -360,8 +279,6 @@
     "Test API": "Test API",
     "Force Discord verification": "Force Discord verification",
     "Force E-Mail verification": "Force E-Mail verification",
-    "Creation of new users": "Creation of new users",
-    "If unchecked, it will disable the registration of new users in the system, and this will also apply to the API.": "If unchecked, it will disable the registration of new users in the system, and this will also apply to the API.",
     "Initial Credits": "Initial Credits",
     "Initial Server Limit": "Initial Server Limit",
     "Credits Reward Amount - Discord": "Credits Reward Amount - Discord",
@@ -370,38 +287,13 @@
     "Server Limit Increase - E-Mail": "Server Limit Increase - E-Mail",
     "Server Limit after Credits Purchase": "Server Limit after Credits Purchase",
     "Server": "Server",
-    "Enable upgrade\/downgrade of servers": "Enable upgrade\/downgrade of servers",
-    "Allow upgrade\/downgrade to a new product for the given server": "Allow upgrade\/downgrade to a new product for the given server",
-    "Creation of new servers": "Creation of new servers",
-    "If unchecked, it will disable the creation of new servers for regular users and system moderators, this has no effect for administrators.": "If unchecked, it will disable the creation of new servers for regular users and system moderators, this has no effect for administrators.",
     "Server Allocation Limit": "Server Allocation Limit",
     "The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!": "The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!",
-    "Minimum credits": "Minimum credits",
-    "The minimum amount of credits user has to have to create a server. Can be overridden by package limits.": "The minimum amount of credits user has to have to create a server. Can be overridden by package limits.",
-    "SEO": "SEO",
-    "SEO Title": "SEO Title",
-    "An SEO title tag must contain your target keyword. This tells both Google and searchers that your web page is relevant to this search query!": "An SEO title tag must contain your target keyword. This tells both Google and searchers that your web page is relevant to this search query!",
-    "SEO Description": "SEO Description",
-    "The SEO site description represents your homepage. Search engines show this description in search results for your homepage if they dont find content more relevant to a visitors search terms.": "The SEO site description represents your homepage. Search engines show this description in search results for your homepage if they dont find content more relevant to a visitors search terms.",
     "Design": "Design",
-    "Theme": "Theme",
     "Enable Logo on Loginpage": "Enable Logo on Loginpage",
     "Select panel icon": "Select panel icon",
     "Select Login-page Logo": "Select Login-page Logo",
     "Select panel favicon": "Select panel favicon",
-    "Enable the Alert Message on Homepage": "Enable the Alert Message on Homepage",
-    "Alert Color": "Alert Color",
-    "Blue": "Blue",
-    "Grey": "Grey",
-    "Green": "Green",
-    "Red": "Red",
-    "Orange": "Orange",
-    "Cyan": "Cyan",
-    "Alert Message (HTML might be used)": "Alert Message (HTML might be used)",
-    "Message of the day": "Message of the day",
-    "Enable the MOTD on the Homepage": "Enable the MOTD on the Homepage",
-    "Enable the Useful-Links section": "Enable the Useful-Links section",
-    "MOTD-Text": "MOTD-Text",
     "Store": "Store",
     "Server Slots": "Server Slots",
     "Currency code": "Currency code",
@@ -417,6 +309,7 @@
     "Useful Links": "Useful Links",
     "Icon class name": "Icon class name",
     "You can find available free icons": "You can find available free icons",
+    "Title": "Title",
     "Link": "Link",
     "description": "description",
     "Icon": "Icon",
@@ -446,9 +339,11 @@
     "Content": "Content",
     "Server limit": "Server limit",
     "Discord": "Discord",
+    "Usage": "Usage",
     "IP": "IP",
     "Referals": "Referals",
     "referral-code": "referral-code",
+    "Vouchers": "Vouchers",
     "Voucher details": "Voucher details",
     "Summer break voucher": "Summer break voucher",
     "Code": "Code",
@@ -457,18 +352,14 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
-    "Email or Username": "Email or Username",
     "Password": "Password",
     "Remember Me": "Remember Me",
     "Sign In": "Sign In",
     "Forgot Your Password?": "Forgot Your Password?",
     "Register a new membership": "Register a new membership",
-    "Imprint": "Imprint",
-    "Privacy": "Privacy",
-    "Terms of Service": "Terms of Service",
     "Please confirm your password before continuing.": "Please confirm your password before continuing.",
     "You forgot your password? Here you can easily retrieve a new password.": "You forgot your password? Here you can easily retrieve a new password.",
     "Request new password": "Request new password",
@@ -476,10 +367,7 @@
     "You are only one step a way from your new password, recover your password now.": "You are only one step a way from your new password, recover your password now.",
     "Retype password": "Retype password",
     "Change password": "Change password",
-    "The system administrator has blocked the registration of new users": "The system administrator has blocked the registration of new users",
-    "Back": "Back",
     "Referral code": "Referral code",
-    "I agree to the": "I agree to the",
     "Register": "Register",
     "I already have a membership": "I already have a membership",
     "Verify Your Email Address": "Verify Your Email Address",
@@ -489,17 +377,6 @@
     "click here to request another": "click here to request another",
     "per month": "per month",
     "Out of Credits in": "Out of Credits in",
-    "Partner program": "Partner program",
-    "Your referral URL": "Your referral URL",
-    "Click to copy": "Click to copy",
-    "Number of referred users:": "Number of referred users:",
-    "Your discount": "Your discount",
-    "Discount for your new users": "Discount for your new users",
-    "Reward per registered user": "Reward per registered user",
-    "New user payment commision": "New user payment commision",
-    "Make a purchase to reveal your referral-URL": "Make a purchase to reveal your referral-URL",
-    "URL copied to clipboard": "URL copied to clipboard",
-    "Privacy Policy": "Privacy Policy",
     "Home": "Home",
     "Language": "Language",
     "See all Notifications": "See all Notifications",
@@ -517,6 +394,7 @@
     "Management": "Management",
     "Other": "Other",
     "Logs": "Logs",
+    "Warning!": "Warning!",
     "You have not yet verified your email address": "You have not yet verified your email address",
     "Click here to resend verification email": "Click here to resend verification email",
     "Please contact support If you didnt receive your verification email.": "Please contact support If you didnt receive your verification email.",
@@ -528,12 +406,12 @@
     "Blacklist List": "Blacklist List",
     "Reason": "Reason",
     "Created At": "Created At",
+    "Actions": "Actions",
     "Add To Blacklist": "Add To Blacklist",
     "please make the best of it": "please make the best of it",
-    "Please note, the blacklist will make the user unable to make a ticket\/reply again": "Please note, the blacklist will make the user unable to make a ticket\/reply again",
+    "Please note, the blacklist will make the user unable to make a ticket/reply again": "Please note, the blacklist will make the user unable to make a ticket/reply again",
     "Ticket": "Ticket",
     "Category": "Category",
-    "Priority": "Priority",
     "Last Updated": "Last Updated",
     "Comment": "Comment",
     "All notifications": "All notifications",
@@ -544,7 +422,6 @@
     "Please contact support If you face any issues.": "Please contact support If you face any issues.",
     "Due to system settings you are required to verify your discord account!": "Due to system settings you are required to verify your discord account!",
     "It looks like this hasnt been set-up correctly! Please contact support.": "It looks like this hasnt been set-up correctly! Please contact support.",
-    "Permanently delete my account": "Permanently delete my account",
     "Change Password": "Change Password",
     "Current Password": "Current Password",
     "Link your discord account!": "Link your discord account!",
@@ -553,30 +430,25 @@
     "You are verified!": "You are verified!",
     "Re-Sync Discord": "Re-Sync Discord",
     "Save Changes": "Save Changes",
-    "Are you sure you want to permanently delete your account and all of your servers?": "Are you sure you want to permanently delete your account and all of your servers?",
-    "Delete my account": "Delete my account",
-    "Account has been destroyed": "Account has been destroyed",
-    "Account was NOT deleted.": "Account was NOT deleted.",
+    "URL copied to clipboard": "URL copied to clipboard",
     "Server configuration": "Server configuration",
-    "here": "here",
     "Make sure to link your products to nodes and eggs.": "Make sure to link your products to nodes and eggs.",
     "There has to be at least 1 valid product for server creation": "There has to be at least 1 valid product for server creation",
+    "Sync now": "Sync now",
     "No products available!": "No products available!",
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
+    "Node": "Node",
     "Resource Data:": "Resource Data:",
     "vCores": "vCores",
     "MB": "MB",
     "MySQL": "MySQL",
     "ports": "ports",
-    "Required": "Required",
-    "to create this server": "to create this server",
-    "Server cant fit on this Node": "Server cant fit on this Node",
     "Not enough": "Not enough",
     "Create server": "Create server",
     "Please select a node ...": "Please select a node ...",
@@ -600,20 +472,20 @@
     "Hourly Price": "Hourly Price",
     "Monthly Price": "Monthly Price",
     "MySQL Database": "MySQL Database",
-    "Upgrade \/ Downgrade": "Upgrade \/ Downgrade",
-    "Upgrade\/Downgrade Server": "Upgrade\/Downgrade Server",
+    "To enable the upgrade/downgrade system, please set your Ptero Admin-User API Key in the Settings!": "To enable the upgrade/downgrade system, please set your Ptero Admin-User API Key in the Settings!",
+    "Upgrade / Downgrade": "Upgrade / Downgrade",
+    "Upgrade/Downgrade Server": "Upgrade/Downgrade Server",
     "FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN": "FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN",
     "YOUR PRODUCT": "YOUR PRODUCT",
     "Select the product": "Select the product",
-    "Server can´t fit on this node": "Server can´t fit on this node",
     "Once the Upgrade button is pressed, we will automatically deduct the amount for the first hour according to the new product from your credits": "Once the Upgrade button is pressed, we will automatically deduct the amount for the first hour according to the new product from your credits",
-    "Server will be automatically restarted once upgraded": "Server will be automatically restarted once upgraded",
     "Change Product": "Change Product",
     "Delete Server": "Delete Server",
     "This is an irreversible action, all files of this server will be removed!": "This is an irreversible action, all files of this server will be removed!",
     "Date": "Date",
     "Subtotal": "Subtotal",
     "Amount Due": "Amount Due",
+    "Tax": "Tax",
     "Submit Payment": "Submit Payment",
     "Purchase": "Purchase",
     "There are no store products!": "There are no store products!",
@@ -632,10 +504,13 @@
     "VAT Code": "VAT Code",
     "Phone": "Phone",
     "Units": "Units",
+    "Discount": "Discount",
     "Total discount": "Total discount",
     "Taxable amount": "Taxable amount",
     "Tax rate": "Tax rate",
+    "Total taxes": "Total taxes",
     "Shipping": "Shipping",
+    "Total amount": "Total amount",
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
@@ -653,5 +528,30 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
-}
\ No newline at end of file
+    "hu": "Hungarian",
+    "hourly": "Hourly",
+    "monthly": "Monthly",
+    "yearly": "Yearly",
+    "daily": "Daily",
+    "weekly": "Weekly",
+    "quarterly": "Quarterly",
+    "half-annually": "Half-annually",
+    "annually": "Annually",
+    "Suspended": "Suspended",
+    "Cancelled": "Cancelled",
+    "An exception has occurred while trying to cancel the server": "An exception has occurred while trying to cancel the server",
+    "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
+    "Cancel Server?": "Cancel Server?",
+    "Delete Server?": "Delete Server?",
+    "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.",
+    "Billing Period": "Billing Period",
+    "Next Billing Cycle": "Next Billing Cycle",
+    "Manage Server": "Manage Server",
+    "Delete Server": "Delete Server",
+    "Cancel Server": "Cancel Server",
+    "Yes, cancel it!": "Yes, cancel it!",
+    "No, abort!": "No, abort!",
+    "Billing period": "Billing period",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution"
+}
diff --git a/lang/es.json b/lang/es.json
index 400a46f49..818d8e132 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Error de creación del servidor",
     "Your servers have been suspended!": "¡Sus servidores han sido suspendidos!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Para volver a habilitar automáticamente sus servidores, debe comprar más créditos.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Para volver a habilitar automáticamente sus servidores, debe comprar más créditos.",
     "Purchase credits": "Comprar Créditos",
     "If you have any questions please let us know.": "Si tienes más preguntas, por favor háznoslas saber.",
     "Regards": "Atentamente",
@@ -93,7 +93,7 @@
     "Getting started!": "¡Empezando!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -174,10 +174,10 @@
     "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "cree un archivo llamado \"install.lock\" en el directorio Raíz de su tablero. ¡De lo contrario, no se cargará ninguna configuración!",
     "or click here": "o haga clic aquí",
     "Company Name": "Nombre Empresa",
-    "Company Address": "Dirección de la Empresa",
+    "Company Adress": "Dirección de la Empresa",
     "Company Phonenumber": "Número de teléfono de la empresa",
     "VAT ID": "ID de IVA",
-    "Company E-Mail Address": "Dirección de correo electrónico de la empresa",
+    "Company E-Mail Adress": "Dirección de correo electrónico de la empresa",
     "Company Website": "Página Web de la empresa",
     "Invoice Prefix": "Prefijo de factura",
     "Enable Invoices": "Habilitar facturas",
@@ -187,7 +187,7 @@
     "Default language": "Idioma predeterminado",
     "The fallback Language, if something goes wrong": "El lenguaje alternativo, si algo sale mal",
     "Datable language": "Lenguaje de tabla de datos",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "El código de idioma de las tablas de datos. <br><strong>Ejemplo:<\/strong> en-gb, fr_fr, de_de<br>Más información: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "El código de idioma de las tablas de datos. <br><strong>Ejemplo:</strong> en-gb, fr_fr, de_de<br>Más información: ",
     "Auto-translate": "Traducir automáticamente",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Si está marcado, el Tablero se traducirá solo al idioma del Cliente, si está disponible",
     "Client Language-Switch": "Cambio de idioma del cliente",
@@ -199,7 +199,7 @@
     "Mail Username": "Nombre de usuario del correo",
     "Mail Password": "Contraseña de correo",
     "Mail Encryption": "Cifrado de correo",
-    "Mail From Address": "Dirección del correo",
+    "Mail From Adress": "Dirección del correo",
     "Mail From Name": "Nombre del correo",
     "Discord Client-ID": "Discord ID-Cliente",
     "Discord Client-Secret": "Discord Secreto-Cliente",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Carga la primera hora de créditos al crear un servidor.",
     "Credits Display Name": "Nombre de los Créditos para mostrar",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Ingrese la URL de su instalación de PHPMyAdmin. <strong>¡Sin una barra diagonal final!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Ingrese la URL de su instalación de PHPMyAdmin. <strong>¡Sin una barra diagonal final!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Introduzca la URL de su instalación de Pterodactyl. <strong>¡Sin una barra diagonal final!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Introduzca la URL de su instalación de Pterodactyl. <strong>¡Sin una barra diagonal final!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Ingrese la API Key para su instalación de Pterodactyl.",
     "Force Discord verification": "Forzar verificación de Discord",
@@ -263,7 +263,7 @@
     "Select panel favicon": "Seleccionar favicon del panel",
     "Store": "Tienda",
     "Server Slots": "Server Slots",
-    "Currency code": "Código de divisa\/moneda",
+    "Currency code": "Código de divisa/moneda",
     "Checkout the paypal docs to select the appropriate code": "Consulte los documentos de PayPal para seleccionar el código apropiado",
     "Quantity": "Cantidad",
     "Amount given to the user after purchasing": "Importe dado al usuario después de la compra",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "El descuento solo se puede utilizar una vez por usuario. Los usos especifica el número de usuarios diferentes que pueden utilizar este cupón.",
     "Max": "Máx",
     "Expires at": "Expira el",
-    "Used \/ Uses": "Uso \/ Usos",
+    "Used / Uses": "Uso / Usos",
     "Expires": "Expira",
     "Sign in to start your session": "Iniciar sesión para comenzar",
     "Password": "Contraseña",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "¡No se han vinculado nodos!",
     "No nests available!": "¡No hay nidos disponibles!",
     "No eggs have been linked!": "¡No se han vinculado huevos!",
-    "Software \/ Games": "Software \/ Juegos",
+    "Software / Games": "Software / Juegos",
     "Please select software ...": "Seleccione el software...",
     "---": "---",
     "Specification ": "Especificación ",
@@ -460,5 +460,7 @@
     "tr": "Turco",
     "ru": "Ruso",
     "sv": "Sueco",
-    "sk": "Eslovaco"
+    "sk": "Eslovaco",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Actualizar/Reducir el servidor restablecerá su ciclo de facturación a ahora. Se reembolsarán los créditos sobrepagados. El precio del nuevo ciclo de facturación se retirará",
+    "Caution": "Cuidado"
 }
diff --git a/lang/fr.json b/lang/fr.json
index f415e5c62..65a6bc44c 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Erreur lors de la création de votre serveur",
     "Your servers have been suspended!": "Votre serveur à été suspendu !",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Pour réactiver automatiquement votre ou vos serveurs, vous devez racheter des crédits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Pour réactiver automatiquement votre ou vos serveurs, vous devez racheter des crédits.",
     "Purchase credits": "Acheter des crédits",
     "If you have any questions please let us know.": "N'hésitez pas à nous contacter si vous avez des questions.",
     "Regards": "Cordialement",
@@ -93,7 +93,7 @@
     "Getting started!": "Commencer !",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Langue par défaut",
     "The fallback Language, if something goes wrong": "La langue de repli, si quelque chose ne va pas",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Le code ne peut être utilisé qu'une seule fois. L'utilisation spécifie le nombre d'utilisateurs différents qui peuvent utiliser ce code.",
     "Max": "Max",
     "Expires at": "Expire à",
-    "Used \/ Uses": "Utilisé \/ Utilisations",
+    "Used / Uses": "Utilisé / Utilisations",
     "Expires": "Expire",
     "Sign in to start your session": "Identifiez-vous pour commencer votre session",
     "Password": "Mot de passe",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Aucune node n'a été lié !",
     "No nests available!": "Aucun nests disponible !",
     "No eggs have been linked!": "Aucun eggs n'a été lié !",
-    "Software \/ Games": "Logiciels \/ Jeux",
+    "Software / Games": "Logiciels / Jeux",
     "Please select software ...": "Veuillez sélectionner...",
     "---": "---",
     "Specification ": "Spécification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Montant en toutes lettres",
     "Please pay until": "Veuillez payer avant",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Mettre à niveau / Réduire votre serveur réinitialisera votre cycle de facturation à maintenant. Vos crédits surpayés seront remboursés. Le prix du nouveau cycle de facturation sera débité",
+    "Caution": "Attention",
     "cs": "Czech",
     "de": "German",
     "en": "English",
diff --git a/lang/he.json b/lang/he.json
index a1524d6fb..a64fde04a 100644
--- a/lang/he.json
+++ b/lang/he.json
@@ -60,8 +60,8 @@
     "You ran out of Credits": "נגמר לך המטבעות",
     "Profile updated": "הפרופיל עודכן",
     "Server limit reached!": "הגעת להגבלת השרתים!",
-    "You are required to verify your email address before you can create a server.": "אתה מדרש לאמת את כתובת המייל שלך לפני שתוכל\/י ליצור שרת",
-    "You are required to link your discord account before you can create a server.": "אתה חייב לקשר את החשבון דיסקורד שלך לפני שתוכל\/י ליצור שרת",
+    "You are required to verify your email address before you can create a server.": "אתה מדרש לאמת את כתובת המייל שלך לפני שתוכל/י ליצור שרת",
+    "You are required to link your discord account before you can create a server.": "אתה חייב לקשר את החשבון דיסקורד שלך לפני שתוכל/י ליצור שרת",
     "Server created": "השרת נוצר",
     "No allocations satisfying the requirements for automatic deployment on this node were found.": "לא נמצאו הקצאות העומדות בדרישות לפריסה אוטומטית בשרת זה.",
     "You are required to verify your email address before you can purchase credits.": "אתה נדרש לאמת את כתובת המייל שלך לפני רכישת מטבעות",
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "שגיאה ביצירת שרת",
     "Your servers have been suspended!": "השרת שלך מושעה!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "כדי להפעיל מחדש את השרתים שלך באופן אוטומטי, עליך לרכוש מטבעות נוספות.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "כדי להפעיל מחדש את השרתים שלך באופן אוטומטי, עליך לרכוש מטבעות נוספות.",
     "Purchase credits": "לרכישת מטבעות",
     "If you have any questions please let us know.": "אם יש לכם כל שאלה תיידעו אותנו",
     "Regards": "בברכה",
@@ -93,7 +93,7 @@
     "Getting started!": "מתחילים!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -125,7 +125,7 @@
     "Admin Overview": "סקירת מנהל",
     "Support server": "שרת תמיכה",
     "Documentation": "מדריך",
-    "Github": "Github\/גיטאהב",
+    "Github": "Github/גיטאהב",
     "Support ControlPanel": "תמיכת ControlPanel",
     "Servers": "שרתים",
     "Total": "בסך הכל",
@@ -156,7 +156,7 @@
     "Minimum": "מינימום",
     "Setting to -1 will use the value from configuration.": "הגדרות ל -1 ישתמש בערך מ configuration.",
     "IO": "IO",
-    "Databases": "Databases\/ממסד נתונים",
+    "Databases": "Databases/ממסד נתונים",
     "Backups": "גיבויים",
     "Allocations": "הקצאות",
     "Product Linking": "מוצרים מקושרים",
@@ -174,10 +174,10 @@
     "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "אנא צור קובץ בשם \"install.lock\" בספריית השורש של dashboard שלך. אחרת לא ייטענו הגדרות!",
     "or click here": "או לחץ כאן",
     "Company Name": "שם החברה",
-    "Company Address": "כתובת החברה",
+    "Company Adress": "כתובת החברה",
     "Company Phonenumber": "מספר טלפון של החברה",
     "VAT ID": "מזהה מעמ",
-    "Company E-Mail Address": "כתובת מייל של החברה",
+    "Company E-Mail Adress": "כתובת מייל של החברה",
     "Company Website": "אתר החברה",
     "Invoice Prefix": "קידומת החשבונים",
     "Enable Invoices": "אפשר חשבוניות",
@@ -187,7 +187,7 @@
     "Default language": "שפת ברירת מחדל",
     "The fallback Language, if something goes wrong": "אם משהו משתבש",
     "Datable language": "שפה ניתנת לנתונים",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "טבלת הנתונים של השפות.<br><strong>לדוגמא:<\/strong> en-gb, fr_fr, de_de<br>למידע נוסף: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "טבלת הנתונים של השפות.<br><strong>לדוגמא:</strong> en-gb, fr_fr, de_de<br>למידע נוסף: ",
     "Auto-translate": "תרגום אוטומטי",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "אם זה מסומן, Dashboard יתרגם את עצמו לשפת הלקוח, אם זמין",
     "Client Language-Switch": "החלפת שפת לקוח",
@@ -199,7 +199,7 @@
     "Mail Username": "שם המייל",
     "Mail Password": "סיסמת המייל",
     "Mail Encryption": "הצפנת המייל",
-    "Mail From Address": "מייל מכתובת",
+    "Mail From Adress": "מייל מכתובת",
     "Mail From Name": "מייל משם",
     "Discord Client-ID": "מזהה של בוט דיסקורד",
     "Discord Client-Secret": "מזהה סודי של בוט דיסקורד",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Cגובה מטבעות בשווי השעה הראשונה בעת יצירת שרת.",
     "Credits Display Name": "שם המטבעות",
     "PHPMyAdmin URL": "קישור PHPMyAdmin",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "הכנס את הקישור to פיחפי. <strong>בלי צלייה נגררת!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "הכנס את הקישור to פיחפי. <strong>בלי צלייה נגררת!</strong>",
     "Pterodactyl URL": "קישור Pterodactyl",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API מפתח",
     "Enter the API Key to your Pterodactyl installation.": "הכנס את מפתח ה API Pterodactyl installation.",
     "Force Discord verification": "אימות דיסקורד חובה",
@@ -300,12 +300,12 @@
     "Notifications": "התראות",
     "All": "הכל",
     "Send via": "שליחה באמצאות",
-    "Database": "Database\/מאגר נתונים",
+    "Database": "Database/מאגר נתונים",
     "Content": "קשר",
     "Server limit": "הגבלת שרת",
-    "Discord": "Discord\/דיסקורד",
+    "Discord": "Discord/דיסקורד",
     "Usage": "נוהג",
-    "IP": "IP\/אייפי",
+    "IP": "IP/אייפי",
     "Referals": "Referals",
     "Vouchers": "קופונים",
     "Voucher details": "פרטי קופון",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "ניתן להשתמש בשובר פעם אחת בלבד לכל משתמש. שימושים מציינים את מספר המשתמשים השונים שיכולים להשתמש בשובר זה.",
     "Max": "מקסימום",
     "Expires at": "יפוג ב",
-    "Used \/ Uses": "משומש \/ שימושים",
+    "Used / Uses": "משומש / שימושים",
     "Expires": "פגי תוקף",
     "Sign in to start your session": "התחבר על מנת להתחיל",
     "Password": "סיסמה",
@@ -339,7 +339,7 @@
     "Before proceeding, please check your email for a verification link.": "לפני שתמשיך, אנא בדוק באימייל שלך קישור לאימות.",
     "If you did not receive the email": "אם לא קיבלת את המייל",
     "click here to request another": "לחץ כאן כדי לבקש אחר",
-    "per month": "\/חודש",
+    "per month": "/חודש",
     "Out of Credits in": "נגמרו המטבעות ב",
     "Home": "בית",
     "Language": "שפה",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "שרתים לא מקושרים!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "אין eggs מקושרים",
-    "Software \/ Games": "תוכנה \/ משחקים",
+    "Software / Games": "תוכנה / משחקים",
     "Please select software ...": "בבקשה תחבר תוכנה ...",
     "---": "---",
     "Specification ": "ציין ",
@@ -411,9 +411,9 @@
     "Specification": "לציין",
     "Resource plan": "תוכנית משאבים",
     "RAM": "RAM",
-    "MySQL Databases": "בסיס הנתונים <bdi dir=\"ltr\">MySQL<\/bdi>",
-    "per Hour": "\/שעה",
-    "per Month": "\/חודש",
+    "MySQL Databases": "בסיס הנתונים <bdi dir=\"ltr\">MySQL</bdi>",
+    "per Hour": "/שעה",
+    "per Month": "/חודש",
     "Manage": "לנהל",
     "Are you sure?": "האם אתה בטוח?",
     "This is an irreversible action, all files of this server will be removed.": "זוהי פעולה בלתי הפיכה, כל הקבצים של שרת זה יוסרו.",
@@ -460,5 +460,7 @@
     "tr": "טורקית",
     "ru": "רוסית",
     "sv": "שוודית",
-    "sk": "סלובקית"
+    "sk": "סלובקית",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "שדרוג / הורדת שרת יאפס את מחזור החיוב שלך לעכשיו. הקרדיטים ששילמת יוחזרו. המחיר למחזור החיוב החדש יוחסם",
+    "Caution": "אזהרה"
 }
diff --git a/lang/hi.json b/lang/hi.json
index e7b950b14..1449e92af 100644
--- a/lang/hi.json
+++ b/lang/hi.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "सर्वर निर्माण त्रुटि",
     "Your servers have been suspended!": "आपके सर्वर निलंबित कर दिए गए हैं!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "अपने सर्वर\/सर्वर को स्वचालित रूप से पुन: सक्षम करने के लिए, आपको अधिक क्रेडिट खरीदने की आवश्यकता है।",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "अपने सर्वर/सर्वर को स्वचालित रूप से पुन: सक्षम करने के लिए, आपको अधिक क्रेडिट खरीदने की आवश्यकता है।",
     "Purchase credits": "क्रेडिट खरीदें",
     "If you have any questions please let us know.": "यदि आपके पास कोई प्रश्न है, तो हमें बताएं।",
     "Regards": "सादर",
@@ -93,7 +93,7 @@
     "Getting started!": "शुरू करना!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "डिफ़ॉल्ट भाषा",
     "The fallback Language, if something goes wrong": "फ़ॉलबैक भाषा, अगर कुछ गलत हो जाता है",
     "Datable language": "डेटा योग्य भाषा",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "डेटाटेबल्स लैंग-कोड। <br><strong>उदाहरण:<\/strong> en-gb, fr_fr, de_de<br>अधिक जानकारी: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "डेटाटेबल्स लैंग-कोड। <br><strong>उदाहरण:</strong> en-gb, fr_fr, de_de<br>अधिक जानकारी: ",
     "Auto-translate": "ऑटो का अनुवाद",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "यदि यह चेक किया जाता है, तो डैशबोर्ड स्वयं को क्लाइंट भाषा में अनुवाद करेगा, यदि उपलब्ध हो",
     "Client Language-Switch": "क्लाइंट भाषा-स्विच",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "सर्वर बनाने पर पहले घंटे के क्रेडिट का शुल्क लेता है।",
     "Credits Display Name": "क्रेडिट प्रदर्शन नाम",
     "PHPMyAdmin URL": "PhpMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "अपने PHPMyAdmin इंस्टॉलेशन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "अपने PHPMyAdmin इंस्टॉलेशन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!</strong>",
     "Pterodactyl URL": "पटरोडैक्टाइल यूआरएल",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "अपने Pterodactyl संस्थापन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "अपने Pterodactyl संस्थापन का URL दर्ज करें। <strong>पिछली स्लैश के बिना!</strong>",
     "Pterodactyl API Key": "पटरोडैक्टाइल एपीआई कुंजी",
     "Enter the API Key to your Pterodactyl installation.": "अपने Pterodactyl स्थापना के लिए API कुंजी दर्ज करें।",
     "Force Discord verification": "बल विवाद सत्यापन",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "वाउचर प्रति उपयोगकर्ता केवल एक बार उपयोग किया जा सकता है। उपयोग इस वाउचर का उपयोग करने वाले विभिन्न उपयोगकर्ताओं की संख्या को निर्दिष्ट करता है।",
     "Max": "मैक्स",
     "Expires at": "पर समाप्त हो रहा है",
-    "Used \/ Uses": "प्रयुक्त \/ उपयोग",
+    "Used / Uses": "प्रयुक्त / उपयोग",
     "Expires": "समय-सीमा समाप्त",
     "Sign in to start your session": "अपना सत्र शुरू करने के लिए साइन इन करें",
     "Password": "पासवर्ड",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "कोई नोड लिंक नहीं किया गया है!",
     "No nests available!": "कोई घोंसला उपलब्ध नहीं है!",
     "No eggs have been linked!": "कोई अंडे नहीं जोड़े गए हैं!",
-    "Software \/ Games": "सॉफ्टवेयर \/ खेल",
+    "Software / Games": "सॉफ्टवेयर / खेल",
     "Please select software ...": "कृपया सॉफ्टवेयर चुनें...",
     "---": "---",
     "Specification ": "विनिर्देश",
@@ -447,6 +447,8 @@
     "Notes": "टिप्पणियाँ",
     "Amount in words": "राशि शब्दों में",
     "Please pay until": "कृपया भुगतान करें",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "अपने सर्वर को अपग्रेड / डाउनग्रेड करने से आपका बिलिंग साइकिल अब तक रीसेट हो जाएगा। आपके ओवरपेड क्रेडिट वापस किया जाएगा। नए बिलिंग साइकिल के लिए की गई मूल्य निकाला जाएगा",
+    "Caution": "सावधान",
     "cs": "चेक",
     "de": "जर्मन",
     "en": "अंग्रेज़ी",
diff --git a/lang/hu.json b/lang/hu.json
index 744fcf0c3..30350eacf 100644
--- a/lang/hu.json
+++ b/lang/hu.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Valaki regisztrált a te Kódoddal!",
     "Server Creation Error": "Hiba a szerver készítése közben",
     "Your servers have been suspended!": "A szervered fel lett függesztve!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "A szervered\/szervereid autómatikus újraengedélyezéséhez Kreditet kell vásárolnod.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "A szervered/szervereid autómatikus újraengedélyezéséhez Kreditet kell vásárolnod.",
     "Purchase credits": "Kreditek vásárlása",
     "If you have any questions please let us know.": "Ha kérdésed van, kérjük fordulj hozzánk.",
     "Regards": "Üdvözlettel",
@@ -93,7 +93,7 @@
     "Getting started!": "Kezdhetjük!",
     "Welcome to our dashboard": "Üdvözlünk az Irányítópultban",
     "Verification": "Hitelesítés",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Hitelesíteni tudod az email címedet és a Discord fiókodat.",
+    "You can verify your e-mail address and link/verify your Discord account.": "Hitelesíteni tudod az email címedet és a Discord fiókodat.",
     "Information": "Információk",
     "This dashboard can be used to create and delete servers": "Ebben az Irányítópultban szervereket tudsz létrehozni és törölni",
     "These servers can be used and managed on our pterodactyl panel": "Ezeket a szervereket a Pterodactyl panelben tudod kezelni",
@@ -187,7 +187,7 @@
     "Default language": "Alapértelmezett nyelv",
     "The fallback Language, if something goes wrong": "A tartalék nyelv, ha bármi rosszul működne",
     "Datable language": "Keltezhető nyelv",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Az adattáblák kódnyelve. <br><strong>Például:<\/strong> en-gb, fr_fr, de_de<br>Több információ: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Az adattáblák kódnyelve. <br><strong>Például:</strong> en-gb, fr_fr, de_de<br>Több információ: ",
     "Auto-translate": "Autómatikus fordítás",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Ha be van kapcsolva, akkor az Irányítópult autómatikusan le lesz fordítva a Kliens által használt nyelvre, ha az elérhető",
     "Client Language-Switch": "Kliens nyelv váltás",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Első óra kifizetése szerver létrehozásnál.",
     "Credits Display Name": "Kredit megnevezése",
     "PHPMyAdmin URL": "PHPMyAdmin Hivatkozás",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Írd be a hivatkozást a PHPMyAdmin telepítéséhez. <strong>A zárjó perjel nélkül!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Írd be a hivatkozást a PHPMyAdmin telepítéséhez. <strong>A zárjó perjel nélkül!</strong>",
     "Pterodactyl URL": "Pterodactyl Hivatkozás",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Írd be a hivatkozást a Pterodactyl telepítéséhez. <strong>A zárjó perjel nélkül!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Írd be a hivatkozást a Pterodactyl telepítéséhez. <strong>A zárjó perjel nélkül!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Kulcs",
     "Enter the API Key to your Pterodactyl installation.": "Írd be az API Kulcsot a Pterodactyl telepítéséhez.",
     "Force Discord verification": "Discord hitelesítés kötelezése",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Az utalványt egy felhasználó csak egyszer használhatja fel. Ezzel meg tudod adni, hogy hány felhasználó tudja felhasználni az utalványt.",
     "Max": "Max",
     "Expires at": "Lejárás ideje",
-    "Used \/ Uses": "Felhasználva \/ Felhasználások száma",
+    "Used / Uses": "Felhasználva / Felhasználások száma",
     "Expires": "Lejár",
     "Sign in to start your session": "Jelentkezz be a munkamenet elindításához",
     "Password": "Jelszó",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Nem lett csomópont hozzácsatolva!",
     "No nests available!": "Nincs elérhető fészek!",
     "No eggs have been linked!": "Nem lett tojás hozzácsatolva!",
-    "Software \/ Games": "Szoftver \/ Játékok",
+    "Software / Games": "Szoftver / Játékok",
     "Please select software ...": "Szoftver kiválasztása ...",
     "---": "---",
     "Specification ": "Specifikációk ",
@@ -447,6 +447,8 @@
     "Notes": "Jegyzetek",
     "Amount in words": "Mennyiség szavakban",
     "Please pay until": "Fizetési határidő",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "A szerver frissítése / lefrissítése visszaállítja a számlázási ciklust az aktuálisra. A túlfizetett Kreditet visszatérítjük. A számlázási ciklus új ára lesz kivonva",
+    "Caution": "Figyelem",
     "cs": "Cseh",
     "de": "Német",
     "en": "Angol",
diff --git a/lang/it.json b/lang/it.json
index 5bc51c875..ac2f1020f 100644
--- a/lang/it.json
+++ b/lang/it.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Errore di creazione del server",
     "Your servers have been suspended!": "I tuoi server sono stati sospesi!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Per ri-abilitare i tuoi server automaticamente, devi acquistare più crediti.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Per ri-abilitare i tuoi server automaticamente, devi acquistare più crediti.",
     "Purchase credits": "Acquista crediti",
     "If you have any questions please let us know.": "Se hai una domanda faccelo sapere.",
     "Regards": "Cordialmente",
@@ -93,7 +93,7 @@
     "Getting started!": "Come iniziare!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Lingua predefinita",
     "The fallback Language, if something goes wrong": "La lingua secondaria, se qualcosa va storto",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Il lang-code dei datatables. <br><strong>Esempio:<\/strong> en-gb, fr_fr, de_de<br>Piu informazioni: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Il lang-code dei datatables. <br><strong>Esempio:</strong> en-gb, fr_fr, de_de<br>Piu informazioni: ",
     "Auto-translate": "Traduzione-automatica",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Se questo è abilitato la dashboard si traducerà automaticamente alla lingua dei clienti, se disponibile",
     "Client Language-Switch": "Switch delle lingue dei clienti",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Addebita la prima ora in crediti alla creazione di un server.",
     "Credits Display Name": "Nome di Visualizzazione dei Crediti",
     "PHPMyAdmin URL": "URL PHPMyAdmin",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Inserisci l'URL alla tua installazione di PHPMyAdmin. <strong>Senza lo slash finale!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Inserisci l'URL alla tua installazione di PHPMyAdmin. <strong>Senza lo slash finale!</strong>",
     "Pterodactyl URL": "URL di Pterodactyl",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Inserisci l'URL alla tua installazione di Pterodactyl. <strong>Senza un trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Inserisci l'URL alla tua installazione di Pterodactyl. <strong>Senza un trailing slash!</strong>",
     "Pterodactyl API Key": "Chiave API di Pterodactyl",
     "Enter the API Key to your Pterodactyl installation.": "Inserisci la Chiave API alla tua installazione di Pterodactyl.",
     "Force Discord verification": "Forza la verifica di Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Un voucher può essere utilizzato solo una volta per utente. Il numero di usi specifica il numero di utenti diversi che possono utilizzare questo voucher.",
     "Max": "Massimo",
     "Expires at": "Scade il",
-    "Used \/ Uses": "Usato \/ Utilizzi",
+    "Used / Uses": "Usato / Utilizzi",
     "Expires": "Scade",
     "Sign in to start your session": "Accedi per iniziare la sessione",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Nessun nodo è stato connesso!",
     "No nests available!": "Nessun nido (nest) disponibile!",
     "No eggs have been linked!": "Nessun uovo (egg) è stato connesso!",
-    "Software \/ Games": "Software \/ Giochi",
+    "Software / Games": "Software / Giochi",
     "Please select software ...": "Per favore selezione il software...",
     "---": "---",
     "Specification ": "Specifiche ",
@@ -447,6 +447,8 @@
     "Notes": "Note",
     "Amount in words": "Numero in parole",
     "Please pay until": "Per favore paga fino",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "L’aggiornamento / riduzione del tuo server reimposterà il tuo ciclo di fatturazione a ora. I tuoi crediti in eccesso saranno rimborsati. Il prezzo per il nuovo ciclo di fatturazione sarà prelevato",
+    "Caution": "Attenzione",
     "cs": "Ceco",
     "de": "Tedesco",
     "en": "Inglese",
diff --git a/lang/nl.json b/lang/nl.json
index 5e72fc395..6ff9ecf53 100644
--- a/lang/nl.json
+++ b/lang/nl.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Fout bij het maken van de server",
     "Your servers have been suspended!": "Uw servers zijn opgeschort!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Om uw server(s) automatisch opnieuw in te schakelen, moet u meer credits kopen.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Om uw server(s) automatisch opnieuw in te schakelen, moet u meer credits kopen.",
     "Purchase credits": "Credits kopen",
     "If you have any questions please let us know.": "Als u vragen heeft, laat het ons dan weten.",
     "Regards": "Met vriendelijke groet",
@@ -93,7 +93,7 @@
     "Getting started!": "Aan de slag!",
     "Welcome to our dashboard": "Welkom bij ons dashboard",
     "Verification": "Verificatie",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Informatie",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Standaard taal",
     "The fallback Language, if something goes wrong": "De terugval-taal, als er iets misgaat",
     "Datable language": "Dateerbare taal",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "De datatabellen lang-code. <br><strong>Voorbeeld:<\/strong> nl-gb, fr_fr, de_de<br>Meer informatie: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "De datatabellen lang-code. <br><strong>Voorbeeld:</strong> nl-gb, fr_fr, de_de<br>Meer informatie: ",
     "Auto-translate": "Automatisch vertalen",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Als dit is aangevinkt, zal het dashboard zichzelf vertalen naar de taal van de klant, indien beschikbaar",
     "Client Language-Switch": "Klant Taal-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Brengt het eerste uur aan credits in rekening bij het maken van een server.",
     "Credits Display Name": "Weergavenaam tegoed",
     "PHPMyAdmin URL": "PHPMyAdmin-URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Voer de URL naar uw PHPMyAdmin-installatie in. <strong>Zonder een slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Voer de URL naar uw PHPMyAdmin-installatie in. <strong>Zonder een slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Voer de URL naar uw Pterodactyl-installatie in. <strong>Zonder een slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Voer de URL naar uw Pterodactyl-installatie in. <strong>Zonder een slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API sleutel",
     "Enter the API Key to your Pterodactyl installation.": "Voer de API-sleutel in voor uw Pterodactyl-installatie.",
     "Force Discord verification": "Forceer Discord Verificatie",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Een voucher kan slechts één keer per gebruiker worden gebruikt. Gebruik geeft het aantal verschillende gebruikers aan dat deze voucher kan gebruiken.",
     "Max": "Maximum",
     "Expires at": "Verloopt om",
-    "Used \/ Uses": "Gebruikt \/ Toepassingen",
+    "Used / Uses": "Gebruikt / Toepassingen",
     "Expires": "Verloopt",
     "Sign in to start your session": "Login om te beginnen",
     "Password": "Wachtwoord",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Er zijn geen nodes gekoppeld!",
     "No nests available!": "Er zijn geen nesten beschikbaar!",
     "No eggs have been linked!": "Geen eieren gekoppeld!",
-    "Software \/ Games": "Software \/ Spellen",
+    "Software / Games": "Software / Spellen",
     "Please select software ...": "Selecteer software...",
     "---": "---",
     "Specification ": "Specificatie ",
@@ -447,6 +447,8 @@
     "Notes": "Notities",
     "Amount in words": "Hoeveelheid in eenheden",
     "Please pay until": "Gelieve te betalen tot",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgraden/downgraden van uw server zal uw facturatiecyclus resetten naar nu. Uw overbetalen krediet zal worden terugbetaald. De prijs voor de nieuwe facturatiecyclus zal worden afgeschreven",
+    "Caution": "Let op",
     "cs": "Tsjechisch",
     "de": "Duits",
     "en": "Engels",
diff --git a/lang/pl.json b/lang/pl.json
index 14bfaee38..b1f4164dd 100644
--- a/lang/pl.json
+++ b/lang/pl.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Błąd podczas tworzenia serwera",
     "Your servers have been suspended!": "Serwery zostały zawieszone!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Aby reaktywować swoje serwery, musisz kupić więcej kredytów.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Aby reaktywować swoje serwery, musisz kupić więcej kredytów.",
     "Purchase credits": "Zakup kredyty",
     "If you have any questions please let us know.": "W razie jakichkolwiek pytań prosimy o kontakt.",
     "Regards": "Z poważaniem",
@@ -93,7 +93,7 @@
     "Getting started!": "Zaczynajmy!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Domyślny język",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Domyślny język",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Automatyczne tłumaczenie",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Nazwa Waluty",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "URL Pterodactyl Panelu",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Klucz API Pterodactyl panelu",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Kupon może zostać zrealizowany tylko raz przez użytkownika. „Użycie” określa liczbę użytkowników, którzy mogą zrealizować ten kupon.",
     "Max": "Max",
     "Expires at": "Wygasa",
-    "Used \/ Uses": "Użyto \/ Użyć",
+    "Used / Uses": "Użyto / Użyć",
     "Expires": "Wygasa",
     "Sign in to start your session": "Zaloguj się, aby rozpocząć sesję",
     "Password": "Hasło",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Żaden węzeł nie został połączony!",
     "No nests available!": "Brak dostępnych gniazd!",
     "No eggs have been linked!": "Jajka nie zostały połaczone!",
-    "Software \/ Games": "Oprogramowanie \/ gry",
+    "Software / Games": "Oprogramowanie / gry",
     "Please select software ...": "Proszę wybrać oprogramowanie...",
     "---": "---",
     "Specification ": "Specyfikacja ",
@@ -447,6 +447,8 @@
     "Notes": "Uwagi",
     "Amount in words": "Wszystkie słowa",
     "Please pay until": "Zapłać w ciągu:",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizacja / degradacja twojego serwera spowoduje zresetowanie cyklu rozliczeniowego do teraz. Twoje nadpłacone kredyty zostaną zwrócone. Cena za nowy cykl rozliczeniowy zostanie pobrana",
+    "Caution": "Uwaga",
     "cs": "Czeski",
     "de": "Niemiecki",
     "en": "Angielski",
diff --git a/lang/pt.json b/lang/pt.json
index 1ce81866a..d31d5b9b0 100644
--- a/lang/pt.json
+++ b/lang/pt.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Alguém se registrou usando seu código!",
     "Server Creation Error": "Erro de criação do servidor",
     "Your servers have been suspended!": "Os seus servidores foram suspensos!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Para reativar automaticamente o seu(s) servidor(es), é preciso comprar mais créditos.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Para reativar automaticamente o seu(s) servidor(es), é preciso comprar mais créditos.",
     "Purchase credits": "Compra de créditos",
     "If you have any questions please let us know.": "Se tiver alguma dúvida, por favor, nos avise.",
     "Regards": "Cumprimentos,",
@@ -93,7 +93,7 @@
     "Getting started!": "Começar",
     "Welcome to our dashboard": "Bem-vindo ao nosso painel",
     "Verification": "Verificação",
-    "You can verify your e-mail address and link\/verify your Discord account.": "Você pode verificar o seu endereço de e-mail e link",
+    "You can verify your e-mail address and link/verify your Discord account.": "Você pode verificar o seu endereço de e-mail e link",
     "Information": "Informações",
     "This dashboard can be used to create and delete servers": "Este painel pode ser usado para criar e excluir servidores",
     "These servers can be used and managed on our pterodactyl panel": "Esses servidores podem ser usados e gerenciados no nosso painel pterodactyl ",
@@ -187,7 +187,7 @@
     "Default language": "Idioma padrão",
     "The fallback Language, if something goes wrong": "Um idioma padrão, se algo der errado",
     "Datable language": "Idioma de dados",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Os lang-codes disponíveis. <br><strong>Exemplo:<\/strong> en-gb, fr_fr, de_de<br>Mais informações:",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Os lang-codes disponíveis. <br><strong>Exemplo:</strong> en-gb, fr_fr, de_de<br>Mais informações:",
     "Auto-translate": "Traduzir Automaticamente",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Se isto for ativado, o Painel se traduzirá para o idioma do cliente, se disponível.",
     "Client Language-Switch": "Trocar Idioma do cliente",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Cobra a primeira hora de créditos ao criar um servidor.",
     "Credits Display Name": "Nome de exibição dos créditos",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Insira o URL do seu PHPMyAdmin. <strong>Sem barra de arrasto!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Insira o URL do seu PHPMyAdmin. <strong>Sem barra de arrasto!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Insira o URL do seu pterodactyl. <strong>Sem barra de arrasto!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Insira o URL do seu pterodactyl. <strong>Sem barra de arrasto!</strong>",
     "Pterodactyl API Key": "Chave API pterodactyl",
     "Enter the API Key to your Pterodactyl installation.": "Insira a chave API do seu painel pterodactyl.",
     "Force Discord verification": "Forçar verificação do Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Um vale só pode ser usado uma vez por utilizador. Os usos especificam o número de diferentes utilizadores que podem usar este comprovante.",
     "Max": "Máximo",
     "Expires at": "Expira em",
-    "Used \/ Uses": "Usados \/ Usos",
+    "Used / Uses": "Usados / Usos",
     "Expires": "Expira",
     "Sign in to start your session": "Entre para iniciar a sua sessão",
     "Password": "Senha",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Nenhum nó foi ligado!",
     "No nests available!": "Não há ninhos disponíveis!",
     "No eggs have been linked!": "Nenhum ovo foi ligado!",
-    "Software \/ Games": "“Software” \/ Jogos",
+    "Software / Games": "“Software” / Jogos",
     "Please select software ...": "Por favor, selecione o “software”...",
     "---": "—",
     "Specification ": "Especificação",
@@ -447,6 +447,8 @@
     "Notes": "Notas",
     "Amount in words": "Quantia em palavras",
     "Please pay until": "Favor pagar até",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Atualizar / Reduzir o seu servidor irá redefinir o seu ciclo de faturação para agora. Os seus créditos pagos a mais serão reembolsados. O preço para o novo ciclo de faturação será debitado",
+    "Caution": "Cuidado",
     "cs": "Tcheco",
     "de": "Alemão",
     "en": "Inglês",
diff --git a/lang/ro.json b/lang/ro.json
index f4c9004c1..ea3bdea16 100644
--- a/lang/ro.json
+++ b/lang/ro.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -93,7 +93,7 @@
     "Getting started!": "Getting started!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
diff --git a/lang/ru.json b/lang/ru.json
index 68755fabd..50e458e55 100644
--- a/lang/ru.json
+++ b/lang/ru.json
@@ -39,7 +39,7 @@
     "Store item has been removed!": "Товар в магазине был удален!",
     "link has been created!": "Ссылка была создана!",
     "link has been updated!": "Ссылка была обновлена!",
-    "product has been removed!": "Продукт\/Товар был удалён!",
+    "product has been removed!": "Продукт/Товар был удалён!",
     "User does not exists on pterodactyl's panel": "Пользователь не был найден в панеле птеродактиль",
     "user has been removed!": "Пользователь был удален!",
     "Notification sent!": "Оповещение отправлено!",
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Ошибка создание сервера",
     "Your servers have been suspended!": "Ваши сервера были заблокированы!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Чтобы автоматически повторно включить ваш сервер \/ серверы, вам необходимо приобрести больше кредитов.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Чтобы автоматически повторно включить ваш сервер / серверы, вам необходимо приобрести больше кредитов.",
     "Purchase credits": "Приобрести кредиты",
     "If you have any questions please let us know.": "Пожалуйста, сообщите нам, если у Вас есть какие-либо вопросы.",
     "Regards": "С уважением,",
@@ -93,7 +93,7 @@
     "Getting started!": "Начало работы!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Язык по умолчанию",
     "The fallback Language, if something goes wrong": "Резервный язык, если что-то пойдет не так",
     "Datable language": "Датадатируемый язык",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Языковой код таблицы данных. <br><strong>Пример:<\/strong> en-gb, fr_fr, de_de<br>Дополнительная информация:",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Языковой код таблицы данных. <br><strong>Пример:</strong> en-gb, fr_fr, de_de<br>Дополнительная информация:",
     "Auto-translate": "Автоперевод",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Если этот флажок установлен, информационная панель будет переводиться на язык клиентов, если он доступен",
     "Client Language-Switch": "Переключение языка клиента",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Взимает кредиты за первый час при создании сервера.",
     "Credits Display Name": "Отображаемое имя кредитов",
     "PHPMyAdmin URL": "URL-адрес PHPMyAdmin",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Введите URL-адрес вашей установки PHPMyAdmin. <strong>Без косой черты в конце!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Введите URL-адрес вашей установки PHPMyAdmin. <strong>Без косой черты в конце!</strong>",
     "Pterodactyl URL": "URL-адрес птеродактиля",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Введите URL-адрес вашей установки Pterodactyl. <strong>Без косой черты в конце!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Введите URL-адрес вашей установки Pterodactyl. <strong>Без косой черты в конце!</strong>",
     "Pterodactyl API Key": "API-ключ птеродактиля",
     "Enter the API Key to your Pterodactyl installation.": "Введите ключ API для установки Pterodactyl.",
     "Force Discord verification": "Требуется верификация в Discord",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Промокод можно использовать только один раз для каждого пользователя. Пользователь указывает количество различных пользователей, которые могут использовать этот промокод.",
     "Max": "Макс.",
     "Expires at": "Срок действия до",
-    "Used \/ Uses": "Используется \/ Использует",
+    "Used / Uses": "Используется / Использует",
     "Expires": "Истекает",
     "Sign in to start your session": "Войдите, чтобы начать сессию",
     "Password": "Пароль",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Ни один узел не был связан!",
     "No nests available!": "Гнезда в наличии нет!",
     "No eggs have been linked!": "Группы были связаны!",
-    "Software \/ Games": "Программное обеспечение \/ Игры",
+    "Software / Games": "Программное обеспечение / Игры",
     "Please select software ...": "Пожалуйста, выберите программное обеспечение...",
     "---": "---",
     "Specification ": "Характеристики ",
@@ -447,6 +447,8 @@
     "Notes": "Примечания",
     "Amount in words": "Сумма прописью",
     "Please pay until": "Пожалуйста, платите до",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Обновление/Уменьшение вашего сервера сбросит ваш цикл оплаты на текущий. Ваши переплаты будут возвращены. Цена за новый цикл оплаты будет списана",
+    "Caution": "Внимание",
     "cs": "Czech",
     "de": "German",
     "en": "English",
diff --git a/lang/sh.json b/lang/sh.json
index cd3b0e50f..bdf0019ba 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -80,7 +80,7 @@
     "User ID": "User ID",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -160,10 +160,10 @@
     "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!",
     "or click here": "or click here",
     "Company Name": "Company Name",
-    "Company Address": "Company Address",
+    "Company Adress": "Company Adress",
     "Company Phonenumber": "Company Phonenumber",
     "VAT ID": "VAT ID",
-    "Company E-Mail Address": "Company E-Mail Address",
+    "Company E-Mail Adress": "Company E-Mail Adress",
     "Company Website": "Company Website",
     "Invoice Prefix": "Invoice Prefix",
     "Enable Invoices": "Enable Invoices",
@@ -173,7 +173,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -185,7 +185,7 @@
     "Mail Username": "Mail Username",
     "Mail Password": "Mail Password",
     "Mail Encryption": "Mail Encryption",
-    "Mail From Address": "Mail From Address",
+    "Mail From Adress": "Mail From Adress",
     "Mail From Name": "Mail From Name",
     "Discord Client-ID": "Discord Client-ID",
     "Discord Client-Secret": "Discord Client-Secret",
@@ -214,9 +214,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -284,7 +284,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -354,7 +354,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -430,6 +430,8 @@
     "The Language of the Datatables. Grab the Language-Codes from here": "The Language of the Datatables. Grab the Language-Codes from here",
     "Let the Client change the Language": "Let the Client change the Language",
     "Icons updated!": "Icons updated!",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
@@ -441,28 +443,5 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Russian",
-    "hourly": "Hourly",
-    "monthly": "Monthly",
-    "yearly": "Yearly",
-    "daily": "Daily",
-    "weekly": "Weekly",
-    "quarterly": "Quarterly",
-    "half-annually": "Half-annually",
-    "annually": "Annually",
-    "Suspended": "Suspended",
-    "Cancelled": "Cancelled",
-    "An exception has occurred while trying to cancel the server": "An exception has occurred while trying to cancel the server",
-    "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.": "This will cancel your current server to the next billing period. It will get suspended when the current period runs out.",
-    "Cancel Server?": "Cancel Server?",
-    "Delete Server?": "Delete Server?",
-    "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.": "This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.",
-    "Billing Period": "Billing Period",
-    "Next Billing Cycle": "Next Billing Cycle",
-    "Manage Server": "Manage Server",
-    "Delete Server": "Delete Server",
-    "Cancel Server": "Cancel Server",
-    "Yes, cancel it!": "Yes, cancel it!",
-    "No, abort!": "No, abort!",
-    "Billing period": "Billing period"
+    "ru": "Russian"
 }
diff --git a/lang/sk.json b/lang/sk.json
index 136d498de..dc88baf2c 100644
--- a/lang/sk.json
+++ b/lang/sk.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Server Creation Error",
     "Your servers have been suspended!": "Your servers have been suspended!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "To automatically re-enable your server/s, you need to purchase more credits.",
     "Purchase credits": "Purchase credits",
     "If you have any questions please let us know.": "If you have any questions please let us know.",
     "Regards": "Regards",
@@ -93,7 +93,7 @@
     "Getting started!": "Getting started!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Default language",
     "The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Auto-translate",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizácia alebo deaktualizácia servera resetuje Vašu fakturačnú dobu na aktuálny čas. Vaše nadbytočné kredity budú vrátené. Cena za novú fakturačnú dobu bude odobraná.",
+    "Caution": "Upozornenie",
     "cs": "Czech",
     "de": "German",
     "en": "English",
diff --git a/lang/sr.json b/lang/sr.json
index 6e23c5260..599516313 100644
--- a/lang/sr.json
+++ b/lang/sr.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Greška pri kreiranju servera",
     "Your servers have been suspended!": "Vaši serveri su suspendovani!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Da biste automatski ponovo omogućili svoje servere, potrebno je da kupite još kredita.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Da biste automatski ponovo omogućili svoje servere, potrebno je da kupite još kredita.",
     "Purchase credits": "Kupite kredite",
     "If you have any questions please let us know.": "Ako imate bilo kakvih pitanja, molimo vas da nas obavestite.",
     "Regards": "Pozdravi",
@@ -93,7 +93,7 @@
     "Getting started!": "Početak!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Podrazumevani jezik",
     "The fallback Language, if something goes wrong": "Sekundarni jezik, u slučaju da bude problema",
     "Datable language": "Datable language",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ",
     "Auto-translate": "Automatski prevod",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Korisnički izbor za jezik",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Naplaćuje kredite u vrednosti od prvog sata prilikom kreiranja servera.",
     "Credits Display Name": "Ime prikaza kredita",
     "PHPMyAdmin URL": "PHPMyAdmin Link",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Unesite URL adresu instalacije PHPMyAdmin. <strong>Bez kose crte!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Unesite URL adresu instalacije PHPMyAdmin. <strong>Bez kose crte!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Maksimalno",
     "Expires at": "Ističe",
-    "Used \/ Uses": "Upotrebljeno \/ Upotrebe",
+    "Used / Uses": "Upotrebljeno / Upotrebe",
     "Expires": "Ističe",
     "Sign in to start your session": "Prijavite se da biste započeli sesiju",
     "Password": "Lozinka",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Node-ovi nisu povezani!",
     "No nests available!": "Nema dostupnih gnezda!",
     "No eggs have been linked!": "Jaja nisu povezana!",
-    "Software \/ Games": "Softver \/ Igrice",
+    "Software / Games": "Softver / Igrice",
     "Please select software ...": "Molimo izaberite softver ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Napomena",
     "Amount in words": "Iznos u rečima",
     "Please pay until": "Molimo platite do",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
diff --git a/lang/sv.json b/lang/sv.json
index 805887ef8..41d5d1c72 100644
--- a/lang/sv.json
+++ b/lang/sv.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Someone registered using your Code!",
     "Server Creation Error": "Serverskapande fel",
     "Your servers have been suspended!": "Ditt konto har blivit avstängt!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "För att automatiskt återaktivera din server\/s, så måste du köpa mer krediter.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "För att automatiskt återaktivera din server/s, så måste du köpa mer krediter.",
     "Purchase credits": "Köp krediter",
     "If you have any questions please let us know.": "Kontakta oss gärna om du har några eventuella frågor.",
     "Regards": "Hälsningar",
@@ -93,7 +93,7 @@
     "Getting started!": "Kom igång!",
     "Welcome to our dashboard": "Welcome to our dashboard",
     "Verification": "Verification",
-    "You can verify your e-mail address and link\/verify your Discord account.": "You can verify your e-mail address and link\/verify your Discord account.",
+    "You can verify your e-mail address and link/verify your Discord account.": "You can verify your e-mail address and link/verify your Discord account.",
     "Information": "Information",
     "This dashboard can be used to create and delete servers": "This dashboard can be used to create and delete servers",
     "These servers can be used and managed on our pterodactyl panel": "These servers can be used and managed on our pterodactyl panel",
@@ -187,7 +187,7 @@
     "Default language": "Förvalt språk",
     "The fallback Language, if something goes wrong": "Reservspråket, om något går fel",
     "Datable language": "Daterbart språk",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Datatabellernas språkkod. <br><strong>Exempel:<\/strong> en-gb, fr_fr, de_de<br>Mer information: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Datatabellernas språkkod. <br><strong>Exempel:</strong> en-gb, fr_fr, de_de<br>Mer information: ",
     "Auto-translate": "Auto-översätt",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
     "Client Language-Switch": "Client Language-Switch",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
     "Credits Display Name": "Credits Display Name",
     "PHPMyAdmin URL": "PHPMyAdmin URL",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl URL": "Pterodactyl URL",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Key",
     "Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
     "Force Discord verification": "Force Discord verification",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
     "Max": "Max",
     "Expires at": "Expires at",
-    "Used \/ Uses": "Used \/ Uses",
+    "Used / Uses": "Used / Uses",
     "Expires": "Expires",
     "Sign in to start your session": "Sign in to start your session",
     "Password": "Password",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "No nodes have been linked!",
     "No nests available!": "No nests available!",
     "No eggs have been linked!": "No eggs have been linked!",
-    "Software \/ Games": "Software \/ Games",
+    "Software / Games": "Software / Games",
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
@@ -447,6 +447,8 @@
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
     "cs": "Czech",
     "de": "German",
     "en": "English",
diff --git a/lang/tr.json b/lang/tr.json
index f712fd680..7d34213fc 100644
--- a/lang/tr.json
+++ b/lang/tr.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "Birileri senin kodunu kullanarak kayıt oldu!",
     "Server Creation Error": "Sunucu Oluşturma Hatası",
     "Your servers have been suspended!": "Sunucularınız askıya alındı!",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "Sunucularınızı\/sunucularınızı otomatik olarak yeniden etkinleştirmek için daha fazla kredi satın almanız gerekir.",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "Sunucularınızı/sunucularınızı otomatik olarak yeniden etkinleştirmek için daha fazla kredi satın almanız gerekir.",
     "Purchase credits": "Satın alma kredisi",
     "If you have any questions please let us know.": "Herhangi bir sorunuz varsa lütfen bize bildirin.",
     "Regards": "Saygılarımızla",
@@ -93,7 +93,7 @@
     "Getting started!": "Başlarken!",
     "Welcome to our dashboard": "Kontrol panelimize hoş geldiniz",
     "Verification": "Doğrulama",
-    "You can verify your e-mail address and link\/verify your Discord account.": "E-posta adresinizi doğrulayabilir ve Discord hesabınızı bağlayabilir\/doğrulayabilirsiniz.",
+    "You can verify your e-mail address and link/verify your Discord account.": "E-posta adresinizi doğrulayabilir ve Discord hesabınızı bağlayabilir/doğrulayabilirsiniz.",
     "Information": "Bilgi",
     "This dashboard can be used to create and delete servers": "Bu gösterge panosu, sunucular oluşturmak ve silmek için kullanılabilir",
     "These servers can be used and managed on our pterodactyl panel": "Bu sunucular pterodactyl panelimizde kullanılabilir ve yönetilebilir",
@@ -187,7 +187,7 @@
     "Default language": "Varsayılan Dil",
     "The fallback Language, if something goes wrong": "Yedek dil, eğer bir şeyler yanlış giderse",
     "Datable language": "Tarih Dili",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Tarihlerde kullanılacak dil kodu. <br><strong>Örnek:<\/strong> en-gb, fr_fr, de_de<br> Daha fazla bilgi: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "Tarihlerde kullanılacak dil kodu. <br><strong>Örnek:</strong> en-gb, fr_fr, de_de<br> Daha fazla bilgi: ",
     "Auto-translate": "Otomatik çeviri",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "Eğer bu seçili ise Yönetim paneli kendisini kullanıcının diline çevirecek, eğer kullanılabiliyorsa",
     "Client Language-Switch": "Müşteri Dil Değiştiricisi",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "Kullanıcı sunucu oluşturduğumda ilk saatin ödemesini direkt olarak alır.",
     "Credits Display Name": "Kredi ismi",
     "PHPMyAdmin URL": "PHPMyAdmin linki",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "PHPMyAdmin kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "PHPMyAdmin kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan</strong>",
     "Pterodactyl URL": "Pterodactyl Linki",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Pterodactyl kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "Pterodactyl kurulumunuzun linkini girin <strong> Sonda eğik çizgi olmadan!</strong>",
     "Pterodactyl API Key": "Pterodactyl API Anahtarı",
     "Enter the API Key to your Pterodactyl installation.": "Pterodactyl kurulumunuzun API anahtarını girin.",
     "Force Discord verification": "Discord Doğrulamasını zorunlu yap",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Bir kupon, kullanıcı başına yalnızca bir kez kullanılabilir. Kullanımlar, bu kuponu kullanabilecek farklı kullanıcıların sayısını belirtir.",
     "Max": "Maks",
     "Expires at": "Sona eriyor",
-    "Used \/ Uses": "Kullanılmış \/ Kullanım Alanları",
+    "Used / Uses": "Kullanılmış / Kullanım Alanları",
     "Expires": "Sona eriyor",
     "Sign in to start your session": "Oturumunuzu başlatmak için oturum açın",
     "Password": "Parola",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "Hiçbir makine bağlanmamış!",
     "No nests available!": "Hiçbir nest bulunamadı!",
     "No eggs have been linked!": "Hiçbir egg bağlanmamış!",
-    "Software \/ Games": "Yazılımlar \/ Oyunlar",
+    "Software / Games": "Yazılımlar / Oyunlar",
     "Please select software ...": "Lütfen bir yazılım seçin ...",
     "---": "---",
     "Specification ": "Özellikler ",
@@ -447,6 +447,8 @@
     "Notes": "Notlar",
     "Amount in words": "Yazı ile Tutar",
     "Please pay until": "Lütfen şu tarihe kadar ödeyin",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Sunucunuzu yükseltmek / düşürmek faturalandırma döngünüzü şimdiye sıfırlayacaktır. Aşırı ödenen kredileriniz iade edilecektir. Yeni faturalandırma döngüsü için ödenen tutar çekilecektir",
+    "Caution": "Dikkat",
     "cs": "Çekçe",
     "de": "Almanca",
     "en": "İngilizce",
diff --git a/lang/zh.json b/lang/zh.json
index 0e665123e..907ed1695 100644
--- a/lang/zh.json
+++ b/lang/zh.json
@@ -81,7 +81,7 @@
     "Someone registered using your Code!": "已经有人使用您的代码注册了",
     "Server Creation Error": "服务器创建错误",
     "Your servers have been suspended!": "您的服务器已被暂停",
-    "To automatically re-enable your server\/s, you need to purchase more credits.": "如需重新启用你的服务器,您需要购买更多的余额",
+    "To automatically re-enable your server/s, you need to purchase more credits.": "如需重新启用你的服务器,您需要购买更多的余额",
     "Purchase credits": "购买余额",
     "If you have any questions please let us know.": "如果您有其他任何问题,欢迎联系我们。",
     "Regards": "此致",
@@ -93,7 +93,7 @@
     "Getting started!": "开始吧!",
     "Welcome to our dashboard": "欢迎访问 dashboard",
     "Verification": "验证",
-    "You can verify your e-mail address and link\/verify your Discord account.": "你可以验证你的邮箱地址或者连接到你的Discord账户",
+    "You can verify your e-mail address and link/verify your Discord account.": "你可以验证你的邮箱地址或者连接到你的Discord账户",
     "Information": "相关信息",
     "This dashboard can be used to create and delete servers": "此仪表板可用于创建和删除服务器",
     "These servers can be used and managed on our pterodactyl panel": "这些服务器可以在我们的pterodactyl面板上使用和管理",
@@ -187,7 +187,7 @@
     "Default language": "默认语言",
     "The fallback Language, if something goes wrong": "备用语言",
     "Datable language": "可用语言",
-    "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "数据表语言代码 <br><strong>示例:<\/strong> en-gb、fr_fr、de_de<br> 更多信息: ",
+    "The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ": "数据表语言代码 <br><strong>示例:</strong> en-gb、fr_fr、de_de<br> 更多信息: ",
     "Auto-translate": "自动翻译",
     "If this is checked, the Dashboard will translate itself to the Clients language, if available": "如果勾选此项,系统将把自己翻译成客户语言(如果有)",
     "Client Language-Switch": "客户语言切换",
@@ -243,9 +243,9 @@
     "Charges the first hour worth of credits upon creating a server.": "在创建服务器时收取第一个小时的费用",
     "Credits Display Name": "积分显示名称",
     "PHPMyAdmin URL": "PHPMyAdmin地址",
-    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "输入你PHPMyAdmin的URL。<strong>不要有尾部斜线!<\/strong>",
+    "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>": "输入你PHPMyAdmin的URL。<strong>不要有尾部斜线!</strong>",
     "Pterodactyl URL": "Pterodactyl地址",
-    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "输入你Pterodactyl的URL。<strong>不要有尾部斜线!<\/strong>",
+    "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>": "输入你Pterodactyl的URL。<strong>不要有尾部斜线!</strong>",
     "Pterodactyl API Key": "Pterodactyl API密钥",
     "Enter the API Key to your Pterodactyl installation.": "输入Pterodactyl API密钥",
     "Force Discord verification": "强制Discord验证",
@@ -316,7 +316,7 @@
     "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "每个用户只能使用一次代金券。使用次数指定了可以使用此代金券的不同用户的数量。",
     "Max": "最大",
     "Expires at": "过期时间",
-    "Used \/ Uses": "已使用\/使用情况",
+    "Used / Uses": "已使用/使用情况",
     "Expires": "过期",
     "Sign in to start your session": "登录以开始您的会议",
     "Password": "密码",
@@ -388,7 +388,7 @@
     "No nodes have been linked!": "没有节点被链接!",
     "No nests available!": "没有可用的巢穴!",
     "No eggs have been linked!": "没有蛋被链接!",
-    "Software \/ Games": "软件\/游戏",
+    "Software / Games": "软件/游戏",
     "Please select software ...": "请选择软件...",
     "---": "---",
     "Specification ": "规格 ",
@@ -447,6 +447,8 @@
     "Notes": "笔记",
     "Amount in words": "税额的字数",
     "Please pay until": "请支付至",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "升级/降级你的服务器将重置你的账单周期。你的多余的点数将被退还。新的账单周期的价格将被扣除",
+    "Caution": "警告",
     "cs": "捷克语",
     "de": "德语",
     "en": "英语",

From 27d2a48e10e9e9a4e54677cea6db1b4a7cda1f63 Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Mon, 19 Dec 2022 15:08:09 +0100
Subject: [PATCH 092/514] chore: doc

---
 Addon-notes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Addon-notes.md b/Addon-notes.md
index bed6f5a2e..ac00939be 100644
--- a/Addon-notes.md
+++ b/Addon-notes.md
@@ -1,4 +1,4 @@
 Export diff files:
 Commit Hash of lates Main commit
 
-git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf ../controllpanelgg-monthly-addon/file.tgz -T -
+git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf \.\./controllpanelgg-monthly-addon/file.tgz -T -

From fda40fe8bcd34d762017036beea15971c57af6eb Mon Sep 17 00:00:00 2001
From: IceToast <>
Date: Mon, 23 Jan 2023 16:27:32 +0100
Subject: [PATCH 093/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Merge=20missing?=
 =?UTF-8?q?=20hidden=20product=20in=20form?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/servers/create.blade.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 2a0a3d841..0a91cc046 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -229,7 +229,8 @@ class="custom-select">
                                     </div>
                                     <div class="mt-auto border rounded border-secondary">
                                         <div class="d-flex justify-content-between p-2">
-                                            <span class="d-inline-block mr-4" x-text="'{{ __('Price') }}' + ' (' + product.billing_period + ')'">
+                                            <span class="d-inline-block mr-4"
+                                                x-text="'{{ __('Price') }}' + ' (' + product.billing_period + ')'">
                                             </span>
                                             <span class="d-inline-block"
                                                 x-text="product.price + ' {{ CREDITS_DISPLAY_NAME }}'"></span>
@@ -250,13 +251,12 @@ class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
                                     </div>
                                 </div>
                             </div>
+                        </template>
                     </div>
-                    </template>
                 </div>
-        </div>
 
-        </form>
-        <!-- END FORM -->
+            </form>
+            <!-- END FORM -->
 
         </div>
     </section>

From 255671e20da007c7f6a5fed7d2d53b16062a8b79 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 6 Feb 2023 14:45:44 +0100
Subject: [PATCH 094/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Merge=20issues?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php     |  50 ++-
 app/Models/User.php                           |  13 +-
 resources/views/servers/index.blade.php       | 295 ----------------
 themes/default/views/servers/create.blade.php |  22 +-
 themes/default/views/servers/index.blade.php  | 324 +++++++++++++-----
 5 files changed, 269 insertions(+), 435 deletions(-)
 delete mode 100644 resources/views/servers/index.blade.php

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 61ac4218a..8822ad3ab 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -33,7 +33,7 @@ public function index()
 
             //Get server infos from ptero
             $serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id, true);
-            if (! $serverAttributes) {
+            if (!$serverAttributes) {
                 continue;
             }
             $serverRelationships = $serverAttributes['relationships'];
@@ -70,7 +70,7 @@ public function index()
     /** Show the form for creating a new resource. */
     public function create()
     {
-        if (! is_null($this->validateConfigurationRules())) {
+        if (!is_null($this->validateConfigurationRules())) {
             return $this->validateConfigurationRules();
         }
 
@@ -125,7 +125,7 @@ private function validateConfigurationRules()
             // Check if node has enough memory and disk space
             $checkResponse = Pterodactyl::checkNodeResources($node, $product->memory, $product->disk);
             if ($checkResponse == false) {
-                return redirect()->route('servers.index')->with('error', __("The node '".$nodeName."' doesn't have the required memory or disk left to allocate this product."));
+                return redirect()->route('servers.index')->with('error', __("The node '" . $nodeName . "' doesn't have the required memory or disk left to allocate this product."));
             }
 
             // Min. Credits
@@ -133,23 +133,23 @@ private function validateConfigurationRules()
                 Auth::user()->credits < $product->minimum_credits ||
                 Auth::user()->credits < $product->price
             ) {
-                return redirect()->route('servers.index')->with('error', 'You do not have the required amount of '.CREDITS_DISPLAY_NAME.' to use this product!');
+                return redirect()->route('servers.index')->with('error', 'You do not have the required amount of ' . CREDITS_DISPLAY_NAME . ' to use this product!');
             }
         }
 
         //Required Verification for creating an server
-        if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', 'false') === 'true' && ! Auth::user()->hasVerifiedEmail()) {
+        if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', 'false') === 'true' && !Auth::user()->hasVerifiedEmail()) {
             return redirect()->route('profile.index')->with('error', __('You are required to verify your email address before you can create a server.'));
         }
 
         //Required Verification for creating an server
 
-        if (! config('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS', 'true') && Auth::user()->role != 'admin') {
+        if (!config('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS', 'true') && Auth::user()->role != 'admin') {
             return redirect()->route('servers.index')->with('error', __('The system administrator has blocked the creation of new servers.'));
         }
 
         //Required Verification for creating an server
-        if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', 'false') === 'true' && ! Auth::user()->discordUser) {
+        if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', 'false') === 'true' && !Auth::user()->discordUser) {
             return redirect()->route('profile.index')->with('error', __('You are required to link your discord account before you can create a server.'));
         }
 
@@ -162,7 +162,7 @@ public function store(Request $request)
         /** @var Node $node */
         /** @var Egg $egg */
         /** @var Product $product */
-        if (! is_null($this->validateConfigurationRules())) {
+        if (!is_null($this->validateConfigurationRules())) {
             return $this->validateConfigurationRules();
         }
 
@@ -186,7 +186,7 @@ public function store(Request $request)
 
         //get free allocation ID
         $allocationId = Pterodactyl::getFreeAllocationId($node);
-        if (! $allocationId) {
+        if (!$allocationId) {
             return $this->noAllocationsError($server);
         }
 
@@ -249,13 +249,9 @@ public function destroy(Server $server)
     }
 
     /** Cancel Server */
-    public function cancel (Server $server)
+    public function cancel(Server $server)
     {
         try {
-            error_log($server->update([
-                'cancelled' => now(),
-            ]));
-
             return redirect()->route('servers.index')->with('success', __('Server cancelled'));
         } catch (Exception $e) {
             return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
@@ -267,7 +263,9 @@ public function show(Server $server)
     {
 
 
-        if($server->user_id != Auth::user()->id){ return back()->with('error', __('This is not your Server!'));}
+        if ($server->user_id != Auth::user()->id) {
+            return back()->with('error', __('This is not your Server!'));
+        }
         $serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
         $serverRelationships = $serverAttributes['relationships'];
         $serverLocationAttributes = $serverRelationships['location']['attributes'];
@@ -287,10 +285,10 @@ public function show(Server $server)
         $pteroNode = Pterodactyl::getNode($serverRelationships['node']['attributes']['id']);
 
         $products = Product::orderBy('created_at')
-        ->whereHas('nodes', function (Builder $builder) use ($serverRelationships) { //Only show products for that node
-            $builder->where('id', '=', $serverRelationships['node']['attributes']['id']);
-        })
-        ->get();
+            ->whereHas('nodes', function (Builder $builder) use ($serverRelationships) { //Only show products for that node
+                $builder->where('id', '=', $serverRelationships['node']['attributes']['id']);
+            })
+            ->get();
 
         // Set the each product eggs array to just contain the eggs name
         foreach ($products as $product) {
@@ -308,9 +306,8 @@ public function show(Server $server)
 
     public function upgrade(Server $server, Request $request)
     {
-        if($server->user_id != Auth::user()->id || $server->suspended) return redirect()->route('servers.index');
-        if(!isset($request->product_upgrade))
-        {
+        if ($server->user_id != Auth::user()->id || $server->suspended) return redirect()->route('servers.index');
+        if (!isset($request->product_upgrade)) {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('this product is the only one'));
         }
         $user = Auth::user();
@@ -329,7 +326,7 @@ public function upgrade(Server $server, Request $request)
         $requiredisk = $newProduct->disk - $oldProduct->disk;
         $checkResponse = Pterodactyl::checkNodeResources($node, $requireMemory, $requiredisk);
         if ($checkResponse == false) {
-            return redirect()->route('servers.index')->with('error', __("The node '".$nodeName."' doesn't have the required memory or disk left to upgrade the server."));
+            return redirect()->route('servers.index')->with('error', __("The node '" . $nodeName . "' doesn't have the required memory or disk left to upgrade the server."));
         }
 
         // calculate the amount of credits that the user overpayed for the old product when canceling the server right now
@@ -353,8 +350,7 @@ public function upgrade(Server $server, Request $request)
         $overpayedCredits = $oldProduct->price - $oldProduct->price * ($timeDifference / $billingPeriodMultiplier);
 
 
-        if ($user->credits >= $newProduct->price && $user->credits >= $newProduct->minimum_credits)
-        {
+        if ($user->credits >= $newProduct->price && $user->credits >= $newProduct->minimum_credits) {
             $server->allocation = $serverAttributes['allocation'];
             // Update the server on the panel
             $response = Pterodactyl::updateServer($server, $newProduct);
@@ -374,11 +370,11 @@ public function upgrade(Server $server, Request $request)
             if ($overpayedCredits > 0) $user->increment('credits', $overpayedCredits);
 
             // Withdraw the credits for the new product
-            $user->decrement('credits', $newProduct->price); 
+            $user->decrement('credits', $newProduct->price);
 
             //restart the server
             $response = Pterodactyl::powerAction($server, "restart");
-            if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   '.$response->json()['errors'][0]['detail']);
+            if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   ' . $response->json()['errors'][0]['detail']);
             return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
         } else {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('Not Enough Balance for Upgrade'));
diff --git a/app/Models/User.php b/app/Models/User.php
index 91e15cab3..199bb25d2 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -185,7 +185,7 @@ public function isSuspended()
     }
 
     /**
-     * @throws Exception
+     * @throws \Exception
      */
     public function suspend()
     {
@@ -201,7 +201,7 @@ public function suspend()
     }
 
     /**
-     * @throws Exception
+     * @throws \Exception
      */
     public function unSuspend()
     {
@@ -218,12 +218,6 @@ public function unSuspend()
         return $this;
     }
 
-    private function getServersWithProduct()
-    {
-        return $this->servers()
-            ->with('product')
-            ->get();
-    }
 
     /**
      * @return string
@@ -257,7 +251,8 @@ public function creditUsage()
         return number_format($usage, 2, '.', '');
     }
 
-    private function getServersWithProduct() {
+    private function getServersWithProduct()
+    {
         return $this->servers()
             ->whereNull('suspended')
             ->whereNull('cancelled')
diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php
deleted file mode 100644
index 7910a30af..000000000
--- a/resources/views/servers/index.blade.php
+++ /dev/null
@@ -1,295 +0,0 @@
-@extends('layouts.main')
-
-@section('content')
-    <!-- CONTENT HEADER -->
-    <section class="content-header">
-        <div class="container-fluid">
-            <div class="row mb-2">
-                <div class="col-sm-6">
-                    <h1>{{ __('Servers') }}</h1>
-                </div>
-                <div class="col-sm-6">
-                    <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted"
-                                href="{{ route('servers.index') }}">{{ __('Servers') }}</a>
-                        </li>
-                    </ol>
-                </div>
-            </div>
-        </div>
-    </section>
-    <!-- END CONTENT HEADER -->
-
-    <!-- MAIN CONTENT -->
-    <section class="content">
-        <div class="container-fluid">
-
-            <!-- CUSTOM CONTENT -->
-            <div class="d-flex justify-content-md-start justify-content-center mb-3 ">
-                <a @if (Auth::user()->Servers->count() >= Auth::user()->server_limit)
-                    disabled="disabled" title="Server limit reached!"
-                    @endif href="{{ route('servers.create') }}"
-                    class="btn
-                    @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled
-                    @endif btn-primary"><i
-                        class="fa fa-plus mr-2"></i>
-                    {{ __('Create Server') }}
-                </a>
-            </div>
-
-            <div class="row d-flex flex-row justify-content-center justify-content-md-start">
-                @foreach ($servers as $server)
-                    <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
-                        style="max-width: 350px">
-                        <div class="card-header">
-                            <div class="d-flex justify-content-between align-items-center">
-                                <h5 class="card-title mt-1">{{ $server->name }}
-                                </h5>
-                                <div class="card-tools mt-1">
-                                    <div class="dropdown no-arrow">
-                                        <a href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown"
-                                            aria-haspopup="true" aria-expanded="false">
-                                            <i class="fas fa-ellipsis-v fa-sm fa-fw text-white-50"></i>
-                                        </a>
-                                        <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
-                                            aria-labelledby="dropdownMenuLink">
-                                            @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
-                                                <a href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
-                                                    class="dropdown-item text-info" target="__blank"><i title="manage"
-                                                        class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
-                                            @endif
-                                            <div class="dropdown-divider"></div>
-                                            <span class="dropdown-item"><i title="Created at"
-                                                    class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }}</span></span>
-                                        </div>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="card-body">
-                            <div class="container mt-1">
-                                <div class="row mb-3">
-                                    <div class="col my-auto">{{ __('Status') }}:</div>
-                                    <div class="col-7 my-auto">
-                                        @if($server->suspended)
-                                            <span class="badge badge-danger">{{ __('Suspended') }}</span>
-                                        @elseif($server->cancelled)
-                                            <span class="badge badge-warning">{{ __('Cancelled') }}</span>
-                                        @else
-                                            <span class="badge badge-success">{{ __('Active') }}</span>
-                                        @endif
-                                    </div>
-                                </div>
-                                <div class="row mb-2">
-                                    <div class="col-5">
-                                        {{ __('Location') }}:
-                                    </div>
-                                    <div class="col-7 d-flex justify-content-between align-items-center">
-                                        <span class="">{{ $server->location }}</span>
-                                        <i data-toggle="popover" data-trigger="hover"
-                                            data-content="{{ __('Node') }}: {{ $server->node }}"
-                                            class="fas fa-info-circle"></i>
-                                    </div>
-
-                                </div>
-                                <div class="row mb-2">
-                                    <div class="col-5 ">
-                                        {{ __('Software') }}:
-                                    </div>
-                                    <div class="col-7 text-wrap">
-                                        <span>{{ $server->nest }}</span>
-                                    </div>
-
-                                </div>
-                                <div class="row mb-2">
-                                    <div class="col-5 ">
-                                        {{ __('Specification') }}:
-                                    </div>
-                                    <div class="col-7 text-wrap">
-                                        <span>{{ $server->egg }}</span>
-                                    </div>
-                                </div>
-                                <div class="row mb-2">
-                                    <div class="col-5 ">
-                                        {{ __('Resource plan') }}:
-                                    </div>
-                                    <div class="col-7 text-wrap d-flex justify-content-between align-items-center">
-                                        <span>{{ $server->product->name }}
-                                        </span>
-                                        <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
-                                            class="fas fa-info-circle"></i>
-                                    </div>
-                                </div>
-
-                                <div class="row mb-4 ">
-                                    <div class="col-5 word-break" style="hyphens: auto">
-                                        {{ __('Next Billing Cycle') }}:
-                                    </div>
-                                    <div class="col-7 d-flex text-wrap align-items-center">
-                                        <span>
-                                        @if ($server->suspended)
-                                            -
-                                        @else
-                                            @switch($server->product->billing_period)
-                                                @case('monthly')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
-                                                    @break
-                                                @case('weekly')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
-                                                    @break
-                                                @case('daily')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
-                                                    @break
-                                                @case('hourly')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
-                                                    @break
-                                                @case('quarterly')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(3)->toDayDateTimeString(); }}
-                                                    @break
-                                                @case('half-annually')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
-                                                    @break
-                                                @case('annually')
-                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
-                                                    @break
-                                                @default
-                                                    {{ __('Unknown') }}
-                                            @endswitch
-                                        @endif
-                                        </span>
-                                    </div>
-                                </div>
-
-                                <div class="row mb-2">
-                                    <div class="col-4">
-                                        {{ __('Price') }}:
-                                        <span class="text-muted">
-                                            ({{ CREDITS_DISPLAY_NAME }})
-                                        </span>
-                                    </div>
-                                    <div class="col-8 text-center">
-                                        <div class="text-muted">
-                                        @if($server->product->billing_period == 'monthly')
-                                            {{ __('per Month') }}
-                                        @elseif($server->product->billing_period == 'half-annually')
-                                            {{ __('per 6 Months') }}
-                                        @elseif($server->product->billing_period == 'quarterly')
-                                            {{ __('per 3 Months') }}
-                                        @elseif($server->product->billing_period == 'annually')
-                                            {{ __('per Year') }}
-                                        @elseif($server->product->billing_period == 'weekly')
-                                            {{ __('per Week') }}
-                                        @elseif($server->product->billing_period == 'daily')
-                                            {{ __('per Day') }}
-                                        @elseif($server->product->billing_period == 'hourly')
-                                            {{ __('per Hour') }}
-                                        @endif
-                                            </div>
-                                        <span>
-                                            {{ $server->product->price == round($server->product->price) ? round($server->product->price) : $server->product->price }}
-                                        </span>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="card-footer text-center">
-                            <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
-                                target="__blank"
-                                class="btn btn-info text-center float-left ml-2"
-                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
-                                <i class="fas fa-tools mx-2"></i>
-                            </a>
-                            @if(config("SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN"))
-                            <a href="{{ route('servers.show', ['server' => $server->id])}}"
-                            	class="btn btn-info text-center mr-3"
-                            	data-toggle="tooltip" data-placement="bottom" title="{{ __('Server Settings') }}">
-                                <i class="fas fa-cog mx-2"></i>
-                            </a>
-                            @endif
-                            <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
-                                class="btn btn-warning  text-center"
-                                {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
-                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
-                                <i class="fas fa-ban mx-2"></i>
-                            </button>
-                            <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
-                                class="btn btn-danger  text-center float-right mr-2"
-                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
-                                <i class="fas fa-trash mx-2"></i>
-                            </button>
-                        </div>
-                    </div>
-                @endforeach
-            </div>
-            <!-- END CUSTOM CONTENT -->
-        </div>
-    </section>
-    <!-- END CONTENT -->
-
-    <script>
-        const handleServerCancel = (serverId) => {
-            // Handle server cancel with sweetalert
-            Swal.fire({
-                title: "{{ __('Cancel Server?') }}",
-                text: "{{ __('This will cancel your current server to the next billing period. It will get suspended when the current period runs out.') }}",
-                icon: 'warning',
-                confirmButtonColor: '#d9534f',
-                showCancelButton: true,
-                confirmButtonText: "{{ __('Yes, cancel it!') }}",
-                cancelButtonText: "{{ __('No, abort!') }}",
-                reverseButtons: true
-            }).then((result) => {
-                if (result.value) {
-                    // Delete server
-                    fetch("{{ route('servers.cancel', '') }}" + '/' + serverId, {
-                        method: 'PATCH',
-                        headers: {
-                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
-                        }
-                    }).then(() => {
-                        window.location.reload();
-                    });
-                    return
-                }
-            })
-        }
-
-        const handleServerDelete = (serverId) => {
-            Swal.fire({
-                title: "{{ __('Delete Server?') }}",
-                html: "{{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}}",
-                icon: 'warning',
-                confirmButtonColor: '#d9534f',
-                showCancelButton: true,
-                confirmButtonText: "{{ __('Yes, delete it!') }}",
-                cancelButtonText: "{{ __('No, abort!') }}",
-                reverseButtons: true
-            }).then((result) => {
-                if (result.value) {
-                    // Delete server
-                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
-                        method: 'DELETE',
-                        headers: {
-                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
-                        }
-                    }).then(() => {
-                        window.location.reload();
-                    });
-                    return
-                }
-            });
-
-        }
-
-        document.addEventListener('DOMContentLoaded', () => {
-            $('[data-toggle="popover"]').popover();
-        });
-
-        $(function () {
-            $('[data-toggle="tooltip"]').tooltip()
-        })
-    </script>
-@endsection
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 0a91cc046..ec18ebfe4 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -213,11 +213,11 @@ class="custom-select">
 
                                                     <span class="d-inline-block" x-text="product.billing_period"></span>
                                                 </li>
-                                                <li>
+                                                <li class="d-flex justify-content-between">
                                                     <span class="d-inline-block"><i class="fa fa-coins"></i>
                                                         {{ __('Minimum') }} {{ CREDITS_DISPLAY_NAME }}</span>
                                                     <span class="d-inline-block"
-                                                        x-text="product.minimum_credits == -1 ? {{ config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER') }} : product.minimum_credits"></span>
+                                                        x-text="product.minimum_credits == -1 ? {{ config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER') }} : Math.round(product.minimum_credits)"></span>
                                                 </li>
                                             </ul>
                                         </div>
@@ -240,14 +240,16 @@ class="custom-select">
                                         <input type="hidden" name="product" x-model="selectedProduct">
                                     </div>
                                     <div>
-										<button type="submit" x-model="selectedProduct" name="product"
-        									:disabled="product.minimum_credits > user.credits || product.price > user.credits || product.doesNotFit == true ||
-            									submitClicked"
-       										:class="product.minimum_credits > user.credits || product.price > user.credits || product.doesNotFit == true ||
-            									submitClicked ? 'disabled' : ''"
-        									class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
-        									x-text="product.doesNotFit == true ? '{{ __('Server cant fit on this Node') }}' : (product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}')">
-    									</button>
+                                        <button type="submit" x-model="selectedProduct" name="product"
+                                            :disabled="product.minimum_credits > user.credits || product.price > user.credits ||
+                                                product.doesNotFit == true ||
+                                                submitClicked"
+                                            :class="product.minimum_credits > user.credits || product.price > user.credits ||
+                                                product.doesNotFit == true ||
+                                                submitClicked ? 'disabled' : ''"
+                                            class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
+                                            x-text="product.doesNotFit == true ? '{{ __('Server cant fit on this Node') }}' : (product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : '{{ __('Create server') }}')">
+                                        </button>
                                     </div>
                                 </div>
                             </div>
diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index ef856b6a0..7910a30af 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -36,124 +36,260 @@ class="btn
                         class="fa fa-plus mr-2"></i>
                     {{ __('Create Server') }}
                 </a>
-                @if (Auth::user()->Servers->count() > 0&&!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
-                    <a 
-                        href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}" target="_blank"
-                        class="btn btn-secondary ml-2"><i title="manage"
-                        class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span>
-                    </a>
-                @endif
             </div>
 
             <div class="row d-flex flex-row justify-content-center justify-content-md-start">
                 @foreach ($servers as $server)
-                    @if($server->location&&$server->node&&$server->nest&&$server->egg)
-                        <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
-                            style="max-width: 350px">
-                            <div class="card-header">
-                                <div class="d-flex justify-content-between align-items-center">
-                                    <h5 class="card-title mt-1">{{ $server->name }}
-                                    </h5>
+                    <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
+                        style="max-width: 350px">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between align-items-center">
+                                <h5 class="card-title mt-1">{{ $server->name }}
+                                </h5>
+                                <div class="card-tools mt-1">
+                                    <div class="dropdown no-arrow">
+                                        <a href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown"
+                                            aria-haspopup="true" aria-expanded="false">
+                                            <i class="fas fa-ellipsis-v fa-sm fa-fw text-white-50"></i>
+                                        </a>
+                                        <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
+                                            aria-labelledby="dropdownMenuLink">
+                                            @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
+                                                <a href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
+                                                    class="dropdown-item text-info" target="__blank"><i title="manage"
+                                                        class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
+                                            @endif
+                                            <div class="dropdown-divider"></div>
+                                            <span class="dropdown-item"><i title="Created at"
+                                                    class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }}</span></span>
+                                        </div>
+                                    </div>
                                 </div>
                             </div>
-                            <div class="card-body">
-                                <div class="container mt-1">
-                                    <div class="row mb-3">
-                                        <div class="col my-auto">{{ __('Status') }}:</div>
-                                        <div class="col-7 my-auto">
-                                            <i
-                                                class="fas {{ $server->isSuspended() ? 'text-danger' : 'text-success' }} fa-circle mr-2"></i>
-                                            {{ $server->isSuspended() ? 'Suspended' : 'Active' }}
-                                        </div>
+                        </div>
+                        <div class="card-body">
+                            <div class="container mt-1">
+                                <div class="row mb-3">
+                                    <div class="col my-auto">{{ __('Status') }}:</div>
+                                    <div class="col-7 my-auto">
+                                        @if($server->suspended)
+                                            <span class="badge badge-danger">{{ __('Suspended') }}</span>
+                                        @elseif($server->cancelled)
+                                            <span class="badge badge-warning">{{ __('Cancelled') }}</span>
+                                        @else
+                                            <span class="badge badge-success">{{ __('Active') }}</span>
+                                        @endif
+                                    </div>
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5">
+                                        {{ __('Location') }}:
+                                    </div>
+                                    <div class="col-7 d-flex justify-content-between align-items-center">
+                                        <span class="">{{ $server->location }}</span>
+                                        <i data-toggle="popover" data-trigger="hover"
+                                            data-content="{{ __('Node') }}: {{ $server->node }}"
+                                            class="fas fa-info-circle"></i>
                                     </div>
-                                    <div class="row mb-2">
-                                        <div class="col-5">
-                                            {{ __('Location') }}:
-                                        </div>
-                                        <div class="col-7 d-flex justify-content-between align-items-center">
-                                            <span class="">{{ $server->location }}</span>
-                                            <i data-toggle="popover" data-trigger="hover"
-                                                data-content="{{ __('Node') }}: {{ $server->node }}"
-                                                class="fas fa-info-circle"></i>
-                                        </div>
 
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5 ">
+                                        {{ __('Software') }}:
+                                    </div>
+                                    <div class="col-7 text-wrap">
+                                        <span>{{ $server->nest }}</span>
                                     </div>
-                                    <div class="row mb-2">
-                                        <div class="col-5 ">
-                                            {{ __('Software') }}:
-                                        </div>
-                                        <div class="col-7 text-wrap">
-                                            <span>{{ $server->nest }}</span>
-                                        </div>
 
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5 ">
+                                        {{ __('Specification') }}:
                                     </div>
-                                    <div class="row mb-2">
-                                        <div class="col-5 ">
-                                            {{ __('Specification') }}:
-                                        </div>
-                                        <div class="col-7 text-wrap">
-                                            <span>{{ $server->egg }}</span>
-                                        </div>
+                                    <div class="col-7 text-wrap">
+                                        <span>{{ $server->egg }}</span>
                                     </div>
-                                    <div class="row mb-4">
-                                        <div class="col-5 ">
-                                            {{ __('Resource plan') }}:
-                                        </div>
-                                        <div class="col-7 text-wrap d-flex justify-content-between align-items-center">
-                                            <span>{{ $server->product->name }}
-                                            </span>
-                                            <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                                data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>"
-                                                class="fas fa-info-circle"></i>
-                                        </div>
+                                </div>
+                                <div class="row mb-2">
+                                    <div class="col-5 ">
+                                        {{ __('Resource plan') }}:
+                                    </div>
+                                    <div class="col-7 text-wrap d-flex justify-content-between align-items-center">
+                                        <span>{{ $server->product->name }}
+                                        </span>
+                                        <i data-toggle="popover" data-trigger="hover" data-html="true"
+                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
+                                            class="fas fa-info-circle"></i>
+                                    </div>
+                                </div>
 
+                                <div class="row mb-4 ">
+                                    <div class="col-5 word-break" style="hyphens: auto">
+                                        {{ __('Next Billing Cycle') }}:
                                     </div>
-                                    <div class="row mb-2">
-                                        <div class="col-4">
-                                            {{ __('Price') }}:
-                                            <span class="text-muted">
-                                                ({{ CREDITS_DISPLAY_NAME }})
-                                            </span>
-                                        </div>
-                                        <div class="col-8">
-                                            <div class="row">
-                                                <div class="col-6  text-center">
-                                                    <div class="text-muted">{{ __('per Hour') }}</div>
-                                                    <span>
-                                                        {{ number_format($server->product->getHourlyPrice(), 2, '.', '') }}
-                                                    </span>
-                                                </div>
-                                                <div class="col-6  text-center">
-                                                    <div class="text-muted">{{ __('per Month') }}
-                                                    </div>
-                                                    <span>
-                                                        {{ $server->product->getHourlyPrice() * 24 * 30 }}
-                                                    </span>
-                                                </div>
+                                    <div class="col-7 d-flex text-wrap align-items-center">
+                                        <span>
+                                        @if ($server->suspended)
+                                            -
+                                        @else
+                                            @switch($server->product->billing_period)
+                                                @case('monthly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('weekly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('daily')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('hourly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('quarterly')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(3)->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('half-annually')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
+                                                    @break
+                                                @case('annually')
+                                                    {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
+                                                    @break
+                                                @default
+                                                    {{ __('Unknown') }}
+                                            @endswitch
+                                        @endif
+                                        </span>
+                                    </div>
+                                </div>
+
+                                <div class="row mb-2">
+                                    <div class="col-4">
+                                        {{ __('Price') }}:
+                                        <span class="text-muted">
+                                            ({{ CREDITS_DISPLAY_NAME }})
+                                        </span>
+                                    </div>
+                                    <div class="col-8 text-center">
+                                        <div class="text-muted">
+                                        @if($server->product->billing_period == 'monthly')
+                                            {{ __('per Month') }}
+                                        @elseif($server->product->billing_period == 'half-annually')
+                                            {{ __('per 6 Months') }}
+                                        @elseif($server->product->billing_period == 'quarterly')
+                                            {{ __('per 3 Months') }}
+                                        @elseif($server->product->billing_period == 'annually')
+                                            {{ __('per Year') }}
+                                        @elseif($server->product->billing_period == 'weekly')
+                                            {{ __('per Week') }}
+                                        @elseif($server->product->billing_period == 'daily')
+                                            {{ __('per Day') }}
+                                        @elseif($server->product->billing_period == 'hourly')
+                                            {{ __('per Hour') }}
+                                        @endif
                                             </div>
-                                        </div>
+                                        <span>
+                                            {{ $server->product->price == round($server->product->price) ? round($server->product->price) : $server->product->price }}
+                                        </span>
                                     </div>
                                 </div>
                             </div>
+                        </div>
 
-                            <div class="card-footer d-flex align-items-center justify-content-between">
-                                <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
-                                    target="__blank"
-                                    class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex">
-                                    <i class="fas fa-tools mr-2"></i>
-                                    <span>{{ __('Manage') }}</span>
-                                </a>
-                                <a href="{{ route('servers.show', ['server' => $server->id])}}" class="btn btn-warning mx-3 w-100 align-items-center justify-content-center d-flex">
-                                    <i class="fas fa-cog mr-2"></i>
-                                    <span>{{ __('Settings') }}</span>
-                                </a>
-                            </div>
+                        <div class="card-footer text-center">
+                            <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
+                                target="__blank"
+                                class="btn btn-info text-center float-left ml-2"
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
+                                <i class="fas fa-tools mx-2"></i>
+                            </a>
+                            @if(config("SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN"))
+                            <a href="{{ route('servers.show', ['server' => $server->id])}}"
+                            	class="btn btn-info text-center mr-3"
+                            	data-toggle="tooltip" data-placement="bottom" title="{{ __('Server Settings') }}">
+                                <i class="fas fa-cog mx-2"></i>
+                            </a>
+                            @endif
+                            <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
+                                class="btn btn-warning  text-center"
+                                {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
+                                <i class="fas fa-ban mx-2"></i>
+                            </button>
+                            <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
+                                class="btn btn-danger  text-center float-right mr-2"
+                                data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
+                                <i class="fas fa-trash mx-2"></i>
+                            </button>
                         </div>
-                    @endif
+                    </div>
                 @endforeach
             </div>
             <!-- END CUSTOM CONTENT -->
         </div>
     </section>
     <!-- END CONTENT -->
+
+    <script>
+        const handleServerCancel = (serverId) => {
+            // Handle server cancel with sweetalert
+            Swal.fire({
+                title: "{{ __('Cancel Server?') }}",
+                text: "{{ __('This will cancel your current server to the next billing period. It will get suspended when the current period runs out.') }}",
+                icon: 'warning',
+                confirmButtonColor: '#d9534f',
+                showCancelButton: true,
+                confirmButtonText: "{{ __('Yes, cancel it!') }}",
+                cancelButtonText: "{{ __('No, abort!') }}",
+                reverseButtons: true
+            }).then((result) => {
+                if (result.value) {
+                    // Delete server
+                    fetch("{{ route('servers.cancel', '') }}" + '/' + serverId, {
+                        method: 'PATCH',
+                        headers: {
+                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                        }
+                    }).then(() => {
+                        window.location.reload();
+                    });
+                    return
+                }
+            })
+        }
+
+        const handleServerDelete = (serverId) => {
+            Swal.fire({
+                title: "{{ __('Delete Server?') }}",
+                html: "{{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}}",
+                icon: 'warning',
+                confirmButtonColor: '#d9534f',
+                showCancelButton: true,
+                confirmButtonText: "{{ __('Yes, delete it!') }}",
+                cancelButtonText: "{{ __('No, abort!') }}",
+                reverseButtons: true
+            }).then((result) => {
+                if (result.value) {
+                    // Delete server
+                    fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
+                        method: 'DELETE',
+                        headers: {
+                            'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                        }
+                    }).then(() => {
+                        window.location.reload();
+                    });
+                    return
+                }
+            });
+
+        }
+
+        document.addEventListener('DOMContentLoaded', () => {
+            $('[data-toggle="popover"]').popover();
+        });
+
+        $(function () {
+            $('[data-toggle="tooltip"]').tooltip()
+        })
+    </script>
 @endsection

From 971226ee8e088c37c0780d9fe4b0c22fb9bdc83c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sat, 29 Apr 2023 23:30:35 +0200
Subject: [PATCH 095/514] update composer dependencies

---
 composer.lock | 528 +++++++++++++++++++++++++-------------------------
 1 file changed, 263 insertions(+), 265 deletions(-)

diff --git a/composer.lock b/composer.lock
index b46d1632d..96825a92c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -62,16 +62,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.262.3",
+            "version": "3.269.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "f5c8142d43846194bbb3bb40b18e7f6df2788409"
+                "reference": "6d759ef9f24f0c7f271baf8014f41fc0cfdfbf78"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f5c8142d43846194bbb3bb40b18e7f6df2788409",
-                "reference": "f5c8142d43846194bbb3bb40b18e7f6df2788409",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6d759ef9f24f0c7f271baf8014f41fc0cfdfbf78",
+                "reference": "6d759ef9f24f0c7f271baf8014f41fc0cfdfbf78",
                 "shasum": ""
             },
             "require": {
@@ -81,7 +81,7 @@
                 "ext-simplexml": "*",
                 "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5",
                 "guzzlehttp/promises": "^1.4.0",
-                "guzzlehttp/psr7": "^1.8.5 || ^2.3",
+                "guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
                 "mtdowling/jmespath.php": "^2.6",
                 "php": ">=5.5"
             },
@@ -100,6 +100,7 @@
                 "paragonie/random_compat": ">= 2",
                 "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5",
                 "psr/cache": "^1.0",
+                "psr/http-message": "^1.0",
                 "psr/simple-cache": "^1.0",
                 "sebastian/comparator": "^1.2.3 || ^4.0",
                 "yoast/phpunit-polyfills": "^1.0"
@@ -150,9 +151,9 @@
             "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.262.3"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.269.0"
             },
-            "time": "2023-03-28T18:18:50+00:00"
+            "time": "2023-04-26T18:21:04+00:00"
         },
         {
             "name": "barryvdh/laravel-dompdf",
@@ -527,16 +528,16 @@
         },
         {
             "name": "doctrine/dbal",
-            "version": "3.6.1",
+            "version": "3.6.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e"
+                "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/57815c7bbcda3cd18871d253c1dd8cbe56f8526e",
-                "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/b4bd1cfbd2b916951696d82e57d054394d84864c",
+                "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c",
                 "shasum": ""
             },
             "require": {
@@ -552,9 +553,9 @@
                 "doctrine/coding-standard": "11.1.0",
                 "fig/log-test": "^1",
                 "jetbrains/phpstorm-stubs": "2022.3",
-                "phpstan/phpstan": "1.10.3",
+                "phpstan/phpstan": "1.10.9",
                 "phpstan/phpstan-strict-rules": "^1.5",
-                "phpunit/phpunit": "9.6.4",
+                "phpunit/phpunit": "9.6.6",
                 "psalm/plugin-phpunit": "0.18.4",
                 "squizlabs/php_codesniffer": "3.7.2",
                 "symfony/cache": "^5.4|^6.0",
@@ -619,7 +620,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/3.6.1"
+                "source": "https://github.com/doctrine/dbal/tree/3.6.2"
             },
             "funding": [
                 {
@@ -635,7 +636,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-02T19:26:24+00:00"
+            "time": "2023-04-14T07:25:38+00:00"
         },
         {
             "name": "doctrine/deprecations",
@@ -1317,22 +1318,22 @@
         },
         {
             "name": "guzzlehttp/guzzle",
-            "version": "7.5.0",
+            "version": "7.5.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/guzzle.git",
-                "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba"
+                "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba",
-                "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9",
+                "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
                 "guzzlehttp/promises": "^1.5",
-                "guzzlehttp/psr7": "^1.9 || ^2.4",
+                "guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
                 "php": "^7.2.5 || ^8.0",
                 "psr/http-client": "^1.0",
                 "symfony/deprecation-contracts": "^2.2 || ^3.0"
@@ -1425,7 +1426,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/guzzle/issues",
-                "source": "https://github.com/guzzle/guzzle/tree/7.5.0"
+                "source": "https://github.com/guzzle/guzzle/tree/7.5.1"
             },
             "funding": [
                 {
@@ -1441,7 +1442,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-08-28T15:39:27+00:00"
+            "time": "2023-04-17T16:30:08+00:00"
         },
         {
             "name": "guzzlehttp/promises",
@@ -1529,22 +1530,22 @@
         },
         {
             "name": "guzzlehttp/psr7",
-            "version": "2.4.4",
+            "version": "2.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
+                "reference": "b635f279edd83fc275f822a1188157ffea568ff6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
-                "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6",
+                "reference": "b635f279edd83fc275f822a1188157ffea568ff6",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.2.5 || ^8.0",
                 "psr/http-factory": "^1.0",
-                "psr/http-message": "^1.0",
+                "psr/http-message": "^1.1 || ^2.0",
                 "ralouphie/getallheaders": "^3.0"
             },
             "provide": {
@@ -1564,9 +1565,6 @@
                 "bamarni-bin": {
                     "bin-links": true,
                     "forward-command": false
-                },
-                "branch-alias": {
-                    "dev-master": "2.4-dev"
                 }
             },
             "autoload": {
@@ -1628,7 +1626,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.4.4"
+                "source": "https://github.com/guzzle/psr7/tree/2.5.0"
             },
             "funding": [
                 {
@@ -1644,7 +1642,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-09T13:19:02+00:00"
+            "time": "2023-04-17T16:11:26+00:00"
         },
         {
             "name": "guzzlehttp/uri-template",
@@ -1732,16 +1730,16 @@
         },
         {
             "name": "hidehalo/nanoid-php",
-            "version": "1.1.12",
+            "version": "1.1.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/hidehalo/nanoid-php.git",
-                "reference": "3229400d7e69b127a9e4f8fdad2e498e64cdaae4"
+                "reference": "3fc7c949f4e655939cc30e7110d658af3dbb0e30"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/hidehalo/nanoid-php/zipball/3229400d7e69b127a9e4f8fdad2e498e64cdaae4",
-                "reference": "3229400d7e69b127a9e4f8fdad2e498e64cdaae4",
+                "url": "https://api.github.com/repos/hidehalo/nanoid-php/zipball/3fc7c949f4e655939cc30e7110d658af3dbb0e30",
+                "reference": "3fc7c949f4e655939cc30e7110d658af3dbb0e30",
                 "shasum": ""
             },
             "require": {
@@ -1783,9 +1781,9 @@
             ],
             "support": {
                 "issues": "https://github.com/hidehalo/nanoid-php/issues",
-                "source": "https://github.com/hidehalo/nanoid-php/tree/1.1.12"
+                "source": "https://github.com/hidehalo/nanoid-php/tree/1.1.13"
             },
-            "time": "2021-12-30T07:27:43+00:00"
+            "time": "2022-08-04T12:07:12+00:00"
         },
         {
             "name": "kkomelin/laravel-translatable-string-exporter",
@@ -1854,16 +1852,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v9.52.5",
+            "version": "v9.52.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "e14d28c0f9403630d13f308bb43f3d3cb73d6d67"
+                "reference": "675ea868fe36b18c8303e954aac540e6b1caa677"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/e14d28c0f9403630d13f308bb43f3d3cb73d6d67",
-                "reference": "e14d28c0f9403630d13f308bb43f3d3cb73d6d67",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/675ea868fe36b18c8303e954aac540e6b1caa677",
+                "reference": "675ea868fe36b18c8303e954aac540e6b1caa677",
                 "shasum": ""
             },
             "require": {
@@ -1960,7 +1958,7 @@
                 "league/flysystem-read-only": "^3.3",
                 "league/flysystem-sftp-v3": "^3.0",
                 "mockery/mockery": "^1.5.1",
-                "orchestra/testbench-core": "^7.16",
+                "orchestra/testbench-core": "^7.24",
                 "pda/pheanstalk": "^4.0",
                 "phpstan/phpdoc-parser": "^1.15",
                 "phpstan/phpstan": "^1.4.7",
@@ -2048,7 +2046,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-03-28T18:03:54+00:00"
+            "time": "2023-04-25T13:44:05+00:00"
         },
         {
             "name": "laravel/serializable-closure",
@@ -2565,16 +2563,16 @@
         },
         {
             "name": "league/flysystem",
-            "version": "3.12.3",
+            "version": "3.14.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem.git",
-                "reference": "81e87e74dd5213795c7846d65089712d2dda90ce"
+                "reference": "e2a279d7f47d9098e479e8b21f7fb8b8de230158"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/81e87e74dd5213795c7846d65089712d2dda90ce",
-                "reference": "81e87e74dd5213795c7846d65089712d2dda90ce",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e2a279d7f47d9098e479e8b21f7fb8b8de230158",
+                "reference": "e2a279d7f47d9098e479e8b21f7fb8b8de230158",
                 "shasum": ""
             },
             "require": {
@@ -2636,7 +2634,7 @@
             ],
             "support": {
                 "issues": "https://github.com/thephpleague/flysystem/issues",
-                "source": "https://github.com/thephpleague/flysystem/tree/3.12.3"
+                "source": "https://github.com/thephpleague/flysystem/tree/3.14.0"
             },
             "funding": [
                 {
@@ -2646,26 +2644,22 @@
                 {
                     "url": "https://github.com/frankdejonge",
                     "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
-                    "type": "tidelift"
                 }
             ],
-            "time": "2023-02-18T15:32:41+00:00"
+            "time": "2023-04-11T18:11:47+00:00"
         },
         {
             "name": "league/flysystem-aws-s3-v3",
-            "version": "3.12.2",
+            "version": "3.13.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
-                "reference": "645e14e4a80bd2da8b01e57388e7296a695a80c2"
+                "reference": "8e04cbb403d4dfd5b73a2f8685f1df395bd177eb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/645e14e4a80bd2da8b01e57388e7296a695a80c2",
-                "reference": "645e14e4a80bd2da8b01e57388e7296a695a80c2",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/8e04cbb403d4dfd5b73a2f8685f1df395bd177eb",
+                "reference": "8e04cbb403d4dfd5b73a2f8685f1df395bd177eb",
                 "shasum": ""
             },
             "require": {
@@ -2706,7 +2700,7 @@
             ],
             "support": {
                 "issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues",
-                "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.12.2"
+                "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.13.0"
             },
             "funding": [
                 {
@@ -2716,13 +2710,9 @@
                 {
                     "url": "https://github.com/frankdejonge",
                     "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
-                    "type": "tidelift"
                 }
             ],
-            "time": "2023-01-17T14:15:08+00:00"
+            "time": "2023-03-16T14:29:01+00:00"
         },
         {
             "name": "league/mime-type-detection",
@@ -2858,26 +2848,24 @@
         },
         {
             "name": "masterminds/html5",
-            "version": "2.7.6",
+            "version": "2.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Masterminds/html5-php.git",
-                "reference": "897eb517a343a2281f11bc5556d6548db7d93947"
+                "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947",
-                "reference": "897eb517a343a2281f11bc5556d6548db7d93947",
+                "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3",
+                "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3",
                 "shasum": ""
             },
             "require": {
-                "ext-ctype": "*",
                 "ext-dom": "*",
-                "ext-libxml": "*",
                 "php": ">=5.3.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7"
+                "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8"
             },
             "type": "library",
             "extra": {
@@ -2921,9 +2909,9 @@
             ],
             "support": {
                 "issues": "https://github.com/Masterminds/html5-php/issues",
-                "source": "https://github.com/Masterminds/html5-php/tree/2.7.6"
+                "source": "https://github.com/Masterminds/html5-php/tree/2.8.0"
             },
-            "time": "2022-08-18T16:18:26+00:00"
+            "time": "2023-04-26T07:27:39+00:00"
         },
         {
             "name": "monolog/monolog",
@@ -3959,16 +3947,16 @@
         },
         {
             "name": "phpstan/phpdoc-parser",
-            "version": "1.16.1",
+            "version": "1.20.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpdoc-parser.git",
-                "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571"
+                "reference": "6c04009f6cae6eda2f040745b6b846080ef069c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e27e92d939e2e3636f0a1f0afaba59692c0bf571",
-                "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6c04009f6cae6eda2f040745b6b846080ef069c2",
+                "reference": "6c04009f6cae6eda2f040745b6b846080ef069c2",
                 "shasum": ""
             },
             "require": {
@@ -3998,9 +3986,9 @@
             "description": "PHPDoc parser with support for nullable, intersection and generic types",
             "support": {
                 "issues": "https://github.com/phpstan/phpdoc-parser/issues",
-                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.16.1"
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.3"
             },
-            "time": "2023-02-07T18:11:17+00:00"
+            "time": "2023-04-25T09:01:03+00:00"
         },
         {
             "name": "predis/predis",
@@ -4214,21 +4202,21 @@
         },
         {
             "name": "psr/http-client",
-            "version": "1.0.1",
+            "version": "1.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/http-client.git",
-                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+                "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
-                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "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"
+                "psr/http-message": "^1.0 || ^2.0"
             },
             "type": "library",
             "extra": {
@@ -4248,7 +4236,7 @@
             "authors": [
                 {
                     "name": "PHP-FIG",
-                    "homepage": "http://www.php-fig.org/"
+                    "homepage": "https://www.php-fig.org/"
                 }
             ],
             "description": "Common interface for HTTP clients",
@@ -4260,27 +4248,27 @@
                 "psr-18"
             ],
             "support": {
-                "source": "https://github.com/php-fig/http-client/tree/master"
+                "source": "https://github.com/php-fig/http-client/tree/1.0.2"
             },
-            "time": "2020-06-29T06:28:15+00:00"
+            "time": "2023-04-10T20:12:12+00:00"
         },
         {
             "name": "psr/http-factory",
-            "version": "1.0.1",
+            "version": "1.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/http-factory.git",
-                "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
+                "reference": "e616d01114759c4c489f93b099585439f795fe35"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
-                "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+                "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"
+                "psr/http-message": "^1.0 || ^2.0"
             },
             "type": "library",
             "extra": {
@@ -4300,7 +4288,7 @@
             "authors": [
                 {
                     "name": "PHP-FIG",
-                    "homepage": "http://www.php-fig.org/"
+                    "homepage": "https://www.php-fig.org/"
                 }
             ],
             "description": "Common interfaces for PSR-7 HTTP message factories",
@@ -4315,31 +4303,31 @@
                 "response"
             ],
             "support": {
-                "source": "https://github.com/php-fig/http-factory/tree/master"
+                "source": "https://github.com/php-fig/http-factory/tree/1.0.2"
             },
-            "time": "2019-04-30T12:38:16+00:00"
+            "time": "2023-04-10T20:10:41+00:00"
         },
         {
             "name": "psr/http-message",
-            "version": "1.0.1",
+            "version": "2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/http-message.git",
-                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+                "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
-                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+                "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.0"
+                "php": "^7.2 || ^8.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
@@ -4354,7 +4342,7 @@
             "authors": [
                 {
                     "name": "PHP-FIG",
-                    "homepage": "http://www.php-fig.org/"
+                    "homepage": "https://www.php-fig.org/"
                 }
             ],
             "description": "Common interface for HTTP messages",
@@ -4368,9 +4356,9 @@
                 "response"
             ],
             "support": {
-                "source": "https://github.com/php-fig/http-message/tree/master"
+                "source": "https://github.com/php-fig/http-message/tree/2.0"
             },
-            "time": "2016-08-06T14:39:51+00:00"
+            "time": "2023-04-04T09:54:51+00:00"
         },
         {
             "name": "psr/log",
@@ -4475,16 +4463,16 @@
         },
         {
             "name": "psy/psysh",
-            "version": "v0.11.14",
+            "version": "v0.11.16",
             "source": {
                 "type": "git",
                 "url": "https://github.com/bobthecow/psysh.git",
-                "reference": "8c2e264def7a8263a68ef6f0b55ce90b77d41e17"
+                "reference": "151b145906804eea8e5d71fea23bfb470c904bfb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/8c2e264def7a8263a68ef6f0b55ce90b77d41e17",
-                "reference": "8c2e264def7a8263a68ef6f0b55ce90b77d41e17",
+                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/151b145906804eea8e5d71fea23bfb470c904bfb",
+                "reference": "151b145906804eea8e5d71fea23bfb470c904bfb",
                 "shasum": ""
             },
             "require": {
@@ -4545,9 +4533,9 @@
             ],
             "support": {
                 "issues": "https://github.com/bobthecow/psysh/issues",
-                "source": "https://github.com/bobthecow/psysh/tree/v0.11.14"
+                "source": "https://github.com/bobthecow/psysh/tree/v0.11.16"
             },
-            "time": "2023-03-28T03:41:01+00:00"
+            "time": "2023-04-26T12:53:57+00:00"
         },
         {
             "name": "qirolab/laravel-themer",
@@ -4754,16 +4742,16 @@
         },
         {
             "name": "ramsey/uuid",
-            "version": "4.x-dev",
+            "version": "4.7.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ramsey/uuid.git",
-                "reference": "8e955307d32dc9b6992440ff81321d3cb09db75a"
+                "reference": "60a4c63ab724854332900504274f6150ff26d286"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ramsey/uuid/zipball/8e955307d32dc9b6992440ff81321d3cb09db75a",
-                "reference": "8e955307d32dc9b6992440ff81321d3cb09db75a",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286",
+                "reference": "60a4c63ab724854332900504274f6150ff26d286",
                 "shasum": ""
             },
             "require": {
@@ -4804,7 +4792,6 @@
                 "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter",
                 "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type."
             },
-            "default-branch": true,
             "type": "library",
             "extra": {
                 "captainhook": {
@@ -4831,7 +4818,7 @@
             ],
             "support": {
                 "issues": "https://github.com/ramsey/uuid/issues",
-                "source": "https://github.com/ramsey/uuid/tree/4.x"
+                "source": "https://github.com/ramsey/uuid/tree/4.7.4"
             },
             "funding": [
                 {
@@ -4843,7 +4830,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-27T22:05:11+00:00"
+            "time": "2023-04-15T23:01:58+00:00"
         },
         {
             "name": "sabberworm/php-css-parser",
@@ -5115,16 +5102,16 @@
         },
         {
             "name": "spatie/laravel-package-tools",
-            "version": "1.14.2",
+            "version": "1.15.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-package-tools.git",
-                "reference": "bab62023a4745a61170ad5424184533685e73c2d"
+                "reference": "efab1844b8826443135201c4443690f032c3d533"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/bab62023a4745a61170ad5424184533685e73c2d",
-                "reference": "bab62023a4745a61170ad5424184533685e73c2d",
+                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/efab1844b8826443135201c4443690f032c3d533",
+                "reference": "efab1844b8826443135201c4443690f032c3d533",
                 "shasum": ""
             },
             "require": {
@@ -5163,7 +5150,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-package-tools/issues",
-                "source": "https://github.com/spatie/laravel-package-tools/tree/1.14.2"
+                "source": "https://github.com/spatie/laravel-package-tools/tree/1.15.0"
             },
             "funding": [
                 {
@@ -5171,7 +5158,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-03-14T16:41:21+00:00"
+            "time": "2023-04-27T08:09:01+00:00"
         },
         {
             "name": "spatie/laravel-query-builder",
@@ -5247,20 +5234,19 @@
         },
         {
             "name": "spatie/laravel-settings",
-            "version": "2.8.2",
+            "version": "2.8.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-settings.git",
-                "reference": "48140731312d73ad000921e23d53b8e1fe5247cf"
+                "reference": "9193603a3e02d19af9f2fd0d309ac2469b25d680"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/48140731312d73ad000921e23d53b8e1fe5247cf",
-                "reference": "48140731312d73ad000921e23d53b8e1fe5247cf",
+                "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/9193603a3e02d19af9f2fd0d309ac2469b25d680",
+                "reference": "9193603a3e02d19af9f2fd0d309ac2469b25d680",
                 "shasum": ""
             },
             "require": {
-                "doctrine/dbal": "^2.13|^3.2",
                 "ext-json": "*",
                 "illuminate/database": "^8.73|^9.0|^10.0",
                 "php": "^7.4|^8.0",
@@ -5319,7 +5305,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-settings/issues",
-                "source": "https://github.com/spatie/laravel-settings/tree/2.8.2"
+                "source": "https://github.com/spatie/laravel-settings/tree/2.8.3"
             },
             "funding": [
                 {
@@ -5331,7 +5317,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-03-10T09:30:34+00:00"
+            "time": "2023-03-30T12:47:39+00:00"
         },
         {
             "name": "spatie/laravel-validation-rules",
@@ -5408,16 +5394,16 @@
         },
         {
             "name": "spatie/temporary-directory",
-            "version": "2.1.1",
+            "version": "2.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/temporary-directory.git",
-                "reference": "e2818d871783d520b319c2d38dc37c10ecdcde20"
+                "reference": "0c804873f6b4042aa8836839dca683c7d0f71831"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/e2818d871783d520b319c2d38dc37c10ecdcde20",
-                "reference": "e2818d871783d520b319c2d38dc37c10ecdcde20",
+                "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/0c804873f6b4042aa8836839dca683c7d0f71831",
+                "reference": "0c804873f6b4042aa8836839dca683c7d0f71831",
                 "shasum": ""
             },
             "require": {
@@ -5453,7 +5439,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/temporary-directory/issues",
-                "source": "https://github.com/spatie/temporary-directory/tree/2.1.1"
+                "source": "https://github.com/spatie/temporary-directory/tree/2.1.2"
             },
             "funding": [
                 {
@@ -5465,7 +5451,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-08-23T07:15:15+00:00"
+            "time": "2023-04-28T07:47:42+00:00"
         },
         {
             "name": "stripe/stripe-php",
@@ -5529,16 +5515,16 @@
         },
         {
             "name": "symfony/console",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "cbad09eb8925b6ad4fb721c7a179344dc4a19d45"
+                "reference": "12288d9f4500f84a4d02254d4aa968b15488476f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/cbad09eb8925b6ad4fb721c7a179344dc4a19d45",
-                "reference": "cbad09eb8925b6ad4fb721c7a179344dc4a19d45",
+                "url": "https://api.github.com/repos/symfony/console/zipball/12288d9f4500f84a4d02254d4aa968b15488476f",
+                "reference": "12288d9f4500f84a4d02254d4aa968b15488476f",
                 "shasum": ""
             },
             "require": {
@@ -5600,12 +5586,12 @@
             "homepage": "https://symfony.com",
             "keywords": [
                 "cli",
-                "command line",
+                "command-line",
                 "console",
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v6.2.7"
+                "source": "https://github.com/symfony/console/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -5621,7 +5607,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-25T17:00:03+00:00"
+            "time": "2023-04-28T13:37:43+00:00"
         },
         {
             "name": "symfony/css-selector",
@@ -5757,16 +5743,16 @@
         },
         {
             "name": "symfony/error-handler",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "61e90f94eb014054000bc902257d2763fac09166"
+                "reference": "8b7e9f124640cb0611624a9383176c3e5f7d8cfb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/61e90f94eb014054000bc902257d2763fac09166",
-                "reference": "61e90f94eb014054000bc902257d2763fac09166",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/8b7e9f124640cb0611624a9383176c3e5f7d8cfb",
+                "reference": "8b7e9f124640cb0611624a9383176c3e5f7d8cfb",
                 "shasum": ""
             },
             "require": {
@@ -5808,7 +5794,7 @@
             "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.7"
+                "source": "https://github.com/symfony/error-handler/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -5824,20 +5810,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-14T08:44:56+00:00"
+            "time": "2023-04-18T13:46:08+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v6.2.7",
+            "version": "v6.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "404b307de426c1c488e5afad64403e5f145e82a5"
+                "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/404b307de426c1c488e5afad64403e5f145e82a5",
-                "reference": "404b307de426c1c488e5afad64403e5f145e82a5",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
+                "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
                 "shasum": ""
             },
             "require": {
@@ -5891,7 +5877,7 @@
             "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.7"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8"
             },
             "funding": [
                 {
@@ -5907,7 +5893,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-14T08:44:56+00:00"
+            "time": "2023-03-20T16:06:02+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
@@ -6054,16 +6040,16 @@
         },
         {
             "name": "symfony/http-client",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "0a5be6cbc570ae23b51b49d67341f378629d78e4"
+                "reference": "3f5545a91c8e79dedd1a06c4b04e1682c80c42f9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/0a5be6cbc570ae23b51b49d67341f378629d78e4",
-                "reference": "0a5be6cbc570ae23b51b49d67341f378629d78e4",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/3f5545a91c8e79dedd1a06c4b04e1682c80c42f9",
+                "reference": "3f5545a91c8e79dedd1a06c4b04e1682c80c42f9",
                 "shasum": ""
             },
             "require": {
@@ -6118,8 +6104,11 @@
             ],
             "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
             "homepage": "https://symfony.com",
+            "keywords": [
+                "http"
+            ],
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v6.2.7"
+                "source": "https://github.com/symfony/http-client/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -6135,7 +6124,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-21T10:54:55+00:00"
+            "time": "2023-04-20T13:12:48+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
@@ -6220,16 +6209,16 @@
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "5fc3038d4a594223f9ea42e4e985548f3fcc9a3b"
+                "reference": "49adbb92bcb4e3c2943719d2756271e8b9602acc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5fc3038d4a594223f9ea42e4e985548f3fcc9a3b",
-                "reference": "5fc3038d4a594223f9ea42e4e985548f3fcc9a3b",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/49adbb92bcb4e3c2943719d2756271e8b9602acc",
+                "reference": "49adbb92bcb4e3c2943719d2756271e8b9602acc",
                 "shasum": ""
             },
             "require": {
@@ -6278,7 +6267,7 @@
             "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.7"
+                "source": "https://github.com/symfony/http-foundation/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -6294,20 +6283,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-21T10:54:55+00:00"
+            "time": "2023-04-18T13:46:08+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "ca0680ad1e2d678536cc20e0ae33f9e4e5d2becd"
+                "reference": "81064a65a5496f17d2b6984f6519406f98864215"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ca0680ad1e2d678536cc20e0ae33f9e4e5d2becd",
-                "reference": "ca0680ad1e2d678536cc20e0ae33f9e4e5d2becd",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/81064a65a5496f17d2b6984f6519406f98864215",
+                "reference": "81064a65a5496f17d2b6984f6519406f98864215",
                 "shasum": ""
             },
             "require": {
@@ -6389,7 +6378,7 @@
             "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.7"
+                "source": "https://github.com/symfony/http-kernel/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -6405,20 +6394,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-28T13:26:41+00:00"
+            "time": "2023-04-28T13:50:28+00:00"
         },
         {
             "name": "symfony/intl",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/intl.git",
-                "reference": "e7346ea6d88ae22e1b5d489b7a60135e72527cec"
+                "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/intl/zipball/e7346ea6d88ae22e1b5d489b7a60135e72527cec",
-                "reference": "e7346ea6d88ae22e1b5d489b7a60135e72527cec",
+                "url": "https://api.github.com/repos/symfony/intl/zipball/860c99e53149d22df1900d3aefdaeb17adb7669d",
+                "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d",
                 "shasum": ""
             },
             "require": {
@@ -6459,7 +6448,7 @@
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Provides a PHP replacement layer for the C intl extension that includes additional data from the ICU library",
+            "description": "Provides access to the localization data of the ICU library",
             "homepage": "https://symfony.com",
             "keywords": [
                 "i18n",
@@ -6470,7 +6459,7 @@
                 "localization"
             ],
             "support": {
-                "source": "https://github.com/symfony/intl/tree/v6.2.7"
+                "source": "https://github.com/symfony/intl/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -6486,20 +6475,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-21T10:54:55+00:00"
+            "time": "2023-04-14T16:23:31+00:00"
         },
         {
             "name": "symfony/mailer",
-            "version": "v6.2.7",
+            "version": "v6.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mailer.git",
-                "reference": "e4f84c633b72ec70efc50b8016871c3bc43e691e"
+                "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mailer/zipball/e4f84c633b72ec70efc50b8016871c3bc43e691e",
-                "reference": "e4f84c633b72ec70efc50b8016871c3bc43e691e",
+                "url": "https://api.github.com/repos/symfony/mailer/zipball/bfcfa015c67e19c6fdb7ca6fe70700af1e740a17",
+                "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17",
                 "shasum": ""
             },
             "require": {
@@ -6549,7 +6538,7 @@
             "description": "Helps sending emails",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/mailer/tree/v6.2.7"
+                "source": "https://github.com/symfony/mailer/tree/v6.2.8"
             },
             "funding": [
                 {
@@ -6565,20 +6554,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-21T10:35:38+00:00"
+            "time": "2023-03-14T15:00:05+00:00"
         },
         {
             "name": "symfony/mailgun-mailer",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mailgun-mailer.git",
-                "reference": "9e27b8ec2f6ee7575c6229a61be1578a5a4b21ee"
+                "reference": "2c9d47b11cc154d2db3f571030cd965d128de1a8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/9e27b8ec2f6ee7575c6229a61be1578a5a4b21ee",
-                "reference": "9e27b8ec2f6ee7575c6229a61be1578a5a4b21ee",
+                "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/2c9d47b11cc154d2db3f571030cd965d128de1a8",
+                "reference": "2c9d47b11cc154d2db3f571030cd965d128de1a8",
                 "shasum": ""
             },
             "require": {
@@ -6614,7 +6603,7 @@
             "description": "Symfony Mailgun Mailer Bridge",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/mailgun-mailer/tree/v6.2.7"
+                "source": "https://github.com/symfony/mailgun-mailer/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -6630,20 +6619,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-21T10:35:38+00:00"
+            "time": "2023-04-14T16:23:31+00:00"
         },
         {
             "name": "symfony/mime",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mime.git",
-                "reference": "62e341f80699badb0ad70b31149c8df89a2d778e"
+                "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mime/zipball/62e341f80699badb0ad70b31149c8df89a2d778e",
-                "reference": "62e341f80699badb0ad70b31149c8df89a2d778e",
+                "url": "https://api.github.com/repos/symfony/mime/zipball/b6c137fc53a9f7c4c951cd3f362b3734c7a97723",
+                "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723",
                 "shasum": ""
             },
             "require": {
@@ -6697,7 +6686,7 @@
                 "mime-type"
             ],
             "support": {
-                "source": "https://github.com/symfony/mime/tree/v6.2.7"
+                "source": "https://github.com/symfony/mime/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -6713,7 +6702,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-24T10:42:00+00:00"
+            "time": "2023-04-19T09:54:16+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
@@ -7375,16 +7364,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902"
+                "reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
-                "reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
+                "url": "https://api.github.com/repos/symfony/process/zipball/b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
+                "reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
                 "shasum": ""
             },
             "require": {
@@ -7416,7 +7405,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v6.2.7"
+                "source": "https://github.com/symfony/process/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -7432,20 +7421,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-24T10:42:00+00:00"
+            "time": "2023-04-18T13:56:57+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v6.2.7",
+            "version": "v6.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "fa643fa4c56de161f8bc8c0492a76a60140b50e4"
+                "reference": "69062e2823f03b82265d73a966999660f0e1e404"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/fa643fa4c56de161f8bc8c0492a76a60140b50e4",
-                "reference": "fa643fa4c56de161f8bc8c0492a76a60140b50e4",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/69062e2823f03b82265d73a966999660f0e1e404",
+                "reference": "69062e2823f03b82265d73a966999660f0e1e404",
                 "shasum": ""
             },
             "require": {
@@ -7504,7 +7493,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v6.2.7"
+                "source": "https://github.com/symfony/routing/tree/v6.2.8"
             },
             "funding": [
                 {
@@ -7520,7 +7509,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-14T08:53:37+00:00"
+            "time": "2023-03-14T15:00:05+00:00"
         },
         {
             "name": "symfony/service-contracts",
@@ -7609,16 +7598,16 @@
         },
         {
             "name": "symfony/string",
-            "version": "v6.2.7",
+            "version": "v6.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "67b8c1eec78296b85dc1c7d9743830160218993d"
+                "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/67b8c1eec78296b85dc1c7d9743830160218993d",
-                "reference": "67b8c1eec78296b85dc1c7d9743830160218993d",
+                "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
+                "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
                 "shasum": ""
             },
             "require": {
@@ -7675,7 +7664,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v6.2.7"
+                "source": "https://github.com/symfony/string/tree/v6.2.8"
             },
             "funding": [
                 {
@@ -7691,20 +7680,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-24T10:42:00+00:00"
+            "time": "2023-03-20T16:06:02+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v6.2.7",
+            "version": "v6.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "90db1c6138c90527917671cd9ffa9e8b359e3a73"
+                "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/90db1c6138c90527917671cd9ffa9e8b359e3a73",
-                "reference": "90db1c6138c90527917671cd9ffa9e8b359e3a73",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/817535dbb1721df8b3a8f2489dc7e50bcd6209b5",
+                "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5",
                 "shasum": ""
             },
             "require": {
@@ -7773,7 +7762,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v6.2.7"
+                "source": "https://github.com/symfony/translation/tree/v6.2.8"
             },
             "funding": [
                 {
@@ -7789,7 +7778,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-24T10:42:00+00:00"
+            "time": "2023-03-31T09:14:44+00:00"
         },
         {
             "name": "symfony/translation-contracts",
@@ -7948,16 +7937,16 @@
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "cf8d4ca1ddc1e3cc242375deb8fc23e54f5e2a1e"
+                "reference": "41a750a23412ca76fdbbf5096943b4134272c1ab"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cf8d4ca1ddc1e3cc242375deb8fc23e54f5e2a1e",
-                "reference": "cf8d4ca1ddc1e3cc242375deb8fc23e54f5e2a1e",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41a750a23412ca76fdbbf5096943b4134272c1ab",
+                "reference": "41a750a23412ca76fdbbf5096943b4134272c1ab",
                 "shasum": ""
             },
             "require": {
@@ -8016,7 +8005,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v6.2.7"
+                "source": "https://github.com/symfony/var-dumper/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -8032,7 +8021,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-24T10:42:00+00:00"
+            "time": "2023-04-18T13:46:08+00:00"
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
@@ -8614,16 +8603,16 @@
         },
         {
             "name": "filp/whoops",
-            "version": "2.15.1",
+            "version": "2.15.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filp/whoops.git",
-                "reference": "e864ac957acd66e1565f25efda61e37791a5db0b"
+                "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filp/whoops/zipball/e864ac957acd66e1565f25efda61e37791a5db0b",
-                "reference": "e864ac957acd66e1565f25efda61e37791a5db0b",
+                "url": "https://api.github.com/repos/filp/whoops/zipball/aac9304c5ed61bf7b1b7a6064bf9806ab842ce73",
+                "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73",
                 "shasum": ""
             },
             "require": {
@@ -8673,7 +8662,7 @@
             ],
             "support": {
                 "issues": "https://github.com/filp/whoops/issues",
-                "source": "https://github.com/filp/whoops/tree/2.15.1"
+                "source": "https://github.com/filp/whoops/tree/2.15.2"
             },
             "funding": [
                 {
@@ -8681,7 +8670,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-03-06T18:09:13+00:00"
+            "time": "2023-04-12T12:00:00+00:00"
         },
         {
             "name": "hamcrest/hamcrest-php",
@@ -8736,16 +8725,16 @@
         },
         {
             "name": "laravel/sail",
-            "version": "v1.21.3",
+            "version": "v1.21.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/sail.git",
-                "reference": "3042ff8cf403817c340d5a7762b2d32900239f46"
+                "reference": "27af207bb1c53faddcba34c7528b3e969f6a646d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/sail/zipball/3042ff8cf403817c340d5a7762b2d32900239f46",
-                "reference": "3042ff8cf403817c340d5a7762b2d32900239f46",
+                "url": "https://api.github.com/repos/laravel/sail/zipball/27af207bb1c53faddcba34c7528b3e969f6a646d",
+                "reference": "27af207bb1c53faddcba34c7528b3e969f6a646d",
                 "shasum": ""
             },
             "require": {
@@ -8797,7 +8786,7 @@
                 "issues": "https://github.com/laravel/sail/issues",
                 "source": "https://github.com/laravel/sail"
             },
-            "time": "2023-03-13T01:22:10+00:00"
+            "time": "2023-04-24T13:29:38+00:00"
         },
         {
             "name": "maximebf/debugbar",
@@ -9515,16 +9504,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "9.6.6",
+            "version": "9.6.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115"
+                "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115",
-                "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
+                "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
                 "shasum": ""
             },
             "require": {
@@ -9598,7 +9587,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7"
             },
             "funding": [
                 {
@@ -9614,7 +9603,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-27T11:43:46+00:00"
+            "time": "2023-04-14T08:58:40+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -10644,16 +10633,16 @@
         },
         {
             "name": "spatie/flare-client-php",
-            "version": "1.3.5",
+            "version": "1.3.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/flare-client-php.git",
-                "reference": "3e5dd5ac4928f3d2d036bd02de5eb83fd0ef1f42"
+                "reference": "530ac81255af79f114344286e4275f8869c671e2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/3e5dd5ac4928f3d2d036bd02de5eb83fd0ef1f42",
-                "reference": "3e5dd5ac4928f3d2d036bd02de5eb83fd0ef1f42",
+                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/530ac81255af79f114344286e4275f8869c671e2",
+                "reference": "530ac81255af79f114344286e4275f8869c671e2",
                 "shasum": ""
             },
             "require": {
@@ -10701,7 +10690,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/flare-client-php/issues",
-                "source": "https://github.com/spatie/flare-client-php/tree/1.3.5"
+                "source": "https://github.com/spatie/flare-client-php/tree/1.3.6"
             },
             "funding": [
                 {
@@ -10709,42 +10698,51 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-23T15:58:46+00:00"
+            "time": "2023-04-12T07:57:12+00:00"
         },
         {
             "name": "spatie/ignition",
-            "version": "1.4.5",
+            "version": "1.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/ignition.git",
-                "reference": "cc09114b7057bd217b676f047544b33f5b6247e6"
+                "reference": "fbcfcabc44e506e40c4d72fd4ddf465e272a600e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/ignition/zipball/cc09114b7057bd217b676f047544b33f5b6247e6",
-                "reference": "cc09114b7057bd217b676f047544b33f5b6247e6",
+                "url": "https://api.github.com/repos/spatie/ignition/zipball/fbcfcabc44e506e40c4d72fd4ddf465e272a600e",
+                "reference": "fbcfcabc44e506e40c4d72fd4ddf465e272a600e",
                 "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",
-                "symfony/process": "^5.4|^6.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"
+                    "dev-main": "1.5.x-dev"
                 }
             },
             "autoload": {
@@ -10783,7 +10781,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-28T16:49:47+00:00"
+            "time": "2023-04-27T08:40:07+00:00"
         },
         {
             "name": "spatie/laravel-ignition",
@@ -10877,16 +10875,16 @@
         },
         {
             "name": "symfony/yaml",
-            "version": "v6.2.7",
+            "version": "v6.2.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57"
+                "reference": "61916f3861b1e9705b18cfde723921a71dd1559d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/e8e6a1d59e050525f27a1f530aa9703423cb7f57",
-                "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/61916f3861b1e9705b18cfde723921a71dd1559d",
+                "reference": "61916f3861b1e9705b18cfde723921a71dd1559d",
                 "shasum": ""
             },
             "require": {
@@ -10931,7 +10929,7 @@
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v6.2.7"
+                "source": "https://github.com/symfony/yaml/tree/v6.2.10"
             },
             "funding": [
                 {
@@ -10947,7 +10945,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-16T09:57:23+00:00"
+            "time": "2023-04-28T13:25:36+00:00"
         },
         {
             "name": "theseer/tokenizer",
@@ -11013,5 +11011,5 @@
     "platform-overrides": {
         "php": "8.1"
     },
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.1.0"
 }

From a4b56fa358d45ae7a0490f6ac6b141ae9d5eef32 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sat, 29 Apr 2023 23:35:08 +0200
Subject: [PATCH 096/514] update datatables

---
 .../plugins/datatables/jquery.dataTables.js   | 15383 ----------------
 .../datatables/jquery.dataTables.min.css      |     1 +
 .../datatables/jquery.dataTables.min.js       |   172 +-
 themes/default/views/layouts/main.blade.php   |     4 +-
 4 files changed, 7 insertions(+), 15553 deletions(-)
 delete mode 100644 public/plugins/datatables/jquery.dataTables.js
 create mode 100644 public/plugins/datatables/jquery.dataTables.min.css

diff --git a/public/plugins/datatables/jquery.dataTables.js b/public/plugins/datatables/jquery.dataTables.js
deleted file mode 100644
index df26319a5..000000000
--- a/public/plugins/datatables/jquery.dataTables.js
+++ /dev/null
@@ -1,15383 +0,0 @@
-/*! DataTables 1.10.23
- * ©2008-2020 SpryMedia Ltd - datatables.net/license
- */
-
-/**
- * @summary     DataTables
- * @description Paginate, search and order HTML tables
- * @version     1.10.23
- * @file        jquery.dataTables.js
- * @author      SpryMedia Ltd
- * @contact     www.datatables.net
- * @copyright   Copyright 2008-2020 SpryMedia Ltd.
- *
- * This source file is free software, available under the following license:
- *   MIT license - http://datatables.net/license
- *
- * This source file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- *
- * For details please refer to: http://www.datatables.net
- */
-
-/*jslint evil: true, undef: true, browser: true */
-/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
-
-(function( factory ) {
-	"use strict";
-
-	if ( typeof define === 'function' && define.amd ) {
-		// AMD
-		define( ['jquery'], function ( $ ) {
-			return factory( $, window, document );
-		} );
-	}
-	else if ( typeof exports === 'object' ) {
-		// CommonJS
-		module.exports = function (root, $) {
-			if ( ! root ) {
-				// CommonJS environments without a window global must pass a
-				// root. This will give an error otherwise
-				root = window;
-			}
-
-			if ( ! $ ) {
-				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
-					require('jquery') :
-					require('jquery')( root );
-			}
-
-			return factory( $, root, root.document );
-		};
-	}
-	else {
-		// Browser
-		factory( jQuery, window, document );
-	}
-}
-(function( $, window, document, undefined ) {
-	"use strict";
-
-	/**
-	 * DataTables is a plug-in for the jQuery Javascript library. It is a highly
-	 * flexible tool, based upon the foundations of progressive enhancement,
-	 * which will add advanced interaction controls to any HTML table. For a
-	 * full list of features please refer to
-	 * [DataTables.net](href="http://datatables.net).
-	 *
-	 * Note that the `DataTable` object is not a global variable but is aliased
-	 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
-	 * be  accessed.
-	 *
-	 *  @class
-	 *  @param {object} [init={}] Configuration object for DataTables. Options
-	 *    are defined by {@link DataTable.defaults}
-	 *  @requires jQuery 1.7+
-	 *
-	 *  @example
-	 *    // Basic initialisation
-	 *    $(document).ready( function {
-	 *      $('#example').dataTable();
-	 *    } );
-	 *
-	 *  @example
-	 *    // Initialisation with configuration options - in this case, disable
-	 *    // pagination and sorting.
-	 *    $(document).ready( function {
-	 *      $('#example').dataTable( {
-	 *        "paginate": false,
-	 *        "sort": false
-	 *      } );
-	 *    } );
-	 */
-	var DataTable = function ( options )
-	{
-		/**
-		 * Perform a jQuery selector action on the table's TR elements (from the tbody) and
-		 * return the resulting jQuery object.
-		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
-		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
-		 *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
-		 *    criterion ("applied") or all TR elements (i.e. no filter).
-		 *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
-		 *    Can be either 'current', whereby the current sorting of the table is used, or
-		 *    'original' whereby the original order the data was read into the table is used.
-		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
-		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
-		 *    'current' and filter is 'applied', regardless of what they might be given as.
-		 *  @returns {object} jQuery object, filtered by the given selector.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Highlight every second row
-		 *      oTable.$('tr:odd').css('backgroundColor', 'blue');
-		 *    } );
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Filter to rows with 'Webkit' in them, add a background colour and then
-		 *      // remove the filter, thus highlighting the 'Webkit' rows only.
-		 *      oTable.fnFilter('Webkit');
-		 *      oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
-		 *      oTable.fnFilter('');
-		 *    } );
-		 */
-		this.$ = function ( sSelector, oOpts )
-		{
-			return this.api(true).$( sSelector, oOpts );
-		};
-		
-		
-		/**
-		 * Almost identical to $ in operation, but in this case returns the data for the matched
-		 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
-		 * rather than any descendants, so the data can be obtained for the row/cell. If matching
-		 * rows are found, the data returned is the original data array/object that was used to
-		 * create the row (or a generated array if from a DOM source).
-		 *
-		 * This method is often useful in-combination with $ where both functions are given the
-		 * same parameters and the array indexes will match identically.
-		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
-		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
-		 *  @param {string} [oOpts.filter=none] Select elements that meet the current filter
-		 *    criterion ("applied") or all elements (i.e. no filter).
-		 *  @param {string} [oOpts.order=current] Order of the data in the processed array.
-		 *    Can be either 'current', whereby the current sorting of the table is used, or
-		 *    'original' whereby the original order the data was read into the table is used.
-		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
-		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
-		 *    'current' and filter is 'applied', regardless of what they might be given as.
-		 *  @returns {array} Data for the matched elements. If any elements, as a result of the
-		 *    selector, were not TR, TD or TH elements in the DataTable, they will have a null
-		 *    entry in the array.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Get the data from the first row in the table
-		 *      var data = oTable._('tr:first');
-		 *
-		 *      // Do something useful with the data
-		 *      alert( "First cell is: "+data[0] );
-		 *    } );
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Filter to 'Webkit' and get all data for
-		 *      oTable.fnFilter('Webkit');
-		 *      var data = oTable._('tr', {"search": "applied"});
-		 *
-		 *      // Do something with the data
-		 *      alert( data.length+" rows matched the search" );
-		 *    } );
-		 */
-		this._ = function ( sSelector, oOpts )
-		{
-			return this.api(true).rows( sSelector, oOpts ).data();
-		};
-		
-		
-		/**
-		 * Create a DataTables Api instance, with the currently selected tables for
-		 * the Api's context.
-		 * @param {boolean} [traditional=false] Set the API instance's context to be
-		 *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was
-		 *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),
-		 *   or if all tables captured in the jQuery object should be used.
-		 * @return {DataTables.Api}
-		 */
-		this.api = function ( traditional )
-		{
-			return traditional ?
-				new _Api(
-					_fnSettingsFromNode( this[ _ext.iApiIndex ] )
-				) :
-				new _Api( this );
-		};
-		
-		
-		/**
-		 * Add a single new row or multiple rows of data to the table. Please note
-		 * that this is suitable for client-side processing only - if you are using
-		 * server-side processing (i.e. "bServerSide": true), then to add data, you
-		 * must add it to the data source, i.e. the server-side, through an Ajax call.
-		 *  @param {array|object} data The data to be added to the table. This can be:
-		 *    <ul>
-		 *      <li>1D array of data - add a single row with the data provided</li>
-		 *      <li>2D array of arrays - add multiple rows in a single call</li>
-		 *      <li>object - data object when using <i>mData</i></li>
-		 *      <li>array of objects - multiple data objects when using <i>mData</i></li>
-		 *    </ul>
-		 *  @param {bool} [redraw=true] redraw the table or not
-		 *  @returns {array} An array of integers, representing the list of indexes in
-		 *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
-		 *    the table.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    // Global var for counter
-		 *    var giCount = 2;
-		 *
-		 *    $(document).ready(function() {
-		 *      $('#example').dataTable();
-		 *    } );
-		 *
-		 *    function fnClickAddRow() {
-		 *      $('#example').dataTable().fnAddData( [
-		 *        giCount+".1",
-		 *        giCount+".2",
-		 *        giCount+".3",
-		 *        giCount+".4" ]
-		 *      );
-		 *
-		 *      giCount++;
-		 *    }
-		 */
-		this.fnAddData = function( data, redraw )
-		{
-			var api = this.api( true );
-		
-			/* Check if we want to add multiple rows or not */
-			var rows = Array.isArray(data) && ( Array.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
-				api.rows.add( data ) :
-				api.row.add( data );
-		
-			if ( redraw === undefined || redraw ) {
-				api.draw();
-			}
-		
-			return rows.flatten().toArray();
-		};
-		
-		
-		/**
-		 * This function will make DataTables recalculate the column sizes, based on the data
-		 * contained in the table and the sizes applied to the columns (in the DOM, CSS or
-		 * through the sWidth parameter). This can be useful when the width of the table's
-		 * parent element changes (for example a window resize).
-		 *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable( {
-		 *        "sScrollY": "200px",
-		 *        "bPaginate": false
-		 *      } );
-		 *
-		 *      $(window).on('resize', function () {
-		 *        oTable.fnAdjustColumnSizing();
-		 *      } );
-		 *    } );
-		 */
-		this.fnAdjustColumnSizing = function ( bRedraw )
-		{
-			var api = this.api( true ).columns.adjust();
-			var settings = api.settings()[0];
-			var scroll = settings.oScroll;
-		
-			if ( bRedraw === undefined || bRedraw ) {
-				api.draw( false );
-			}
-			else if ( scroll.sX !== "" || scroll.sY !== "" ) {
-				/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
-				_fnScrollDraw( settings );
-			}
-		};
-		
-		
-		/**
-		 * Quickly and simply clear a table
-		 *  @param {bool} [bRedraw=true] redraw the table or not
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
-		 *      oTable.fnClearTable();
-		 *    } );
-		 */
-		this.fnClearTable = function( bRedraw )
-		{
-			var api = this.api( true ).clear();
-		
-			if ( bRedraw === undefined || bRedraw ) {
-				api.draw();
-			}
-		};
-		
-		
-		/**
-		 * The exact opposite of 'opening' a row, this function will close any rows which
-		 * are currently 'open'.
-		 *  @param {node} nTr the table row to 'close'
-		 *  @returns {int} 0 on success, or 1 if failed (can't find the row)
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable;
-		 *
-		 *      // 'open' an information row when a row is clicked on
-		 *      $('#example tbody tr').click( function () {
-		 *        if ( oTable.fnIsOpen(this) ) {
-		 *          oTable.fnClose( this );
-		 *        } else {
-		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
-		 *        }
-		 *      } );
-		 *
-		 *      oTable = $('#example').dataTable();
-		 *    } );
-		 */
-		this.fnClose = function( nTr )
-		{
-			this.api( true ).row( nTr ).child.hide();
-		};
-		
-		
-		/**
-		 * Remove a row for the table
-		 *  @param {mixed} target The index of the row from aoData to be deleted, or
-		 *    the TR element you want to delete
-		 *  @param {function|null} [callBack] Callback function
-		 *  @param {bool} [redraw=true] Redraw the table or not
-		 *  @returns {array} The row that was deleted
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Immediately remove the first row
-		 *      oTable.fnDeleteRow( 0 );
-		 *    } );
-		 */
-		this.fnDeleteRow = function( target, callback, redraw )
-		{
-			var api = this.api( true );
-			var rows = api.rows( target );
-			var settings = rows.settings()[0];
-			var data = settings.aoData[ rows[0][0] ];
-		
-			rows.remove();
-		
-			if ( callback ) {
-				callback.call( this, settings, data );
-			}
-		
-			if ( redraw === undefined || redraw ) {
-				api.draw();
-			}
-		
-			return data;
-		};
-		
-		
-		/**
-		 * Restore the table to it's original state in the DOM by removing all of DataTables
-		 * enhancements, alterations to the DOM structure of the table and event listeners.
-		 *  @param {boolean} [remove=false] Completely remove the table from the DOM
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      // This example is fairly pointless in reality, but shows how fnDestroy can be used
-		 *      var oTable = $('#example').dataTable();
-		 *      oTable.fnDestroy();
-		 *    } );
-		 */
-		this.fnDestroy = function ( remove )
-		{
-			this.api( true ).destroy( remove );
-		};
-		
-		
-		/**
-		 * Redraw the table
-		 *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
-		 *      oTable.fnDraw();
-		 *    } );
-		 */
-		this.fnDraw = function( complete )
-		{
-			// Note that this isn't an exact match to the old call to _fnDraw - it takes
-			// into account the new data, but can hold position.
-			this.api( true ).draw( complete );
-		};
-		
-		
-		/**
-		 * Filter the input based on data
-		 *  @param {string} sInput String to filter the table on
-		 *  @param {int|null} [iColumn] Column to limit filtering to
-		 *  @param {bool} [bRegex=false] Treat as regular expression or not
-		 *  @param {bool} [bSmart=true] Perform smart filtering or not
-		 *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
-		 *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Sometime later - filter...
-		 *      oTable.fnFilter( 'test string' );
-		 *    } );
-		 */
-		this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
-		{
-			var api = this.api( true );
-		
-			if ( iColumn === null || iColumn === undefined ) {
-				api.search( sInput, bRegex, bSmart, bCaseInsensitive );
-			}
-			else {
-				api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
-			}
-		
-			api.draw();
-		};
-		
-		
-		/**
-		 * Get the data for the whole table, an individual row or an individual cell based on the
-		 * provided parameters.
-		 *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
-		 *    a TR node then the data source for the whole row will be returned. If given as a
-		 *    TD/TH cell node then iCol will be automatically calculated and the data for the
-		 *    cell returned. If given as an integer, then this is treated as the aoData internal
-		 *    data index for the row (see fnGetPosition) and the data for that row used.
-		 *  @param {int} [col] Optional column index that you want the data of.
-		 *  @returns {array|object|string} If mRow is undefined, then the data for all rows is
-		 *    returned. If mRow is defined, just data for that row, and is iCol is
-		 *    defined, only data for the designated cell is returned.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    // Row data
-		 *    $(document).ready(function() {
-		 *      oTable = $('#example').dataTable();
-		 *
-		 *      oTable.$('tr').click( function () {
-		 *        var data = oTable.fnGetData( this );
-		 *        // ... do something with the array / object of data for the row
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Individual cell data
-		 *    $(document).ready(function() {
-		 *      oTable = $('#example').dataTable();
-		 *
-		 *      oTable.$('td').click( function () {
-		 *        var sData = oTable.fnGetData( this );
-		 *        alert( 'The cell clicked on had the value of '+sData );
-		 *      } );
-		 *    } );
-		 */
-		this.fnGetData = function( src, col )
-		{
-			var api = this.api( true );
-		
-			if ( src !== undefined ) {
-				var type = src.nodeName ? src.nodeName.toLowerCase() : '';
-		
-				return col !== undefined || type == 'td' || type == 'th' ?
-					api.cell( src, col ).data() :
-					api.row( src ).data() || null;
-			}
-		
-			return api.data().toArray();
-		};
-		
-		
-		/**
-		 * Get an array of the TR nodes that are used in the table's body. Note that you will
-		 * typically want to use the '$' API method in preference to this as it is more
-		 * flexible.
-		 *  @param {int} [iRow] Optional row index for the TR element you want
-		 *  @returns {array|node} If iRow is undefined, returns an array of all TR elements
-		 *    in the table's body, or iRow is defined, just the TR element requested.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Get the nodes from the table
-		 *      var nNodes = oTable.fnGetNodes( );
-		 *    } );
-		 */
-		this.fnGetNodes = function( iRow )
-		{
-			var api = this.api( true );
-		
-			return iRow !== undefined ?
-				api.row( iRow ).node() :
-				api.rows().nodes().flatten().toArray();
-		};
-		
-		
-		/**
-		 * Get the array indexes of a particular cell from it's DOM element
-		 * and column index including hidden columns
-		 *  @param {node} node this can either be a TR, TD or TH in the table's body
-		 *  @returns {int} If nNode is given as a TR, then a single index is returned, or
-		 *    if given as a cell, an array of [row index, column index (visible),
-		 *    column index (all)] is given.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      $('#example tbody td').click( function () {
-		 *        // Get the position of the current data from the node
-		 *        var aPos = oTable.fnGetPosition( this );
-		 *
-		 *        // Get the data array for this row
-		 *        var aData = oTable.fnGetData( aPos[0] );
-		 *
-		 *        // Update the data array and return the value
-		 *        aData[ aPos[1] ] = 'clicked';
-		 *        this.innerHTML = 'clicked';
-		 *      } );
-		 *
-		 *      // Init DataTables
-		 *      oTable = $('#example').dataTable();
-		 *    } );
-		 */
-		this.fnGetPosition = function( node )
-		{
-			var api = this.api( true );
-			var nodeName = node.nodeName.toUpperCase();
-		
-			if ( nodeName == 'TR' ) {
-				return api.row( node ).index();
-			}
-			else if ( nodeName == 'TD' || nodeName == 'TH' ) {
-				var cell = api.cell( node ).index();
-		
-				return [
-					cell.row,
-					cell.columnVisible,
-					cell.column
-				];
-			}
-			return null;
-		};
-		
-		
-		/**
-		 * Check to see if a row is 'open' or not.
-		 *  @param {node} nTr the table row to check
-		 *  @returns {boolean} true if the row is currently open, false otherwise
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable;
-		 *
-		 *      // 'open' an information row when a row is clicked on
-		 *      $('#example tbody tr').click( function () {
-		 *        if ( oTable.fnIsOpen(this) ) {
-		 *          oTable.fnClose( this );
-		 *        } else {
-		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
-		 *        }
-		 *      } );
-		 *
-		 *      oTable = $('#example').dataTable();
-		 *    } );
-		 */
-		this.fnIsOpen = function( nTr )
-		{
-			return this.api( true ).row( nTr ).child.isShown();
-		};
-		
-		
-		/**
-		 * This function will place a new row directly after a row which is currently
-		 * on display on the page, with the HTML contents that is passed into the
-		 * function. This can be used, for example, to ask for confirmation that a
-		 * particular record should be deleted.
-		 *  @param {node} nTr The table row to 'open'
-		 *  @param {string|node|jQuery} mHtml The HTML to put into the row
-		 *  @param {string} sClass Class to give the new TD cell
-		 *  @returns {node} The row opened. Note that if the table row passed in as the
-		 *    first parameter, is not found in the table, this method will silently
-		 *    return.
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable;
-		 *
-		 *      // 'open' an information row when a row is clicked on
-		 *      $('#example tbody tr').click( function () {
-		 *        if ( oTable.fnIsOpen(this) ) {
-		 *          oTable.fnClose( this );
-		 *        } else {
-		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
-		 *        }
-		 *      } );
-		 *
-		 *      oTable = $('#example').dataTable();
-		 *    } );
-		 */
-		this.fnOpen = function( nTr, mHtml, sClass )
-		{
-			return this.api( true )
-				.row( nTr )
-				.child( mHtml, sClass )
-				.show()
-				.child()[0];
-		};
-		
-		
-		/**
-		 * Change the pagination - provides the internal logic for pagination in a simple API
-		 * function. With this function you can have a DataTables table go to the next,
-		 * previous, first or last pages.
-		 *  @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
-		 *    or page number to jump to (integer), note that page 0 is the first page.
-		 *  @param {bool} [bRedraw=true] Redraw the table or not
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *      oTable.fnPageChange( 'next' );
-		 *    } );
-		 */
-		this.fnPageChange = function ( mAction, bRedraw )
-		{
-			var api = this.api( true ).page( mAction );
-		
-			if ( bRedraw === undefined || bRedraw ) {
-				api.draw(false);
-			}
-		};
-		
-		
-		/**
-		 * Show a particular column
-		 *  @param {int} iCol The column whose display should be changed
-		 *  @param {bool} bShow Show (true) or hide (false) the column
-		 *  @param {bool} [bRedraw=true] Redraw the table or not
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Hide the second column after initialisation
-		 *      oTable.fnSetColumnVis( 1, false );
-		 *    } );
-		 */
-		this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
-		{
-			var api = this.api( true ).column( iCol ).visible( bShow );
-		
-			if ( bRedraw === undefined || bRedraw ) {
-				api.columns.adjust().draw();
-			}
-		};
-		
-		
-		/**
-		 * Get the settings for a particular table for external manipulation
-		 *  @returns {object} DataTables settings object. See
-		 *    {@link DataTable.models.oSettings}
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *      var oSettings = oTable.fnSettings();
-		 *
-		 *      // Show an example parameter from the settings
-		 *      alert( oSettings._iDisplayStart );
-		 *    } );
-		 */
-		this.fnSettings = function()
-		{
-			return _fnSettingsFromNode( this[_ext.iApiIndex] );
-		};
-		
-		
-		/**
-		 * Sort the table by a particular column
-		 *  @param {int} iCol the data index to sort on. Note that this will not match the
-		 *    'display index' if you have hidden data entries
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Sort immediately with columns 0 and 1
-		 *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
-		 *    } );
-		 */
-		this.fnSort = function( aaSort )
-		{
-			this.api( true ).order( aaSort ).draw();
-		};
-		
-		
-		/**
-		 * Attach a sort listener to an element for a given column
-		 *  @param {node} nNode the element to attach the sort listener to
-		 *  @param {int} iColumn the column that a click on this node will sort on
-		 *  @param {function} [fnCallback] callback function when sort is run
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *
-		 *      // Sort on column 1, when 'sorter' is clicked on
-		 *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
-		 *    } );
-		 */
-		this.fnSortListener = function( nNode, iColumn, fnCallback )
-		{
-			this.api( true ).order.listener( nNode, iColumn, fnCallback );
-		};
-		
-		
-		/**
-		 * Update a table cell or row - this method will accept either a single value to
-		 * update the cell with, an array of values with one element for each column or
-		 * an object in the same format as the original data source. The function is
-		 * self-referencing in order to make the multi column updates easier.
-		 *  @param {object|array|string} mData Data to update the cell/row with
-		 *  @param {node|int} mRow TR element you want to update or the aoData index
-		 *  @param {int} [iColumn] The column to update, give as null or undefined to
-		 *    update a whole row.
-		 *  @param {bool} [bRedraw=true] Redraw the table or not
-		 *  @param {bool} [bAction=true] Perform pre-draw actions or not
-		 *  @returns {int} 0 on success, 1 on error
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
-		 *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
-		 *    } );
-		 */
-		this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
-		{
-			var api = this.api( true );
-		
-			if ( iColumn === undefined || iColumn === null ) {
-				api.row( mRow ).data( mData );
-			}
-			else {
-				api.cell( mRow, iColumn ).data( mData );
-			}
-		
-			if ( bAction === undefined || bAction ) {
-				api.columns.adjust();
-			}
-		
-			if ( bRedraw === undefined || bRedraw ) {
-				api.draw();
-			}
-			return 0;
-		};
-		
-		
-		/**
-		 * Provide a common method for plug-ins to check the version of DataTables being used, in order
-		 * to ensure compatibility.
-		 *  @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
-		 *    formats "X" and "X.Y" are also acceptable.
-		 *  @returns {boolean} true if this version of DataTables is greater or equal to the required
-		 *    version, or false if this version of DataTales is not suitable
-		 *  @method
-		 *  @dtopt API
-		 *  @deprecated Since v1.10
-		 *
-		 *  @example
-		 *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *      alert( oTable.fnVersionCheck( '1.9.0' ) );
-		 *    } );
-		 */
-		this.fnVersionCheck = _ext.fnVersionCheck;
-		
-
-		var _that = this;
-		var emptyInit = options === undefined;
-		var len = this.length;
-
-		if ( emptyInit ) {
-			options = {};
-		}
-
-		this.oApi = this.internal = _ext.internal;
-
-		// Extend with old style plug-in API methods
-		for ( var fn in DataTable.ext.internal ) {
-			if ( fn ) {
-				this[fn] = _fnExternApiFunc(fn);
-			}
-		}
-
-		this.each(function() {
-			// For each initialisation we want to give it a clean initialisation
-			// object that can be bashed around
-			var o = {};
-			var oInit = len > 1 ? // optimisation for single table case
-				_fnExtend( o, options, true ) :
-				options;
-
-			/*global oInit,_that,emptyInit*/
-			var i=0, iLen, j, jLen, k, kLen;
-			var sId = this.getAttribute( 'id' );
-			var bInitHandedOff = false;
-			var defaults = DataTable.defaults;
-			var $this = $(this);
-			
-			
-			/* Sanity check */
-			if ( this.nodeName.toLowerCase() != 'table' )
-			{
-				_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
-				return;
-			}
-			
-			/* Backwards compatibility for the defaults */
-			_fnCompatOpts( defaults );
-			_fnCompatCols( defaults.column );
-			
-			/* Convert the camel-case defaults to Hungarian */
-			_fnCamelToHungarian( defaults, defaults, true );
-			_fnCamelToHungarian( defaults.column, defaults.column, true );
-			
-			/* Setting up the initialisation object */
-			_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true );
-			
-			
-			
-			/* Check to see if we are re-initialising a table */
-			var allSettings = DataTable.settings;
-			for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
-			{
-				var s = allSettings[i];
-			
-				/* Base check on table node */
-				if (
-					s.nTable == this ||
-					(s.nTHead && s.nTHead.parentNode == this) ||
-					(s.nTFoot && s.nTFoot.parentNode == this)
-				) {
-					var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
-					var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
-			
-					if ( emptyInit || bRetrieve )
-					{
-						return s.oInstance;
-					}
-					else if ( bDestroy )
-					{
-						s.oInstance.fnDestroy();
-						break;
-					}
-					else
-					{
-						_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
-						return;
-					}
-				}
-			
-				/* If the element we are initialising has the same ID as a table which was previously
-				 * initialised, but the table nodes don't match (from before) then we destroy the old
-				 * instance by simply deleting it. This is under the assumption that the table has been
-				 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
-				 */
-				if ( s.sTableId == this.id )
-				{
-					allSettings.splice( i, 1 );
-					break;
-				}
-			}
-			
-			/* Ensure the table has an ID - required for accessibility */
-			if ( sId === null || sId === "" )
-			{
-				sId = "DataTables_Table_"+(DataTable.ext._unique++);
-				this.id = sId;
-			}
-			
-			/* Create the settings object for this table and set some of the default parameters */
-			var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
-				"sDestroyWidth": $this[0].style.width,
-				"sInstance":     sId,
-				"sTableId":      sId
-			} );
-			oSettings.nTable = this;
-			oSettings.oApi   = _that.internal;
-			oSettings.oInit  = oInit;
-			
-			allSettings.push( oSettings );
-			
-			// Need to add the instance after the instance after the settings object has been added
-			// to the settings array, so we can self reference the table instance if more than one
-			oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
-			
-			// Backwards compatibility, before we apply all the defaults
-			_fnCompatOpts( oInit );
-			_fnLanguageCompat( oInit.oLanguage );
-			
-			// If the length menu is given, but the init display length is not, use the length menu
-			if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
-			{
-				oInit.iDisplayLength = Array.isArray( oInit.aLengthMenu[0] ) ?
-					oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
-			}
-			
-			// Apply the defaults and init options to make a single init object will all
-			// options defined from defaults and instance options.
-			oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
-			
-			
-			// Map the initialisation options onto the settings object
-			_fnMap( oSettings.oFeatures, oInit, [
-				"bPaginate",
-				"bLengthChange",
-				"bFilter",
-				"bSort",
-				"bSortMulti",
-				"bInfo",
-				"bProcessing",
-				"bAutoWidth",
-				"bSortClasses",
-				"bServerSide",
-				"bDeferRender"
-			] );
-			_fnMap( oSettings, oInit, [
-				"asStripeClasses",
-				"ajax",
-				"fnServerData",
-				"fnFormatNumber",
-				"sServerMethod",
-				"aaSorting",
-				"aaSortingFixed",
-				"aLengthMenu",
-				"sPaginationType",
-				"sAjaxSource",
-				"sAjaxDataProp",
-				"iStateDuration",
-				"sDom",
-				"bSortCellsTop",
-				"iTabIndex",
-				"fnStateLoadCallback",
-				"fnStateSaveCallback",
-				"renderer",
-				"searchDelay",
-				"rowId",
-				[ "iCookieDuration", "iStateDuration" ], // backwards compat
-				[ "oSearch", "oPreviousSearch" ],
-				[ "aoSearchCols", "aoPreSearchCols" ],
-				[ "iDisplayLength", "_iDisplayLength" ]
-			] );
-			_fnMap( oSettings.oScroll, oInit, [
-				[ "sScrollX", "sX" ],
-				[ "sScrollXInner", "sXInner" ],
-				[ "sScrollY", "sY" ],
-				[ "bScrollCollapse", "bCollapse" ]
-			] );
-			_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
-			
-			/* Callback functions which are array driven */
-			_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );
-			_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );
-			_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );
-			_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );
-			_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );
-			_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );
-			_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );
-			_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );
-			_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );
-			_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );
-			_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );
-			
-			oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
-			
-			/* Browser support detection */
-			_fnBrowserDetect( oSettings );
-			
-			var oClasses = oSettings.oClasses;
-			
-			$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
-			$this.addClass( oClasses.sTable );
-			
-			
-			if ( oSettings.iInitDisplayStart === undefined )
-			{
-				/* Display start point, taking into account the save saving */
-				oSettings.iInitDisplayStart = oInit.iDisplayStart;
-				oSettings._iDisplayStart = oInit.iDisplayStart;
-			}
-			
-			if ( oInit.iDeferLoading !== null )
-			{
-				oSettings.bDeferLoading = true;
-				var tmp = Array.isArray( oInit.iDeferLoading );
-				oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
-				oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
-			}
-			
-			/* Language definitions */
-			var oLanguage = oSettings.oLanguage;
-			$.extend( true, oLanguage, oInit.oLanguage );
-			
-			if ( oLanguage.sUrl )
-			{
-				/* Get the language definitions from a file - because this Ajax call makes the language
-				 * get async to the remainder of this function we use bInitHandedOff to indicate that
-				 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
-				 */
-				$.ajax( {
-					dataType: 'json',
-					url: oLanguage.sUrl,
-					success: function ( json ) {
-						_fnLanguageCompat( json );
-						_fnCamelToHungarian( defaults.oLanguage, json );
-						$.extend( true, oLanguage, json );
-						_fnInitialise( oSettings );
-					},
-					error: function () {
-						// Error occurred loading language file, continue on as best we can
-						_fnInitialise( oSettings );
-					}
-				} );
-				bInitHandedOff = true;
-			}
-			
-			/*
-			 * Stripes
-			 */
-			if ( oInit.asStripeClasses === null )
-			{
-				oSettings.asStripeClasses =[
-					oClasses.sStripeOdd,
-					oClasses.sStripeEven
-				];
-			}
-			
-			/* Remove row stripe classes if they are already on the table row */
-			var stripeClasses = oSettings.asStripeClasses;
-			var rowOne = $this.children('tbody').find('tr').eq(0);
-			if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
-				return rowOne.hasClass(el);
-			} ) ) !== -1 ) {
-				$('tbody tr', this).removeClass( stripeClasses.join(' ') );
-				oSettings.asDestroyStripes = stripeClasses.slice();
-			}
-			
-			/*
-			 * Columns
-			 * See if we should load columns automatically or use defined ones
-			 */
-			var anThs = [];
-			var aoColumnsInit;
-			var nThead = this.getElementsByTagName('thead');
-			if ( nThead.length !== 0 )
-			{
-				_fnDetectHeader( oSettings.aoHeader, nThead[0] );
-				anThs = _fnGetUniqueThs( oSettings );
-			}
-			
-			/* If not given a column array, generate one with nulls */
-			if ( oInit.aoColumns === null )
-			{
-				aoColumnsInit = [];
-				for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
-				{
-					aoColumnsInit.push( null );
-				}
-			}
-			else
-			{
-				aoColumnsInit = oInit.aoColumns;
-			}
-			
-			/* Add the columns */
-			for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
-			{
-				_fnAddColumn( oSettings, anThs ? anThs[i] : null );
-			}
-			
-			/* Apply the column definitions */
-			_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
-				_fnColumnOptions( oSettings, iCol, oDef );
-			} );
-			
-			/* HTML5 attribute detection - build an mData object automatically if the
-			 * attributes are found
-			 */
-			if ( rowOne.length ) {
-				var a = function ( cell, name ) {
-					return cell.getAttribute( 'data-'+name ) !== null ? name : null;
-				};
-			
-				$( rowOne[0] ).children('th, td').each( function (i, cell) {
-					var col = oSettings.aoColumns[i];
-			
-					if ( col.mData === i ) {
-						var sort = a( cell, 'sort' ) || a( cell, 'order' );
-						var filter = a( cell, 'filter' ) || a( cell, 'search' );
-			
-						if ( sort !== null || filter !== null ) {
-							col.mData = {
-								_:      i+'.display',
-								sort:   sort !== null   ? i+'.@data-'+sort   : undefined,
-								type:   sort !== null   ? i+'.@data-'+sort   : undefined,
-								filter: filter !== null ? i+'.@data-'+filter : undefined
-							};
-			
-							_fnColumnOptions( oSettings, i );
-						}
-					}
-				} );
-			}
-			
-			var features = oSettings.oFeatures;
-			var loadedInit = function () {
-				/*
-				 * Sorting
-				 * @todo For modularisation (1.11) this needs to do into a sort start up handler
-				 */
-			
-				// If aaSorting is not defined, then we use the first indicator in asSorting
-				// in case that has been altered, so the default sort reflects that option
-				if ( oInit.aaSorting === undefined ) {
-					var sorting = oSettings.aaSorting;
-					for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
-						sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
-					}
-				}
-			
-				/* Do a first pass on the sorting classes (allows any size changes to be taken into
-				 * account, and also will apply sorting disabled classes if disabled
-				 */
-				_fnSortingClasses( oSettings );
-			
-				if ( features.bSort ) {
-					_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
-						if ( oSettings.bSorted ) {
-							var aSort = _fnSortFlatten( oSettings );
-							var sortedColumns = {};
-			
-							$.each( aSort, function (i, val) {
-								sortedColumns[ val.src ] = val.dir;
-							} );
-			
-							_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
-							_fnSortAria( oSettings );
-						}
-					} );
-				}
-			
-				_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
-					if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
-						_fnSortingClasses( oSettings );
-					}
-				}, 'sc' );
-			
-			
-				/*
-				 * Final init
-				 * Cache the header, body and footer as required, creating them if needed
-				 */
-			
-				// Work around for Webkit bug 83867 - store the caption-side before removing from doc
-				var captions = $this.children('caption').each( function () {
-					this._captionSide = $(this).css('caption-side');
-				} );
-			
-				var thead = $this.children('thead');
-				if ( thead.length === 0 ) {
-					thead = $('<thead/>').appendTo($this);
-				}
-				oSettings.nTHead = thead[0];
-			
-				var tbody = $this.children('tbody');
-				if ( tbody.length === 0 ) {
-					tbody = $('<tbody/>').appendTo($this);
-				}
-				oSettings.nTBody = tbody[0];
-			
-				var tfoot = $this.children('tfoot');
-				if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
-					// If we are a scrolling table, and no footer has been given, then we need to create
-					// a tfoot element for the caption element to be appended to
-					tfoot = $('<tfoot/>').appendTo($this);
-				}
-			
-				if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
-					$this.addClass( oClasses.sNoFooter );
-				}
-				else if ( tfoot.length > 0 ) {
-					oSettings.nTFoot = tfoot[0];
-					_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
-				}
-			
-				/* Check if there is data passing into the constructor */
-				if ( oInit.aaData ) {
-					for ( i=0 ; i<oInit.aaData.length ; i++ ) {
-						_fnAddData( oSettings, oInit.aaData[ i ] );
-					}
-				}
-				else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
-					/* Grab the data from the page - only do this when deferred loading or no Ajax
-					 * source since there is no point in reading the DOM data if we are then going
-					 * to replace it with Ajax data
-					 */
-					_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
-				}
-			
-				/* Copy the data index array */
-				oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
-			
-				/* Initialisation complete - table can be drawn */
-				oSettings.bInitialised = true;
-			
-				/* Check if we need to initialise the table (it might not have been handed off to the
-				 * language processor)
-				 */
-				if ( bInitHandedOff === false ) {
-					_fnInitialise( oSettings );
-				}
-			};
-			
-			/* Must be done after everything which can be overridden by the state saving! */
-			if ( oInit.bStateSave )
-			{
-				features.bStateSave = true;
-				_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
-				_fnLoadState( oSettings, oInit, loadedInit );
-			}
-			else {
-				loadedInit();
-			}
-			
-		} );
-		_that = null;
-		return this;
-	};
-
-	
-	/*
-	 * It is useful to have variables which are scoped locally so only the
-	 * DataTables functions can access them and they don't leak into global space.
-	 * At the same time these functions are often useful over multiple files in the
-	 * core and API, so we list, or at least document, all variables which are used
-	 * by DataTables as private variables here. This also ensures that there is no
-	 * clashing of variable names and that they can easily referenced for reuse.
-	 */
-	
-	
-	// Defined else where
-	//  _selector_run
-	//  _selector_opts
-	//  _selector_first
-	//  _selector_row_indexes
-	
-	var _ext; // DataTable.ext
-	var _Api; // DataTable.Api
-	var _api_register; // DataTable.Api.register
-	var _api_registerPlural; // DataTable.Api.registerPlural
-	
-	var _re_dic = {};
-	var _re_new_lines = /[\r\n\u2028]/g;
-	var _re_html = /<.*?>/g;
-	
-	// This is not strict ISO8601 - Date.parse() is quite lax, although
-	// implementations differ between browsers.
-	var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
-	
-	// Escape regular expression special characters
-	var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
-	
-	// http://en.wikipedia.org/wiki/Foreign_exchange_market
-	// - \u20BD - Russian ruble.
-	// - \u20a9 - South Korean Won
-	// - \u20BA - Turkish Lira
-	// - \u20B9 - Indian Rupee
-	// - R - Brazil (R$) and South Africa
-	// - fr - Swiss Franc
-	// - kr - Swedish krona, Norwegian krone and Danish krone
-	// - \u2009 is thin space and \u202F is narrow no-break space, both used in many
-	// - Ƀ - Bitcoin
-	// - Ξ - Ethereum
-	//   standards as thousands separators.
-	var _re_formatted_numeric = /['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
-	
-	
-	var _empty = function ( d ) {
-		return !d || d === true || d === '-' ? true : false;
-	};
-	
-	
-	var _intVal = function ( s ) {
-		var integer = parseInt( s, 10 );
-		return !isNaN(integer) && isFinite(s) ? integer : null;
-	};
-	
-	// Convert from a formatted number with characters other than `.` as the
-	// decimal place, to a Javascript number
-	var _numToDecimal = function ( num, decimalPoint ) {
-		// Cache created regular expressions for speed as this function is called often
-		if ( ! _re_dic[ decimalPoint ] ) {
-			_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
-		}
-		return typeof num === 'string' && decimalPoint !== '.' ?
-			num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
-			num;
-	};
-	
-	
-	var _isNumber = function ( d, decimalPoint, formatted ) {
-		var strType = typeof d === 'string';
-	
-		// If empty return immediately so there must be a number if it is a
-		// formatted string (this stops the string "k", or "kr", etc being detected
-		// as a formatted number for currency
-		if ( _empty( d ) ) {
-			return true;
-		}
-	
-		if ( decimalPoint && strType ) {
-			d = _numToDecimal( d, decimalPoint );
-		}
-	
-		if ( formatted && strType ) {
-			d = d.replace( _re_formatted_numeric, '' );
-		}
-	
-		return !isNaN( parseFloat(d) ) && isFinite( d );
-	};
-	
-	
-	// A string without HTML in it can be considered to be HTML still
-	var _isHtml = function ( d ) {
-		return _empty( d ) || typeof d === 'string';
-	};
-	
-	
-	var _htmlNumeric = function ( d, decimalPoint, formatted ) {
-		if ( _empty( d ) ) {
-			return true;
-		}
-	
-		var html = _isHtml( d );
-		return ! html ?
-			null :
-			_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
-				true :
-				null;
-	};
-	
-	
-	var _pluck = function ( a, prop, prop2 ) {
-		var out = [];
-		var i=0, ien=a.length;
-	
-		// Could have the test in the loop for slightly smaller code, but speed
-		// is essential here
-		if ( prop2 !== undefined ) {
-			for ( ; i<ien ; i++ ) {
-				if ( a[i] && a[i][ prop ] ) {
-					out.push( a[i][ prop ][ prop2 ] );
-				}
-			}
-		}
-		else {
-			for ( ; i<ien ; i++ ) {
-				if ( a[i] ) {
-					out.push( a[i][ prop ] );
-				}
-			}
-		}
-	
-		return out;
-	};
-	
-	
-	// Basically the same as _pluck, but rather than looping over `a` we use `order`
-	// as the indexes to pick from `a`
-	var _pluck_order = function ( a, order, prop, prop2 )
-	{
-		var out = [];
-		var i=0, ien=order.length;
-	
-		// Could have the test in the loop for slightly smaller code, but speed
-		// is essential here
-		if ( prop2 !== undefined ) {
-			for ( ; i<ien ; i++ ) {
-				if ( a[ order[i] ][ prop ] ) {
-					out.push( a[ order[i] ][ prop ][ prop2 ] );
-				}
-			}
-		}
-		else {
-			for ( ; i<ien ; i++ ) {
-				out.push( a[ order[i] ][ prop ] );
-			}
-		}
-	
-		return out;
-	};
-	
-	
-	var _range = function ( len, start )
-	{
-		var out = [];
-		var end;
-	
-		if ( start === undefined ) {
-			start = 0;
-			end = len;
-		}
-		else {
-			end = start;
-			start = len;
-		}
-	
-		for ( var i=start ; i<end ; i++ ) {
-			out.push( i );
-		}
-	
-		return out;
-	};
-	
-	
-	var _removeEmpty = function ( a )
-	{
-		var out = [];
-	
-		for ( var i=0, ien=a.length ; i<ien ; i++ ) {
-			if ( a[i] ) { // careful - will remove all falsy values!
-				out.push( a[i] );
-			}
-		}
-	
-		return out;
-	};
-	
-	
-	var _stripHtml = function ( d ) {
-		return d.replace( _re_html, '' );
-	};
-	
-	
-	/**
-	 * Determine if all values in the array are unique. This means we can short
-	 * cut the _unique method at the cost of a single loop. A sorted array is used
-	 * to easily check the values.
-	 *
-	 * @param  {array} src Source array
-	 * @return {boolean} true if all unique, false otherwise
-	 * @ignore
-	 */
-	var _areAllUnique = function ( src ) {
-		if ( src.length < 2 ) {
-			return true;
-		}
-	
-		var sorted = src.slice().sort();
-		var last = sorted[0];
-	
-		for ( var i=1, ien=sorted.length ; i<ien ; i++ ) {
-			if ( sorted[i] === last ) {
-				return false;
-			}
-	
-			last = sorted[i];
-		}
-	
-		return true;
-	};
-	
-	
-	/**
-	 * Find the unique elements in a source array.
-	 *
-	 * @param  {array} src Source array
-	 * @return {array} Array of unique items
-	 * @ignore
-	 */
-	var _unique = function ( src )
-	{
-		if ( _areAllUnique( src ) ) {
-			return src.slice();
-		}
-	
-		// A faster unique method is to use object keys to identify used values,
-		// but this doesn't work with arrays or objects, which we must also
-		// consider. See jsperf.com/compare-array-unique-versions/4 for more
-		// information.
-		var
-			out = [],
-			val,
-			i, ien=src.length,
-			j, k=0;
-	
-		again: for ( i=0 ; i<ien ; i++ ) {
-			val = src[i];
-	
-			for ( j=0 ; j<k ; j++ ) {
-				if ( out[j] === val ) {
-					continue again;
-				}
-			}
-	
-			out.push( val );
-			k++;
-		}
-	
-		return out;
-	};
-	
-	// Surprisingly this is faster than [].concat.apply
-	// https://jsperf.com/flatten-an-array-loop-vs-reduce/2
-	var _flatten = function (out, val) {
-		if (Array.isArray(val)) {
-			for (var i=0 ; i<val.length ; i++) {
-				_flatten(out, val[i]);
-			}
-		}
-		else {
-			out.push(val);
-		}
-	  
-		return out;
-	}
-	
-	// Array.isArray polyfill.
-	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
-	if (! Array.isArray) {
-	    Array.isArray = function(arg) {
-	        return Object.prototype.toString.call(arg) === '[object Array]';
-	    };
-	}
-	
-	// .trim() polyfill
-	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim
-	if (!String.prototype.trim) {
-	  String.prototype.trim = function () {
-	    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
-	  };
-	}
-	
-	/**
-	 * DataTables utility methods
-	 * 
-	 * This namespace provides helper methods that DataTables uses internally to
-	 * create a DataTable, but which are not exclusively used only for DataTables.
-	 * These methods can be used by extension authors to save the duplication of
-	 * code.
-	 *
-	 *  @namespace
-	 */
-	DataTable.util = {
-		/**
-		 * Throttle the calls to a function. Arguments and context are maintained
-		 * for the throttled function.
-		 *
-		 * @param {function} fn Function to be called
-		 * @param {integer} freq Call frequency in mS
-		 * @return {function} Wrapped function
-		 */
-		throttle: function ( fn, freq ) {
-			var
-				frequency = freq !== undefined ? freq : 200,
-				last,
-				timer;
-	
-			return function () {
-				var
-					that = this,
-					now  = +new Date(),
-					args = arguments;
-	
-				if ( last && now < last + frequency ) {
-					clearTimeout( timer );
-	
-					timer = setTimeout( function () {
-						last = undefined;
-						fn.apply( that, args );
-					}, frequency );
-				}
-				else {
-					last = now;
-					fn.apply( that, args );
-				}
-			};
-		},
-	
-	
-		/**
-		 * Escape a string such that it can be used in a regular expression
-		 *
-		 *  @param {string} val string to escape
-		 *  @returns {string} escaped string
-		 */
-		escapeRegex: function ( val ) {
-			return val.replace( _re_escape_regex, '\\$1' );
-		}
-	};
-	
-	
-	
-	/**
-	 * Create a mapping object that allows camel case parameters to be looked up
-	 * for their Hungarian counterparts. The mapping is stored in a private
-	 * parameter called `_hungarianMap` which can be accessed on the source object.
-	 *  @param {object} o
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnHungarianMap ( o )
-	{
-		var
-			hungarian = 'a aa ai ao as b fn i m o s ',
-			match,
-			newKey,
-			map = {};
-	
-		$.each( o, function (key, val) {
-			match = key.match(/^([^A-Z]+?)([A-Z])/);
-	
-			if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
-			{
-				newKey = key.replace( match[0], match[2].toLowerCase() );
-				map[ newKey ] = key;
-	
-				if ( match[1] === 'o' )
-				{
-					_fnHungarianMap( o[key] );
-				}
-			}
-		} );
-	
-		o._hungarianMap = map;
-	}
-	
-	
-	/**
-	 * Convert from camel case parameters to Hungarian, based on a Hungarian map
-	 * created by _fnHungarianMap.
-	 *  @param {object} src The model object which holds all parameters that can be
-	 *    mapped.
-	 *  @param {object} user The object to convert from camel case to Hungarian.
-	 *  @param {boolean} force When set to `true`, properties which already have a
-	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
-	 *    won't be.
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnCamelToHungarian ( src, user, force )
-	{
-		if ( ! src._hungarianMap ) {
-			_fnHungarianMap( src );
-		}
-	
-		var hungarianKey;
-	
-		$.each( user, function (key, val) {
-			hungarianKey = src._hungarianMap[ key ];
-	
-			if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
-			{
-				// For objects, we need to buzz down into the object to copy parameters
-				if ( hungarianKey.charAt(0) === 'o' )
-				{
-					// Copy the camelCase options over to the hungarian
-					if ( ! user[ hungarianKey ] ) {
-						user[ hungarianKey ] = {};
-					}
-					$.extend( true, user[hungarianKey], user[key] );
-	
-					_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
-				}
-				else {
-					user[hungarianKey] = user[ key ];
-				}
-			}
-		} );
-	}
-	
-	
-	/**
-	 * Language compatibility - when certain options are given, and others aren't, we
-	 * need to duplicate the values over, in order to provide backwards compatibility
-	 * with older language files.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnLanguageCompat( lang )
-	{
-		// Note the use of the Hungarian notation for the parameters in this method as
-		// this is called after the mapping of camelCase to Hungarian
-		var defaults = DataTable.defaults.oLanguage;
-	
-		// Default mapping
-		var defaultDecimal = defaults.sDecimal;
-		if ( defaultDecimal ) {
-			_addNumericSort( defaultDecimal );
-		}
-	
-		if ( lang ) {
-			var zeroRecords = lang.sZeroRecords;
-	
-			// Backwards compatibility - if there is no sEmptyTable given, then use the same as
-			// sZeroRecords - assuming that is given.
-			if ( ! lang.sEmptyTable && zeroRecords &&
-				defaults.sEmptyTable === "No data available in table" )
-			{
-				_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
-			}
-	
-			// Likewise with loading records
-			if ( ! lang.sLoadingRecords && zeroRecords &&
-				defaults.sLoadingRecords === "Loading..." )
-			{
-				_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
-			}
-	
-			// Old parameter name of the thousands separator mapped onto the new
-			if ( lang.sInfoThousands ) {
-				lang.sThousands = lang.sInfoThousands;
-			}
-	
-			var decimal = lang.sDecimal;
-			if ( decimal && defaultDecimal !== decimal ) {
-				_addNumericSort( decimal );
-			}
-		}
-	}
-	
-	
-	/**
-	 * Map one parameter onto another
-	 *  @param {object} o Object to map
-	 *  @param {*} knew The new parameter name
-	 *  @param {*} old The old parameter name
-	 */
-	var _fnCompatMap = function ( o, knew, old ) {
-		if ( o[ knew ] !== undefined ) {
-			o[ old ] = o[ knew ];
-		}
-	};
-	
-	
-	/**
-	 * Provide backwards compatibility for the main DT options. Note that the new
-	 * options are mapped onto the old parameters, so this is an external interface
-	 * change only.
-	 *  @param {object} init Object to map
-	 */
-	function _fnCompatOpts ( init )
-	{
-		_fnCompatMap( init, 'ordering',      'bSort' );
-		_fnCompatMap( init, 'orderMulti',    'bSortMulti' );
-		_fnCompatMap( init, 'orderClasses',  'bSortClasses' );
-		_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
-		_fnCompatMap( init, 'order',         'aaSorting' );
-		_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );
-		_fnCompatMap( init, 'paging',        'bPaginate' );
-		_fnCompatMap( init, 'pagingType',    'sPaginationType' );
-		_fnCompatMap( init, 'pageLength',    'iDisplayLength' );
-		_fnCompatMap( init, 'searching',     'bFilter' );
-	
-		// Boolean initialisation of x-scrolling
-		if ( typeof init.sScrollX === 'boolean' ) {
-			init.sScrollX = init.sScrollX ? '100%' : '';
-		}
-		if ( typeof init.scrollX === 'boolean' ) {
-			init.scrollX = init.scrollX ? '100%' : '';
-		}
-	
-		// Column search objects are in an array, so it needs to be converted
-		// element by element
-		var searchCols = init.aoSearchCols;
-	
-		if ( searchCols ) {
-			for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
-				if ( searchCols[i] ) {
-					_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
-				}
-			}
-		}
-	}
-	
-	
-	/**
-	 * Provide backwards compatibility for column options. Note that the new options
-	 * are mapped onto the old parameters, so this is an external interface change
-	 * only.
-	 *  @param {object} init Object to map
-	 */
-	function _fnCompatCols ( init )
-	{
-		_fnCompatMap( init, 'orderable',     'bSortable' );
-		_fnCompatMap( init, 'orderData',     'aDataSort' );
-		_fnCompatMap( init, 'orderSequence', 'asSorting' );
-		_fnCompatMap( init, 'orderDataType', 'sortDataType' );
-	
-		// orderData can be given as an integer
-		var dataSort = init.aDataSort;
-		if ( typeof dataSort === 'number' && ! Array.isArray( dataSort ) ) {
-			init.aDataSort = [ dataSort ];
-		}
-	}
-	
-	
-	/**
-	 * Browser feature detection for capabilities, quirks
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnBrowserDetect( settings )
-	{
-		// We don't need to do this every time DataTables is constructed, the values
-		// calculated are specific to the browser and OS configuration which we
-		// don't expect to change between initialisations
-		if ( ! DataTable.__browser ) {
-			var browser = {};
-			DataTable.__browser = browser;
-	
-			// Scrolling feature / quirks detection
-			var n = $('<div/>')
-				.css( {
-					position: 'fixed',
-					top: 0,
-					left: $(window).scrollLeft()*-1, // allow for scrolling
-					height: 1,
-					width: 1,
-					overflow: 'hidden'
-				} )
-				.append(
-					$('<div/>')
-						.css( {
-							position: 'absolute',
-							top: 1,
-							left: 1,
-							width: 100,
-							overflow: 'scroll'
-						} )
-						.append(
-							$('<div/>')
-								.css( {
-									width: '100%',
-									height: 10
-								} )
-						)
-				)
-				.appendTo( 'body' );
-	
-			var outer = n.children();
-			var inner = outer.children();
-	
-			// Numbers below, in order, are:
-			// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
-			//
-			// IE6 XP:                           100 100 100  83
-			// IE7 Vista:                        100 100 100  83
-			// IE 8+ Windows:                     83  83 100  83
-			// Evergreen Windows:                 83  83 100  83
-			// Evergreen Mac with scrollbars:     85  85 100  85
-			// Evergreen Mac without scrollbars: 100 100 100 100
-	
-			// Get scrollbar width
-			browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
-	
-			// IE6/7 will oversize a width 100% element inside a scrolling element, to
-			// include the width of the scrollbar, while other browsers ensure the inner
-			// element is contained without forcing scrolling
-			browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
-	
-			// In rtl text layout, some browsers (most, but not all) will place the
-			// scrollbar on the left, rather than the right.
-			browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
-	
-			// IE8- don't provide height and width for getBoundingClientRect
-			browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
-	
-			n.remove();
-		}
-	
-		$.extend( settings.oBrowser, DataTable.__browser );
-		settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
-	}
-	
-	
-	/**
-	 * Array.prototype reduce[Right] method, used for browsers which don't support
-	 * JS 1.6. Done this way to reduce code size, since we iterate either way
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnReduce ( that, fn, init, start, end, inc )
-	{
-		var
-			i = start,
-			value,
-			isSet = false;
-	
-		if ( init !== undefined ) {
-			value = init;
-			isSet = true;
-		}
-	
-		while ( i !== end ) {
-			if ( ! that.hasOwnProperty(i) ) {
-				continue;
-			}
-	
-			value = isSet ?
-				fn( value, that[i], i, that ) :
-				that[i];
-	
-			isSet = true;
-			i += inc;
-		}
-	
-		return value;
-	}
-	
-	/**
-	 * Add a column to the list used for the table with default values
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {node} nTh The th element for this column
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAddColumn( oSettings, nTh )
-	{
-		// Add column to aoColumns array
-		var oDefaults = DataTable.defaults.column;
-		var iCol = oSettings.aoColumns.length;
-		var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
-			"nTh": nTh ? nTh : document.createElement('th'),
-			"sTitle":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',
-			"aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
-			"mData": oDefaults.mData ? oDefaults.mData : iCol,
-			idx: iCol
-		} );
-		oSettings.aoColumns.push( oCol );
-	
-		// Add search object for column specific search. Note that the `searchCols[ iCol ]`
-		// passed into extend can be undefined. This allows the user to give a default
-		// with only some of the parameters defined, and also not give a default
-		var searchCols = oSettings.aoPreSearchCols;
-		searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
-	
-		// Use the default column options function to initialise classes etc
-		_fnColumnOptions( oSettings, iCol, $(nTh).data() );
-	}
-	
-	
-	/**
-	 * Apply options for a column
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {int} iCol column index to consider
-	 *  @param {object} oOptions object with sType, bVisible and bSearchable etc
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnColumnOptions( oSettings, iCol, oOptions )
-	{
-		var oCol = oSettings.aoColumns[ iCol ];
-		var oClasses = oSettings.oClasses;
-		var th = $(oCol.nTh);
-	
-		// Try to get width information from the DOM. We can't get it from CSS
-		// as we'd need to parse the CSS stylesheet. `width` option can override
-		if ( ! oCol.sWidthOrig ) {
-			// Width attribute
-			oCol.sWidthOrig = th.attr('width') || null;
-	
-			// Style attribute
-			var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
-			if ( t ) {
-				oCol.sWidthOrig = t[1];
-			}
-		}
-	
-		/* User specified column options */
-		if ( oOptions !== undefined && oOptions !== null )
-		{
-			// Backwards compatibility
-			_fnCompatCols( oOptions );
-	
-			// Map camel case parameters to their Hungarian counterparts
-			_fnCamelToHungarian( DataTable.defaults.column, oOptions, true );
-	
-			/* Backwards compatibility for mDataProp */
-			if ( oOptions.mDataProp !== undefined && !oOptions.mData )
-			{
-				oOptions.mData = oOptions.mDataProp;
-			}
-	
-			if ( oOptions.sType )
-			{
-				oCol._sManualType = oOptions.sType;
-			}
-	
-			// `class` is a reserved word in Javascript, so we need to provide
-			// the ability to use a valid name for the camel case input
-			if ( oOptions.className && ! oOptions.sClass )
-			{
-				oOptions.sClass = oOptions.className;
-			}
-			if ( oOptions.sClass ) {
-				th.addClass( oOptions.sClass );
-			}
-	
-			$.extend( oCol, oOptions );
-			_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
-	
-			/* iDataSort to be applied (backwards compatibility), but aDataSort will take
-			 * priority if defined
-			 */
-			if ( oOptions.iDataSort !== undefined )
-			{
-				oCol.aDataSort = [ oOptions.iDataSort ];
-			}
-			_fnMap( oCol, oOptions, "aDataSort" );
-		}
-	
-		/* Cache the data get and set functions for speed */
-		var mDataSrc = oCol.mData;
-		var mData = _fnGetObjectDataFn( mDataSrc );
-		var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
-	
-		var attrTest = function( src ) {
-			return typeof src === 'string' && src.indexOf('@') !== -1;
-		};
-		oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
-			attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
-		);
-		oCol._setter = null;
-	
-		oCol.fnGetData = function (rowData, type, meta) {
-			var innerData = mData( rowData, type, undefined, meta );
-	
-			return mRender && type ?
-				mRender( innerData, type, rowData, meta ) :
-				innerData;
-		};
-		oCol.fnSetData = function ( rowData, val, meta ) {
-			return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
-		};
-	
-		// Indicate if DataTables should read DOM data as an object or array
-		// Used in _fnGetRowElements
-		if ( typeof mDataSrc !== 'number' ) {
-			oSettings._rowReadObject = true;
-		}
-	
-		/* Feature sorting overrides column specific when off */
-		if ( !oSettings.oFeatures.bSort )
-		{
-			oCol.bSortable = false;
-			th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
-		}
-	
-		/* Check that the class assignment is correct for sorting */
-		var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
-		var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
-		if ( !oCol.bSortable || (!bAsc && !bDesc) )
-		{
-			oCol.sSortingClass = oClasses.sSortableNone;
-			oCol.sSortingClassJUI = "";
-		}
-		else if ( bAsc && !bDesc )
-		{
-			oCol.sSortingClass = oClasses.sSortableAsc;
-			oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
-		}
-		else if ( !bAsc && bDesc )
-		{
-			oCol.sSortingClass = oClasses.sSortableDesc;
-			oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
-		}
-		else
-		{
-			oCol.sSortingClass = oClasses.sSortable;
-			oCol.sSortingClassJUI = oClasses.sSortJUI;
-		}
-	}
-	
-	
-	/**
-	 * Adjust the table column widths for new data. Note: you would probably want to
-	 * do a redraw after calling this function!
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAdjustColumnSizing ( settings )
-	{
-		/* Not interested in doing column width calculation if auto-width is disabled */
-		if ( settings.oFeatures.bAutoWidth !== false )
-		{
-			var columns = settings.aoColumns;
-	
-			_fnCalculateColumnWidths( settings );
-			for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
-			{
-				columns[i].nTh.style.width = columns[i].sWidth;
-			}
-		}
-	
-		var scroll = settings.oScroll;
-		if ( scroll.sY !== '' || scroll.sX !== '')
-		{
-			_fnScrollDraw( settings );
-		}
-	
-		_fnCallbackFire( settings, null, 'column-sizing', [settings] );
-	}
-	
-	
-	/**
-	 * Covert the index of a visible column to the index in the data array (take account
-	 * of hidden columns)
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {int} iMatch Visible column index to lookup
-	 *  @returns {int} i the data index
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnVisibleToColumnIndex( oSettings, iMatch )
-	{
-		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
-	
-		return typeof aiVis[iMatch] === 'number' ?
-			aiVis[iMatch] :
-			null;
-	}
-	
-	
-	/**
-	 * Covert the index of an index in the data array and convert it to the visible
-	 *   column index (take account of hidden columns)
-	 *  @param {int} iMatch Column index to lookup
-	 *  @param {object} oSettings dataTables settings object
-	 *  @returns {int} i the data index
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnColumnIndexToVisible( oSettings, iMatch )
-	{
-		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
-		var iPos = $.inArray( iMatch, aiVis );
-	
-		return iPos !== -1 ? iPos : null;
-	}
-	
-	
-	/**
-	 * Get the number of visible columns
-	 *  @param {object} oSettings dataTables settings object
-	 *  @returns {int} i the number of visible columns
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnVisbleColumns( oSettings )
-	{
-		var vis = 0;
-	
-		// No reduce in IE8, use a loop for now
-		$.each( oSettings.aoColumns, function ( i, col ) {
-			if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
-				vis++;
-			}
-		} );
-	
-		return vis;
-	}
-	
-	
-	/**
-	 * Get an array of column indexes that match a given property
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {string} sParam Parameter in aoColumns to look for - typically
-	 *    bVisible or bSearchable
-	 *  @returns {array} Array of indexes with matched properties
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetColumns( oSettings, sParam )
-	{
-		var a = [];
-	
-		$.map( oSettings.aoColumns, function(val, i) {
-			if ( val[sParam] ) {
-				a.push( i );
-			}
-		} );
-	
-		return a;
-	}
-	
-	
-	/**
-	 * Calculate the 'type' of a column
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnColumnTypes ( settings )
-	{
-		var columns = settings.aoColumns;
-		var data = settings.aoData;
-		var types = DataTable.ext.type.detect;
-		var i, ien, j, jen, k, ken;
-		var col, cell, detectedType, cache;
-	
-		// For each column, spin over the 
-		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
-			col = columns[i];
-			cache = [];
-	
-			if ( ! col.sType && col._sManualType ) {
-				col.sType = col._sManualType;
-			}
-			else if ( ! col.sType ) {
-				for ( j=0, jen=types.length ; j<jen ; j++ ) {
-					for ( k=0, ken=data.length ; k<ken ; k++ ) {
-						// Use a cache array so we only need to get the type data
-						// from the formatter once (when using multiple detectors)
-						if ( cache[k] === undefined ) {
-							cache[k] = _fnGetCellData( settings, k, i, 'type' );
-						}
-	
-						detectedType = types[j]( cache[k], settings );
-	
-						// If null, then this type can't apply to this column, so
-						// rather than testing all cells, break out. There is an
-						// exception for the last type which is `html`. We need to
-						// scan all rows since it is possible to mix string and HTML
-						// types
-						if ( ! detectedType && j !== types.length-1 ) {
-							break;
-						}
-	
-						// Only a single match is needed for html type since it is
-						// bottom of the pile and very similar to string
-						if ( detectedType === 'html' ) {
-							break;
-						}
-					}
-	
-					// Type is valid for all data points in the column - use this
-					// type
-					if ( detectedType ) {
-						col.sType = detectedType;
-						break;
-					}
-				}
-	
-				// Fall back - if no type was detected, always use string
-				if ( ! col.sType ) {
-					col.sType = 'string';
-				}
-			}
-		}
-	}
-	
-	
-	/**
-	 * Take the column definitions and static columns arrays and calculate how
-	 * they relate to column indexes. The callback function will then apply the
-	 * definition found for a column to a suitable configuration object.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {array} aoColDefs The aoColumnDefs array that is to be applied
-	 *  @param {array} aoCols The aoColumns array that defines columns individually
-	 *  @param {function} fn Callback function - takes two parameters, the calculated
-	 *    column index and the definition for that column.
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
-	{
-		var i, iLen, j, jLen, k, kLen, def;
-		var columns = oSettings.aoColumns;
-	
-		// Column definitions with aTargets
-		if ( aoColDefs )
-		{
-			/* Loop over the definitions array - loop in reverse so first instance has priority */
-			for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
-			{
-				def = aoColDefs[i];
-	
-				/* Each definition can target multiple columns, as it is an array */
-				var aTargets = def.targets !== undefined ?
-					def.targets :
-					def.aTargets;
-	
-				if ( ! Array.isArray( aTargets ) )
-				{
-					aTargets = [ aTargets ];
-				}
-	
-				for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
-				{
-					if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
-					{
-						/* Add columns that we don't yet know about */
-						while( columns.length <= aTargets[j] )
-						{
-							_fnAddColumn( oSettings );
-						}
-	
-						/* Integer, basic index */
-						fn( aTargets[j], def );
-					}
-					else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
-					{
-						/* Negative integer, right to left column counting */
-						fn( columns.length+aTargets[j], def );
-					}
-					else if ( typeof aTargets[j] === 'string' )
-					{
-						/* Class name matching on TH element */
-						for ( k=0, kLen=columns.length ; k<kLen ; k++ )
-						{
-							if ( aTargets[j] == "_all" ||
-							     $(columns[k].nTh).hasClass( aTargets[j] ) )
-							{
-								fn( k, def );
-							}
-						}
-					}
-				}
-			}
-		}
-	
-		// Statically defined columns array
-		if ( aoCols )
-		{
-			for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
-			{
-				fn( i, aoCols[i] );
-			}
-		}
-	}
-	
-	/**
-	 * Add a data array to the table, creating DOM node etc. This is the parallel to
-	 * _fnGatherData, but for adding rows from a Javascript source, rather than a
-	 * DOM source.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {array} aData data array to be added
-	 *  @param {node} [nTr] TR element to add to the table - optional. If not given,
-	 *    DataTables will create a row automatically
-	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
-	 *    if nTr is.
-	 *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAddData ( oSettings, aDataIn, nTr, anTds )
-	{
-		/* Create the object for storing information about this new row */
-		var iRow = oSettings.aoData.length;
-		var oData = $.extend( true, {}, DataTable.models.oRow, {
-			src: nTr ? 'dom' : 'data',
-			idx: iRow
-		} );
-	
-		oData._aData = aDataIn;
-		oSettings.aoData.push( oData );
-	
-		/* Create the cells */
-		var nTd, sThisType;
-		var columns = oSettings.aoColumns;
-	
-		// Invalidate the column types as the new data needs to be revalidated
-		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
-		{
-			columns[i].sType = null;
-		}
-	
-		/* Add to the display array */
-		oSettings.aiDisplayMaster.push( iRow );
-	
-		var id = oSettings.rowIdFn( aDataIn );
-		if ( id !== undefined ) {
-			oSettings.aIds[ id ] = oData;
-		}
-	
-		/* Create the DOM information, or register it if already present */
-		if ( nTr || ! oSettings.oFeatures.bDeferRender )
-		{
-			_fnCreateTr( oSettings, iRow, nTr, anTds );
-		}
-	
-		return iRow;
-	}
-	
-	
-	/**
-	 * Add one or more TR elements to the table. Generally we'd expect to
-	 * use this for reading data from a DOM sourced table, but it could be
-	 * used for an TR element. Note that if a TR is given, it is used (i.e.
-	 * it is not cloned).
-	 *  @param {object} settings dataTables settings object
-	 *  @param {array|node|jQuery} trs The TR element(s) to add to the table
-	 *  @returns {array} Array of indexes for the added rows
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAddTr( settings, trs )
-	{
-		var row;
-	
-		// Allow an individual node to be passed in
-		if ( ! (trs instanceof $) ) {
-			trs = $(trs);
-		}
-	
-		return trs.map( function (i, el) {
-			row = _fnGetRowElements( settings, el );
-			return _fnAddData( settings, row.data, el, row.cells );
-		} );
-	}
-	
-	
-	/**
-	 * Take a TR element and convert it to an index in aoData
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {node} n the TR element to find
-	 *  @returns {int} index if the node is found, null if not
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnNodeToDataIndex( oSettings, n )
-	{
-		return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
-	}
-	
-	
-	/**
-	 * Take a TD element and convert it into a column data index (not the visible index)
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {int} iRow The row number the TD/TH can be found in
-	 *  @param {node} n The TD/TH element to find
-	 *  @returns {int} index if the node is found, -1 if not
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnNodeToColumnIndex( oSettings, iRow, n )
-	{
-		return $.inArray( n, oSettings.aoData[ iRow ].anCells );
-	}
-	
-	
-	/**
-	 * Get the data for a given cell from the internal cache, taking into account data mapping
-	 *  @param {object} settings dataTables settings object
-	 *  @param {int} rowIdx aoData row id
-	 *  @param {int} colIdx Column index
-	 *  @param {string} type data get type ('display', 'type' 'filter' 'sort')
-	 *  @returns {*} Cell data
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetCellData( settings, rowIdx, colIdx, type )
-	{
-		var draw           = settings.iDraw;
-		var col            = settings.aoColumns[colIdx];
-		var rowData        = settings.aoData[rowIdx]._aData;
-		var defaultContent = col.sDefaultContent;
-		var cellData       = col.fnGetData( rowData, type, {
-			settings: settings,
-			row:      rowIdx,
-			col:      colIdx
-		} );
-	
-		if ( cellData === undefined ) {
-			if ( settings.iDrawError != draw && defaultContent === null ) {
-				_fnLog( settings, 0, "Requested unknown parameter "+
-					(typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
-					" for row "+rowIdx+", column "+colIdx, 4 );
-				settings.iDrawError = draw;
-			}
-			return defaultContent;
-		}
-	
-		// When the data source is null and a specific data type is requested (i.e.
-		// not the original data), we can use default column data
-		if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
-			cellData = defaultContent;
-		}
-		else if ( typeof cellData === 'function' ) {
-			// If the data source is a function, then we run it and use the return,
-			// executing in the scope of the data object (for instances)
-			return cellData.call( rowData );
-		}
-	
-		if ( cellData === null && type == 'display' ) {
-			return '';
-		}
-		return cellData;
-	}
-	
-	
-	/**
-	 * Set the value for a specific cell, into the internal data cache
-	 *  @param {object} settings dataTables settings object
-	 *  @param {int} rowIdx aoData row id
-	 *  @param {int} colIdx Column index
-	 *  @param {*} val Value to set
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSetCellData( settings, rowIdx, colIdx, val )
-	{
-		var col     = settings.aoColumns[colIdx];
-		var rowData = settings.aoData[rowIdx]._aData;
-	
-		col.fnSetData( rowData, val, {
-			settings: settings,
-			row:      rowIdx,
-			col:      colIdx
-		}  );
-	}
-	
-	
-	// Private variable that is used to match action syntax in the data property object
-	var __reArray = /\[.*?\]$/;
-	var __reFn = /\(\)$/;
-	
-	/**
-	 * Split string on periods, taking into account escaped periods
-	 * @param  {string} str String to split
-	 * @return {array} Split string
-	 */
-	function _fnSplitObjNotation( str )
-	{
-		return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
-			return s.replace(/\\\./g, '.');
-		} );
-	}
-	
-	
-	/**
-	 * Return a function that can be used to get data from a source object, taking
-	 * into account the ability to use nested objects as a source
-	 *  @param {string|int|function} mSource The data source for the object
-	 *  @returns {function} Data get function
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetObjectDataFn( mSource )
-	{
-		if ( $.isPlainObject( mSource ) )
-		{
-			/* Build an object of get functions, and wrap them in a single call */
-			var o = {};
-			$.each( mSource, function (key, val) {
-				if ( val ) {
-					o[key] = _fnGetObjectDataFn( val );
-				}
-			} );
-	
-			return function (data, type, row, meta) {
-				var t = o[type] || o._;
-				return t !== undefined ?
-					t(data, type, row, meta) :
-					data;
-			};
-		}
-		else if ( mSource === null )
-		{
-			/* Give an empty string for rendering / sorting etc */
-			return function (data) { // type, row and meta also passed, but not used
-				return data;
-			};
-		}
-		else if ( typeof mSource === 'function' )
-		{
-			return function (data, type, row, meta) {
-				return mSource( data, type, row, meta );
-			};
-		}
-		else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
-			      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
-		{
-			/* If there is a . in the source string then the data source is in a
-			 * nested object so we loop over the data for each level to get the next
-			 * level down. On each loop we test for undefined, and if found immediately
-			 * return. This allows entire objects to be missing and sDefaultContent to
-			 * be used if defined, rather than throwing an error
-			 */
-			var fetchData = function (data, type, src) {
-				var arrayNotation, funcNotation, out, innerSrc;
-	
-				if ( src !== "" )
-				{
-					var a = _fnSplitObjNotation( src );
-	
-					for ( var i=0, iLen=a.length ; i<iLen ; i++ )
-					{
-						// Check if we are dealing with special notation
-						arrayNotation = a[i].match(__reArray);
-						funcNotation = a[i].match(__reFn);
-	
-						if ( arrayNotation )
-						{
-							// Array notation
-							a[i] = a[i].replace(__reArray, '');
-	
-							// Condition allows simply [] to be passed in
-							if ( a[i] !== "" ) {
-								data = data[ a[i] ];
-							}
-							out = [];
-	
-							// Get the remainder of the nested object to get
-							a.splice( 0, i+1 );
-							innerSrc = a.join('.');
-	
-							// Traverse each entry in the array getting the properties requested
-							if ( Array.isArray( data ) ) {
-								for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
-									out.push( fetchData( data[j], type, innerSrc ) );
-								}
-							}
-	
-							// If a string is given in between the array notation indicators, that
-							// is used to join the strings together, otherwise an array is returned
-							var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
-							data = (join==="") ? out : out.join(join);
-	
-							// The inner call to fetchData has already traversed through the remainder
-							// of the source requested, so we exit from the loop
-							break;
-						}
-						else if ( funcNotation )
-						{
-							// Function call
-							a[i] = a[i].replace(__reFn, '');
-							data = data[ a[i] ]();
-							continue;
-						}
-	
-						if ( data === null || data[ a[i] ] === undefined )
-						{
-							return undefined;
-						}
-						data = data[ a[i] ];
-					}
-				}
-	
-				return data;
-			};
-	
-			return function (data, type) { // row and meta also passed, but not used
-				return fetchData( data, type, mSource );
-			};
-		}
-		else
-		{
-			/* Array or flat object mapping */
-			return function (data, type) { // row and meta also passed, but not used
-				return data[mSource];
-			};
-		}
-	}
-	
-	
-	/**
-	 * Return a function that can be used to set data from a source object, taking
-	 * into account the ability to use nested objects as a source
-	 *  @param {string|int|function} mSource The data source for the object
-	 *  @returns {function} Data set function
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSetObjectDataFn( mSource )
-	{
-		if ( $.isPlainObject( mSource ) )
-		{
-			/* Unlike get, only the underscore (global) option is used for for
-			 * setting data since we don't know the type here. This is why an object
-			 * option is not documented for `mData` (which is read/write), but it is
-			 * for `mRender` which is read only.
-			 */
-			return _fnSetObjectDataFn( mSource._ );
-		}
-		else if ( mSource === null )
-		{
-			/* Nothing to do when the data source is null */
-			return function () {};
-		}
-		else if ( typeof mSource === 'function' )
-		{
-			return function (data, val, meta) {
-				mSource( data, 'set', val, meta );
-			};
-		}
-		else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
-			      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
-		{
-			/* Like the get, we need to get data from a nested object */
-			var setData = function (data, val, src) {
-				var a = _fnSplitObjNotation( src ), b;
-				var aLast = a[a.length-1];
-				var arrayNotation, funcNotation, o, innerSrc;
-	
-				for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
-				{
-					// Protect against prototype pollution
-					if (a[i] === '__proto__' || a[i] === 'constructor') {
-						throw new Error('Cannot set prototype values');
-					}
-	
-					// Check if we are dealing with an array notation request
-					arrayNotation = a[i].match(__reArray);
-					funcNotation = a[i].match(__reFn);
-	
-					if ( arrayNotation )
-					{
-						a[i] = a[i].replace(__reArray, '');
-						data[ a[i] ] = [];
-	
-						// Get the remainder of the nested object to set so we can recurse
-						b = a.slice();
-						b.splice( 0, i+1 );
-						innerSrc = b.join('.');
-	
-						// Traverse each entry in the array setting the properties requested
-						if ( Array.isArray( val ) )
-						{
-							for ( var j=0, jLen=val.length ; j<jLen ; j++ )
-							{
-								o = {};
-								setData( o, val[j], innerSrc );
-								data[ a[i] ].push( o );
-							}
-						}
-						else
-						{
-							// We've been asked to save data to an array, but it
-							// isn't array data to be saved. Best that can be done
-							// is to just save the value.
-							data[ a[i] ] = val;
-						}
-	
-						// The inner call to setData has already traversed through the remainder
-						// of the source and has set the data, thus we can exit here
-						return;
-					}
-					else if ( funcNotation )
-					{
-						// Function call
-						a[i] = a[i].replace(__reFn, '');
-						data = data[ a[i] ]( val );
-					}
-	
-					// If the nested object doesn't currently exist - since we are
-					// trying to set the value - create it
-					if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
-					{
-						data[ a[i] ] = {};
-					}
-					data = data[ a[i] ];
-				}
-	
-				// Last item in the input - i.e, the actual set
-				if ( aLast.match(__reFn ) )
-				{
-					// Function call
-					data = data[ aLast.replace(__reFn, '') ]( val );
-				}
-				else
-				{
-					// If array notation is used, we just want to strip it and use the property name
-					// and assign the value. If it isn't used, then we get the result we want anyway
-					data[ aLast.replace(__reArray, '') ] = val;
-				}
-			};
-	
-			return function (data, val) { // meta is also passed in, but not used
-				return setData( data, val, mSource );
-			};
-		}
-		else
-		{
-			/* Array or flat object mapping */
-			return function (data, val) { // meta is also passed in, but not used
-				data[mSource] = val;
-			};
-		}
-	}
-	
-	
-	/**
-	 * Return an array with the full table data
-	 *  @param {object} oSettings dataTables settings object
-	 *  @returns array {array} aData Master data array
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetDataMaster ( settings )
-	{
-		return _pluck( settings.aoData, '_aData' );
-	}
-	
-	
-	/**
-	 * Nuke the table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnClearTable( settings )
-	{
-		settings.aoData.length = 0;
-		settings.aiDisplayMaster.length = 0;
-		settings.aiDisplay.length = 0;
-		settings.aIds = {};
-	}
-	
-	
-	 /**
-	 * Take an array of integers (index array) and remove a target integer (value - not
-	 * the key!)
-	 *  @param {array} a Index array to target
-	 *  @param {int} iTarget value to find
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnDeleteIndex( a, iTarget, splice )
-	{
-		var iTargetIndex = -1;
-	
-		for ( var i=0, iLen=a.length ; i<iLen ; i++ )
-		{
-			if ( a[i] == iTarget )
-			{
-				iTargetIndex = i;
-			}
-			else if ( a[i] > iTarget )
-			{
-				a[i]--;
-			}
-		}
-	
-		if ( iTargetIndex != -1 && splice === undefined )
-		{
-			a.splice( iTargetIndex, 1 );
-		}
-	}
-	
-	
-	/**
-	 * Mark cached data as invalid such that a re-read of the data will occur when
-	 * the cached data is next requested. Also update from the data source object.
-	 *
-	 * @param {object} settings DataTables settings object
-	 * @param {int}    rowIdx   Row index to invalidate
-	 * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'
-	 *     or 'data'
-	 * @param {int}    [colIdx] Column index to invalidate. If undefined the whole
-	 *     row will be invalidated
-	 * @memberof DataTable#oApi
-	 *
-	 * @todo For the modularisation of v1.11 this will need to become a callback, so
-	 *   the sort and filter methods can subscribe to it. That will required
-	 *   initialisation options for sorting, which is why it is not already baked in
-	 */
-	function _fnInvalidate( settings, rowIdx, src, colIdx )
-	{
-		var row = settings.aoData[ rowIdx ];
-		var i, ien;
-		var cellWrite = function ( cell, col ) {
-			// This is very frustrating, but in IE if you just write directly
-			// to innerHTML, and elements that are overwritten are GC'ed,
-			// even if there is a reference to them elsewhere
-			while ( cell.childNodes.length ) {
-				cell.removeChild( cell.firstChild );
-			}
-	
-			cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
-		};
-	
-		// Are we reading last data from DOM or the data object?
-		if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
-			// Read the data from the DOM
-			row._aData = _fnGetRowElements(
-					settings, row, colIdx, colIdx === undefined ? undefined : row._aData
-				)
-				.data;
-		}
-		else {
-			// Reading from data object, update the DOM
-			var cells = row.anCells;
-	
-			if ( cells ) {
-				if ( colIdx !== undefined ) {
-					cellWrite( cells[colIdx], colIdx );
-				}
-				else {
-					for ( i=0, ien=cells.length ; i<ien ; i++ ) {
-						cellWrite( cells[i], i );
-					}
-				}
-			}
-		}
-	
-		// For both row and cell invalidation, the cached data for sorting and
-		// filtering is nulled out
-		row._aSortData = null;
-		row._aFilterData = null;
-	
-		// Invalidate the type for a specific column (if given) or all columns since
-		// the data might have changed
-		var cols = settings.aoColumns;
-		if ( colIdx !== undefined ) {
-			cols[ colIdx ].sType = null;
-		}
-		else {
-			for ( i=0, ien=cols.length ; i<ien ; i++ ) {
-				cols[i].sType = null;
-			}
-	
-			// Update DataTables special `DT_*` attributes for the row
-			_fnRowAttributes( settings, row );
-		}
-	}
-	
-	
-	/**
-	 * Build a data source object from an HTML row, reading the contents of the
-	 * cells that are in the row.
-	 *
-	 * @param {object} settings DataTables settings object
-	 * @param {node|object} TR element from which to read data or existing row
-	 *   object from which to re-read the data from the cells
-	 * @param {int} [colIdx] Optional column index
-	 * @param {array|object} [d] Data source object. If `colIdx` is given then this
-	 *   parameter should also be given and will be used to write the data into.
-	 *   Only the column in question will be written
-	 * @returns {object} Object with two parameters: `data` the data read, in
-	 *   document order, and `cells` and array of nodes (they can be useful to the
-	 *   caller, so rather than needing a second traversal to get them, just return
-	 *   them from here).
-	 * @memberof DataTable#oApi
-	 */
-	function _fnGetRowElements( settings, row, colIdx, d )
-	{
-		var
-			tds = [],
-			td = row.firstChild,
-			name, col, o, i=0, contents,
-			columns = settings.aoColumns,
-			objectRead = settings._rowReadObject;
-	
-		// Allow the data object to be passed in, or construct
-		d = d !== undefined ?
-			d :
-			objectRead ?
-				{} :
-				[];
-	
-		var attr = function ( str, td  ) {
-			if ( typeof str === 'string' ) {
-				var idx = str.indexOf('@');
-	
-				if ( idx !== -1 ) {
-					var attr = str.substring( idx+1 );
-					var setter = _fnSetObjectDataFn( str );
-					setter( d, td.getAttribute( attr ) );
-				}
-			}
-		};
-	
-		// Read data from a cell and store into the data object
-		var cellProcess = function ( cell ) {
-			if ( colIdx === undefined || colIdx === i ) {
-				col = columns[i];
-				contents = (cell.innerHTML).trim();
-	
-				if ( col && col._bAttrSrc ) {
-					var setter = _fnSetObjectDataFn( col.mData._ );
-					setter( d, contents );
-	
-					attr( col.mData.sort, cell );
-					attr( col.mData.type, cell );
-					attr( col.mData.filter, cell );
-				}
-				else {
-					// Depending on the `data` option for the columns the data can
-					// be read to either an object or an array.
-					if ( objectRead ) {
-						if ( ! col._setter ) {
-							// Cache the setter function
-							col._setter = _fnSetObjectDataFn( col.mData );
-						}
-						col._setter( d, contents );
-					}
-					else {
-						d[i] = contents;
-					}
-				}
-			}
-	
-			i++;
-		};
-	
-		if ( td ) {
-			// `tr` element was passed in
-			while ( td ) {
-				name = td.nodeName.toUpperCase();
-	
-				if ( name == "TD" || name == "TH" ) {
-					cellProcess( td );
-					tds.push( td );
-				}
-	
-				td = td.nextSibling;
-			}
-		}
-		else {
-			// Existing row object passed in
-			tds = row.anCells;
-	
-			for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
-				cellProcess( tds[j] );
-			}
-		}
-	
-		// Read the ID from the DOM if present
-		var rowNode = row.firstChild ? row : row.nTr;
-	
-		if ( rowNode ) {
-			var id = rowNode.getAttribute( 'id' );
-	
-			if ( id ) {
-				_fnSetObjectDataFn( settings.rowId )( d, id );
-			}
-		}
-	
-		return {
-			data: d,
-			cells: tds
-		};
-	}
-	/**
-	 * Create a new TR element (and it's TD children) for a row
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {int} iRow Row to consider
-	 *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,
-	 *    DataTables will create a row automatically
-	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
-	 *    if nTr is.
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
-	{
-		var
-			row = oSettings.aoData[iRow],
-			rowData = row._aData,
-			cells = [],
-			nTr, nTd, oCol,
-			i, iLen, create;
-	
-		if ( row.nTr === null )
-		{
-			nTr = nTrIn || document.createElement('tr');
-	
-			row.nTr = nTr;
-			row.anCells = cells;
-	
-			/* Use a private property on the node to allow reserve mapping from the node
-			 * to the aoData array for fast look up
-			 */
-			nTr._DT_RowIndex = iRow;
-	
-			/* Special parameters can be given by the data source to be used on the row */
-			_fnRowAttributes( oSettings, row );
-	
-			/* Process each column */
-			for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
-			{
-				oCol = oSettings.aoColumns[i];
-				create = nTrIn ? false : true;
-	
-				nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
-				nTd._DT_CellIndex = {
-					row: iRow,
-					column: i
-				};
-				
-				cells.push( nTd );
-	
-				// Need to create the HTML if new, or if a rendering function is defined
-				if ( create || ((oCol.mRender || oCol.mData !== i) &&
-					 (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
-				)) {
-					nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
-				}
-	
-				/* Add user defined class */
-				if ( oCol.sClass )
-				{
-					nTd.className += ' '+oCol.sClass;
-				}
-	
-				// Visibility - add or remove as required
-				if ( oCol.bVisible && ! nTrIn )
-				{
-					nTr.appendChild( nTd );
-				}
-				else if ( ! oCol.bVisible && nTrIn )
-				{
-					nTd.parentNode.removeChild( nTd );
-				}
-	
-				if ( oCol.fnCreatedCell )
-				{
-					oCol.fnCreatedCell.call( oSettings.oInstance,
-						nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
-					);
-				}
-			}
-	
-			_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] );
-		}
-	}
-	
-	
-	/**
-	 * Add attributes to a row based on the special `DT_*` parameters in a data
-	 * source object.
-	 *  @param {object} settings DataTables settings object
-	 *  @param {object} DataTables row object for the row to be modified
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnRowAttributes( settings, row )
-	{
-		var tr = row.nTr;
-		var data = row._aData;
-	
-		if ( tr ) {
-			var id = settings.rowIdFn( data );
-	
-			if ( id ) {
-				tr.id = id;
-			}
-	
-			if ( data.DT_RowClass ) {
-				// Remove any classes added by DT_RowClass before
-				var a = data.DT_RowClass.split(' ');
-				row.__rowc = row.__rowc ?
-					_unique( row.__rowc.concat( a ) ) :
-					a;
-	
-				$(tr)
-					.removeClass( row.__rowc.join(' ') )
-					.addClass( data.DT_RowClass );
-			}
-	
-			if ( data.DT_RowAttr ) {
-				$(tr).attr( data.DT_RowAttr );
-			}
-	
-			if ( data.DT_RowData ) {
-				$(tr).data( data.DT_RowData );
-			}
-		}
-	}
-	
-	
-	/**
-	 * Create the HTML header for the table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnBuildHead( oSettings )
-	{
-		var i, ien, cell, row, column;
-		var thead = oSettings.nTHead;
-		var tfoot = oSettings.nTFoot;
-		var createHeader = $('th, td', thead).length === 0;
-		var classes = oSettings.oClasses;
-		var columns = oSettings.aoColumns;
-	
-		if ( createHeader ) {
-			row = $('<tr/>').appendTo( thead );
-		}
-	
-		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
-			column = columns[i];
-			cell = $( column.nTh ).addClass( column.sClass );
-	
-			if ( createHeader ) {
-				cell.appendTo( row );
-			}
-	
-			// 1.11 move into sorting
-			if ( oSettings.oFeatures.bSort ) {
-				cell.addClass( column.sSortingClass );
-	
-				if ( column.bSortable !== false ) {
-					cell
-						.attr( 'tabindex', oSettings.iTabIndex )
-						.attr( 'aria-controls', oSettings.sTableId );
-	
-					_fnSortAttachListener( oSettings, column.nTh, i );
-				}
-			}
-	
-			if ( column.sTitle != cell[0].innerHTML ) {
-				cell.html( column.sTitle );
-			}
-	
-			_fnRenderer( oSettings, 'header' )(
-				oSettings, cell, column, classes
-			);
-		}
-	
-		if ( createHeader ) {
-			_fnDetectHeader( oSettings.aoHeader, thead );
-		}
-		
-		/* ARIA role for the rows */
-		$(thead).children('tr').attr('role', 'row');
-	
-		/* Deal with the footer - add classes if required */
-		$(thead).children('tr').children('th, td').addClass( classes.sHeaderTH );
-		$(tfoot).children('tr').children('th, td').addClass( classes.sFooterTH );
-	
-		// Cache the footer cells. Note that we only take the cells from the first
-		// row in the footer. If there is more than one row the user wants to
-		// interact with, they need to use the table().foot() method. Note also this
-		// allows cells to be used for multiple columns using colspan
-		if ( tfoot !== null ) {
-			var cells = oSettings.aoFooter[0];
-	
-			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
-				column = columns[i];
-				column.nTf = cells[i].cell;
-	
-				if ( column.sClass ) {
-					$(column.nTf).addClass( column.sClass );
-				}
-			}
-		}
-	}
-	
-	
-	/**
-	 * Draw the header (or footer) element based on the column visibility states. The
-	 * methodology here is to use the layout array from _fnDetectHeader, modified for
-	 * the instantaneous column visibility, to construct the new layout. The grid is
-	 * traversed over cell at a time in a rows x columns grid fashion, although each
-	 * cell insert can cover multiple elements in the grid - which is tracks using the
-	 * aApplied array. Cell inserts in the grid will only occur where there isn't
-	 * already a cell in that position.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param array {objects} aoSource Layout array from _fnDetectHeader
-	 *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
-	{
-		var i, iLen, j, jLen, k, kLen, n, nLocalTr;
-		var aoLocal = [];
-		var aApplied = [];
-		var iColumns = oSettings.aoColumns.length;
-		var iRowspan, iColspan;
-	
-		if ( ! aoSource )
-		{
-			return;
-		}
-	
-		if (  bIncludeHidden === undefined )
-		{
-			bIncludeHidden = false;
-		}
-	
-		/* Make a copy of the master layout array, but without the visible columns in it */
-		for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
-		{
-			aoLocal[i] = aoSource[i].slice();
-			aoLocal[i].nTr = aoSource[i].nTr;
-	
-			/* Remove any columns which are currently hidden */
-			for ( j=iColumns-1 ; j>=0 ; j-- )
-			{
-				if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
-				{
-					aoLocal[i].splice( j, 1 );
-				}
-			}
-	
-			/* Prep the applied array - it needs an element for each row */
-			aApplied.push( [] );
-		}
-	
-		for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
-		{
-			nLocalTr = aoLocal[i].nTr;
-	
-			/* All cells are going to be replaced, so empty out the row */
-			if ( nLocalTr )
-			{
-				while( (n = nLocalTr.firstChild) )
-				{
-					nLocalTr.removeChild( n );
-				}
-			}
-	
-			for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
-			{
-				iRowspan = 1;
-				iColspan = 1;
-	
-				/* Check to see if there is already a cell (row/colspan) covering our target
-				 * insert point. If there is, then there is nothing to do.
-				 */
-				if ( aApplied[i][j] === undefined )
-				{
-					nLocalTr.appendChild( aoLocal[i][j].cell );
-					aApplied[i][j] = 1;
-	
-					/* Expand the cell to cover as many rows as needed */
-					while ( aoLocal[i+iRowspan] !== undefined &&
-					        aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
-					{
-						aApplied[i+iRowspan][j] = 1;
-						iRowspan++;
-					}
-	
-					/* Expand the cell to cover as many columns as needed */
-					while ( aoLocal[i][j+iColspan] !== undefined &&
-					        aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
-					{
-						/* Must update the applied array over the rows for the columns */
-						for ( k=0 ; k<iRowspan ; k++ )
-						{
-							aApplied[i+k][j+iColspan] = 1;
-						}
-						iColspan++;
-					}
-	
-					/* Do the actual expansion in the DOM */
-					$(aoLocal[i][j].cell)
-						.attr('rowspan', iRowspan)
-						.attr('colspan', iColspan);
-				}
-			}
-		}
-	}
-	
-	
-	/**
-	 * Insert the required TR nodes into the table for display
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnDraw( oSettings )
-	{
-		/* Provide a pre-callback function which can be used to cancel the draw is false is returned */
-		var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
-		if ( $.inArray( false, aPreDraw ) !== -1 )
-		{
-			_fnProcessingDisplay( oSettings, false );
-			return;
-		}
-	
-		var i, iLen, n;
-		var anRows = [];
-		var iRowCount = 0;
-		var asStripeClasses = oSettings.asStripeClasses;
-		var iStripes = asStripeClasses.length;
-		var iOpenRows = oSettings.aoOpenRows.length;
-		var oLang = oSettings.oLanguage;
-		var iInitDisplayStart = oSettings.iInitDisplayStart;
-		var bServerSide = _fnDataSource( oSettings ) == 'ssp';
-		var aiDisplay = oSettings.aiDisplay;
-	
-		oSettings.bDrawing = true;
-	
-		/* Check and see if we have an initial draw position from state saving */
-		if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
-		{
-			oSettings._iDisplayStart = bServerSide ?
-				iInitDisplayStart :
-				iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
-					0 :
-					iInitDisplayStart;
-	
-			oSettings.iInitDisplayStart = -1;
-		}
-	
-		var iDisplayStart = oSettings._iDisplayStart;
-		var iDisplayEnd = oSettings.fnDisplayEnd();
-	
-		/* Server-side processing draw intercept */
-		if ( oSettings.bDeferLoading )
-		{
-			oSettings.bDeferLoading = false;
-			oSettings.iDraw++;
-			_fnProcessingDisplay( oSettings, false );
-		}
-		else if ( !bServerSide )
-		{
-			oSettings.iDraw++;
-		}
-		else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
-		{
-			return;
-		}
-	
-		if ( aiDisplay.length !== 0 )
-		{
-			var iStart = bServerSide ? 0 : iDisplayStart;
-			var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
-	
-			for ( var j=iStart ; j<iEnd ; j++ )
-			{
-				var iDataIndex = aiDisplay[j];
-				var aoData = oSettings.aoData[ iDataIndex ];
-				if ( aoData.nTr === null )
-				{
-					_fnCreateTr( oSettings, iDataIndex );
-				}
-	
-				var nRow = aoData.nTr;
-	
-				/* Remove the old striping classes and then add the new one */
-				if ( iStripes !== 0 )
-				{
-					var sStripe = asStripeClasses[ iRowCount % iStripes ];
-					if ( aoData._sRowStripe != sStripe )
-					{
-						$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
-						aoData._sRowStripe = sStripe;
-					}
-				}
-	
-				// Row callback functions - might want to manipulate the row
-				// iRowCount and j are not currently documented. Are they at all
-				// useful?
-				_fnCallbackFire( oSettings, 'aoRowCallback', null,
-					[nRow, aoData._aData, iRowCount, j, iDataIndex] );
-	
-				anRows.push( nRow );
-				iRowCount++;
-			}
-		}
-		else
-		{
-			/* Table is empty - create a row with an empty message in it */
-			var sZero = oLang.sZeroRecords;
-			if ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )
-			{
-				sZero = oLang.sLoadingRecords;
-			}
-			else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
-			{
-				sZero = oLang.sEmptyTable;
-			}
-	
-			anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
-				.append( $('<td />', {
-					'valign':  'top',
-					'colSpan': _fnVisbleColumns( oSettings ),
-					'class':   oSettings.oClasses.sRowEmpty
-				} ).html( sZero ) )[0];
-		}
-	
-		/* Header and footer callbacks */
-		_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
-			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
-	
-		_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
-			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
-	
-		var body = $(oSettings.nTBody);
-	
-		body.children().detach();
-		body.append( $(anRows) );
-	
-		/* Call all required callback functions for the end of a draw */
-		_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
-	
-		/* Draw is complete, sorting and filtering must be as well */
-		oSettings.bSorted = false;
-		oSettings.bFiltered = false;
-		oSettings.bDrawing = false;
-	}
-	
-	
-	/**
-	 * Redraw the table - taking account of the various features which are enabled
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {boolean} [holdPosition] Keep the current paging position. By default
-	 *    the paging is reset to the first page
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnReDraw( settings, holdPosition )
-	{
-		var
-			features = settings.oFeatures,
-			sort     = features.bSort,
-			filter   = features.bFilter;
-	
-		if ( sort ) {
-			_fnSort( settings );
-		}
-	
-		if ( filter ) {
-			_fnFilterComplete( settings, settings.oPreviousSearch );
-		}
-		else {
-			// No filtering, so we want to just use the display master
-			settings.aiDisplay = settings.aiDisplayMaster.slice();
-		}
-	
-		if ( holdPosition !== true ) {
-			settings._iDisplayStart = 0;
-		}
-	
-		// Let any modules know about the draw hold position state (used by
-		// scrolling internally)
-		settings._drawHold = holdPosition;
-	
-		_fnDraw( settings );
-	
-		settings._drawHold = false;
-	}
-	
-	
-	/**
-	 * Add the options to the page HTML for the table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAddOptionsHtml ( oSettings )
-	{
-		var classes = oSettings.oClasses;
-		var table = $(oSettings.nTable);
-		var holding = $('<div/>').insertBefore( table ); // Holding element for speed
-		var features = oSettings.oFeatures;
-	
-		// All DataTables are wrapped in a div
-		var insert = $('<div/>', {
-			id:      oSettings.sTableId+'_wrapper',
-			'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
-		} );
-	
-		oSettings.nHolding = holding[0];
-		oSettings.nTableWrapper = insert[0];
-		oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
-	
-		/* Loop over the user set positioning and place the elements as needed */
-		var aDom = oSettings.sDom.split('');
-		var featureNode, cOption, nNewNode, cNext, sAttr, j;
-		for ( var i=0 ; i<aDom.length ; i++ )
-		{
-			featureNode = null;
-			cOption = aDom[i];
-	
-			if ( cOption == '<' )
-			{
-				/* New container div */
-				nNewNode = $('<div/>')[0];
-	
-				/* Check to see if we should append an id and/or a class name to the container */
-				cNext = aDom[i+1];
-				if ( cNext == "'" || cNext == '"' )
-				{
-					sAttr = "";
-					j = 2;
-					while ( aDom[i+j] != cNext )
-					{
-						sAttr += aDom[i+j];
-						j++;
-					}
-	
-					/* Replace jQuery UI constants @todo depreciated */
-					if ( sAttr == "H" )
-					{
-						sAttr = classes.sJUIHeader;
-					}
-					else if ( sAttr == "F" )
-					{
-						sAttr = classes.sJUIFooter;
-					}
-	
-					/* The attribute can be in the format of "#id.class", "#id" or "class" This logic
-					 * breaks the string into parts and applies them as needed
-					 */
-					if ( sAttr.indexOf('.') != -1 )
-					{
-						var aSplit = sAttr.split('.');
-						nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
-						nNewNode.className = aSplit[1];
-					}
-					else if ( sAttr.charAt(0) == "#" )
-					{
-						nNewNode.id = sAttr.substr(1, sAttr.length-1);
-					}
-					else
-					{
-						nNewNode.className = sAttr;
-					}
-	
-					i += j; /* Move along the position array */
-				}
-	
-				insert.append( nNewNode );
-				insert = $(nNewNode);
-			}
-			else if ( cOption == '>' )
-			{
-				/* End container div */
-				insert = insert.parent();
-			}
-			// @todo Move options into their own plugins?
-			else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
-			{
-				/* Length */
-				featureNode = _fnFeatureHtmlLength( oSettings );
-			}
-			else if ( cOption == 'f' && features.bFilter )
-			{
-				/* Filter */
-				featureNode = _fnFeatureHtmlFilter( oSettings );
-			}
-			else if ( cOption == 'r' && features.bProcessing )
-			{
-				/* pRocessing */
-				featureNode = _fnFeatureHtmlProcessing( oSettings );
-			}
-			else if ( cOption == 't' )
-			{
-				/* Table */
-				featureNode = _fnFeatureHtmlTable( oSettings );
-			}
-			else if ( cOption ==  'i' && features.bInfo )
-			{
-				/* Info */
-				featureNode = _fnFeatureHtmlInfo( oSettings );
-			}
-			else if ( cOption == 'p' && features.bPaginate )
-			{
-				/* Pagination */
-				featureNode = _fnFeatureHtmlPaginate( oSettings );
-			}
-			else if ( DataTable.ext.feature.length !== 0 )
-			{
-				/* Plug-in features */
-				var aoFeatures = DataTable.ext.feature;
-				for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
-				{
-					if ( cOption == aoFeatures[k].cFeature )
-					{
-						featureNode = aoFeatures[k].fnInit( oSettings );
-						break;
-					}
-				}
-			}
-	
-			/* Add to the 2D features array */
-			if ( featureNode )
-			{
-				var aanFeatures = oSettings.aanFeatures;
-	
-				if ( ! aanFeatures[cOption] )
-				{
-					aanFeatures[cOption] = [];
-				}
-	
-				aanFeatures[cOption].push( featureNode );
-				insert.append( featureNode );
-			}
-		}
-	
-		/* Built our DOM structure - replace the holding div with what we want */
-		holding.replaceWith( insert );
-		oSettings.nHolding = null;
-	}
-	
-	
-	/**
-	 * Use the DOM source to create up an array of header cells. The idea here is to
-	 * create a layout grid (array) of rows x columns, which contains a reference
-	 * to the cell that that point in the grid (regardless of col/rowspan), such that
-	 * any column / row could be removed and the new grid constructed
-	 *  @param array {object} aLayout Array to store the calculated layout in
-	 *  @param {node} nThead The header/footer element for the table
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnDetectHeader ( aLayout, nThead )
-	{
-		var nTrs = $(nThead).children('tr');
-		var nTr, nCell;
-		var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
-		var bUnique;
-		var fnShiftCol = function ( a, i, j ) {
-			var k = a[i];
-	                while ( k[j] ) {
-				j++;
-			}
-			return j;
-		};
-	
-		aLayout.splice( 0, aLayout.length );
-	
-		/* We know how many rows there are in the layout - so prep it */
-		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
-		{
-			aLayout.push( [] );
-		}
-	
-		/* Calculate a layout array */
-		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
-		{
-			nTr = nTrs[i];
-			iColumn = 0;
-	
-			/* For every cell in the row... */
-			nCell = nTr.firstChild;
-			while ( nCell ) {
-				if ( nCell.nodeName.toUpperCase() == "TD" ||
-				     nCell.nodeName.toUpperCase() == "TH" )
-				{
-					/* Get the col and rowspan attributes from the DOM and sanitise them */
-					iColspan = nCell.getAttribute('colspan') * 1;
-					iRowspan = nCell.getAttribute('rowspan') * 1;
-					iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
-					iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
-	
-					/* There might be colspan cells already in this row, so shift our target
-					 * accordingly
-					 */
-					iColShifted = fnShiftCol( aLayout, i, iColumn );
-	
-					/* Cache calculation for unique columns */
-					bUnique = iColspan === 1 ? true : false;
-	
-					/* If there is col / rowspan, copy the information into the layout grid */
-					for ( l=0 ; l<iColspan ; l++ )
-					{
-						for ( k=0 ; k<iRowspan ; k++ )
-						{
-							aLayout[i+k][iColShifted+l] = {
-								"cell": nCell,
-								"unique": bUnique
-							};
-							aLayout[i+k].nTr = nTr;
-						}
-					}
-				}
-				nCell = nCell.nextSibling;
-			}
-		}
-	}
-	
-	
-	/**
-	 * Get an array of unique th elements, one for each column
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {node} nHeader automatically detect the layout from this node - optional
-	 *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
-	 *  @returns array {node} aReturn list of unique th's
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
-	{
-		var aReturn = [];
-		if ( !aLayout )
-		{
-			aLayout = oSettings.aoHeader;
-			if ( nHeader )
-			{
-				aLayout = [];
-				_fnDetectHeader( aLayout, nHeader );
-			}
-		}
-	
-		for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
-		{
-			for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
-			{
-				if ( aLayout[i][j].unique &&
-					 (!aReturn[j] || !oSettings.bSortCellsTop) )
-				{
-					aReturn[j] = aLayout[i][j].cell;
-				}
-			}
-		}
-	
-		return aReturn;
-	}
-	
-	/**
-	 * Create an Ajax call based on the table's settings, taking into account that
-	 * parameters can have multiple forms, and backwards compatibility.
-	 *
-	 * @param {object} oSettings dataTables settings object
-	 * @param {array} data Data to send to the server, required by
-	 *     DataTables - may be augmented by developer callbacks
-	 * @param {function} fn Callback function to run when data is obtained
-	 */
-	function _fnBuildAjax( oSettings, data, fn )
-	{
-		// Compatibility with 1.9-, allow fnServerData and event to manipulate
-		_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
-	
-		// Convert to object based for 1.10+ if using the old array scheme which can
-		// come from server-side processing or serverParams
-		if ( data && Array.isArray(data) ) {
-			var tmp = {};
-			var rbracket = /(.*?)\[\]$/;
-	
-			$.each( data, function (key, val) {
-				var match = val.name.match(rbracket);
-	
-				if ( match ) {
-					// Support for arrays
-					var name = match[0];
-	
-					if ( ! tmp[ name ] ) {
-						tmp[ name ] = [];
-					}
-					tmp[ name ].push( val.value );
-				}
-				else {
-					tmp[val.name] = val.value;
-				}
-			} );
-			data = tmp;
-		}
-	
-		var ajaxData;
-		var ajax = oSettings.ajax;
-		var instance = oSettings.oInstance;
-		var callback = function ( json ) {
-			_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
-			fn( json );
-		};
-	
-		if ( $.isPlainObject( ajax ) && ajax.data )
-		{
-			ajaxData = ajax.data;
-	
-			var newData = typeof ajaxData === 'function' ?
-				ajaxData( data, oSettings ) :  // fn can manipulate data or return
-				ajaxData;                      // an object object or array to merge
-	
-			// If the function returned something, use that alone
-			data = typeof ajaxData === 'function' && newData ?
-				newData :
-				$.extend( true, data, newData );
-	
-			// Remove the data property as we've resolved it already and don't want
-			// jQuery to do it again (it is restored at the end of the function)
-			delete ajax.data;
-		}
-	
-		var baseAjax = {
-			"data": data,
-			"success": function (json) {
-				var error = json.error || json.sError;
-				if ( error ) {
-					_fnLog( oSettings, 0, error );
-				}
-	
-				oSettings.json = json;
-				callback( json );
-			},
-			"dataType": "json",
-			"cache": false,
-			"type": oSettings.sServerMethod,
-			"error": function (xhr, error, thrown) {
-				var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
-	
-				if ( $.inArray( true, ret ) === -1 ) {
-					if ( error == "parsererror" ) {
-						_fnLog( oSettings, 0, 'Invalid JSON response', 1 );
-					}
-					else if ( xhr.readyState === 4 ) {
-						_fnLog( oSettings, 0, 'Ajax error', 7 );
-					}
-				}
-	
-				_fnProcessingDisplay( oSettings, false );
-			}
-		};
-	
-		// Store the data submitted for the API
-		oSettings.oAjaxData = data;
-	
-		// Allow plug-ins and external processes to modify the data
-		_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
-	
-		if ( oSettings.fnServerData )
-		{
-			// DataTables 1.9- compatibility
-			oSettings.fnServerData.call( instance,
-				oSettings.sAjaxSource,
-				$.map( data, function (val, key) { // Need to convert back to 1.9 trad format
-					return { name: key, value: val };
-				} ),
-				callback,
-				oSettings
-			);
-		}
-		else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
-		{
-			// DataTables 1.9- compatibility
-			oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
-				url: ajax || oSettings.sAjaxSource
-			} ) );
-		}
-		else if ( typeof ajax === 'function' )
-		{
-			// Is a function - let the caller define what needs to be done
-			oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
-		}
-		else
-		{
-			// Object to extend the base settings
-			oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
-	
-			// Restore for next time around
-			ajax.data = ajaxData;
-		}
-	}
-	
-	
-	/**
-	 * Update the table using an Ajax call
-	 *  @param {object} settings dataTables settings object
-	 *  @returns {boolean} Block the table drawing or not
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAjaxUpdate( settings )
-	{
-		if ( settings.bAjaxDataGet ) {
-			settings.iDraw++;
-			_fnProcessingDisplay( settings, true );
-	
-			_fnBuildAjax(
-				settings,
-				_fnAjaxParameters( settings ),
-				function(json) {
-					_fnAjaxUpdateDraw( settings, json );
-				}
-			);
-	
-			return false;
-		}
-		return true;
-	}
-	
-	
-	/**
-	 * Build up the parameters in an object needed for a server-side processing
-	 * request. Note that this is basically done twice, is different ways - a modern
-	 * method which is used by default in DataTables 1.10 which uses objects and
-	 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
-	 * the sAjaxSource option is used in the initialisation, or the legacyAjax
-	 * option is set.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @returns {bool} block the table drawing or not
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAjaxParameters( settings )
-	{
-		var
-			columns = settings.aoColumns,
-			columnCount = columns.length,
-			features = settings.oFeatures,
-			preSearch = settings.oPreviousSearch,
-			preColSearch = settings.aoPreSearchCols,
-			i, data = [], dataProp, column, columnSearch,
-			sort = _fnSortFlatten( settings ),
-			displayStart = settings._iDisplayStart,
-			displayLength = features.bPaginate !== false ?
-				settings._iDisplayLength :
-				-1;
-	
-		var param = function ( name, value ) {
-			data.push( { 'name': name, 'value': value } );
-		};
-	
-		// DataTables 1.9- compatible method
-		param( 'sEcho',          settings.iDraw );
-		param( 'iColumns',       columnCount );
-		param( 'sColumns',       _pluck( columns, 'sName' ).join(',') );
-		param( 'iDisplayStart',  displayStart );
-		param( 'iDisplayLength', displayLength );
-	
-		// DataTables 1.10+ method
-		var d = {
-			draw:    settings.iDraw,
-			columns: [],
-			order:   [],
-			start:   displayStart,
-			length:  displayLength,
-			search:  {
-				value: preSearch.sSearch,
-				regex: preSearch.bRegex
-			}
-		};
-	
-		for ( i=0 ; i<columnCount ; i++ ) {
-			column = columns[i];
-			columnSearch = preColSearch[i];
-			dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
-	
-			d.columns.push( {
-				data:       dataProp,
-				name:       column.sName,
-				searchable: column.bSearchable,
-				orderable:  column.bSortable,
-				search:     {
-					value: columnSearch.sSearch,
-					regex: columnSearch.bRegex
-				}
-			} );
-	
-			param( "mDataProp_"+i, dataProp );
-	
-			if ( features.bFilter ) {
-				param( 'sSearch_'+i,     columnSearch.sSearch );
-				param( 'bRegex_'+i,      columnSearch.bRegex );
-				param( 'bSearchable_'+i, column.bSearchable );
-			}
-	
-			if ( features.bSort ) {
-				param( 'bSortable_'+i, column.bSortable );
-			}
-		}
-	
-		if ( features.bFilter ) {
-			param( 'sSearch', preSearch.sSearch );
-			param( 'bRegex', preSearch.bRegex );
-		}
-	
-		if ( features.bSort ) {
-			$.each( sort, function ( i, val ) {
-				d.order.push( { column: val.col, dir: val.dir } );
-	
-				param( 'iSortCol_'+i, val.col );
-				param( 'sSortDir_'+i, val.dir );
-			} );
-	
-			param( 'iSortingCols', sort.length );
-		}
-	
-		// If the legacy.ajax parameter is null, then we automatically decide which
-		// form to use, based on sAjaxSource
-		var legacy = DataTable.ext.legacy.ajax;
-		if ( legacy === null ) {
-			return settings.sAjaxSource ? data : d;
-		}
-	
-		// Otherwise, if legacy has been specified then we use that to decide on the
-		// form
-		return legacy ? data : d;
-	}
-	
-	
-	/**
-	 * Data the data from the server (nuking the old) and redraw the table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {object} json json data return from the server.
-	 *  @param {string} json.sEcho Tracking flag for DataTables to match requests
-	 *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
-	 *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
-	 *  @param {array} json.aaData The data to display on this page
-	 *  @param {string} [json.sColumns] Column ordering (sName, comma separated)
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnAjaxUpdateDraw ( settings, json )
-	{
-		// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
-		// Support both
-		var compat = function ( old, modern ) {
-			return json[old] !== undefined ? json[old] : json[modern];
-		};
-	
-		var data = _fnAjaxDataSrc( settings, json );
-		var draw            = compat( 'sEcho',                'draw' );
-		var recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );
-		var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
-	
-		if ( draw !== undefined ) {
-			// Protect against out of sequence returns
-			if ( draw*1 < settings.iDraw ) {
-				return;
-			}
-			settings.iDraw = draw * 1;
-		}
-	
-		_fnClearTable( settings );
-		settings._iRecordsTotal   = parseInt(recordsTotal, 10);
-		settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
-	
-		for ( var i=0, ien=data.length ; i<ien ; i++ ) {
-			_fnAddData( settings, data[i] );
-		}
-		settings.aiDisplay = settings.aiDisplayMaster.slice();
-	
-		settings.bAjaxDataGet = false;
-		_fnDraw( settings );
-	
-		if ( ! settings._bInitComplete ) {
-			_fnInitComplete( settings, json );
-		}
-	
-		settings.bAjaxDataGet = true;
-		_fnProcessingDisplay( settings, false );
-	}
-	
-	
-	/**
-	 * Get the data from the JSON data source to use for drawing a table. Using
-	 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
-	 * source object, or from a processing function.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param  {object} json Data source object / array from the server
-	 *  @return {array} Array of data to use
-	 */
-	function _fnAjaxDataSrc ( oSettings, json )
-	{
-		var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
-			oSettings.ajax.dataSrc :
-			oSettings.sAjaxDataProp; // Compatibility with 1.9-.
-	
-		// Compatibility with 1.9-. In order to read from aaData, check if the
-		// default has been changed, if not, check for aaData
-		if ( dataSrc === 'data' ) {
-			return json.aaData || json[dataSrc];
-		}
-	
-		return dataSrc !== "" ?
-			_fnGetObjectDataFn( dataSrc )( json ) :
-			json;
-	}
-	
-	/**
-	 * Generate the node required for filtering text
-	 *  @returns {node} Filter control element
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFeatureHtmlFilter ( settings )
-	{
-		var classes = settings.oClasses;
-		var tableId = settings.sTableId;
-		var language = settings.oLanguage;
-		var previousSearch = settings.oPreviousSearch;
-		var features = settings.aanFeatures;
-		var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
-	
-		var str = language.sSearch;
-		str = str.match(/_INPUT_/) ?
-			str.replace('_INPUT_', input) :
-			str+input;
-	
-		var filter = $('<div/>', {
-				'id': ! features.f ? tableId+'_filter' : null,
-				'class': classes.sFilter
-			} )
-			.append( $('<label/>' ).append( str ) );
-	
-		var searchFn = function() {
-			/* Update all other filter input elements for the new display */
-			var n = features.f;
-			var val = !this.value ? "" : this.value; // mental IE8 fix :-(
-	
-			/* Now do the filter */
-			if ( val != previousSearch.sSearch ) {
-				_fnFilterComplete( settings, {
-					"sSearch": val,
-					"bRegex": previousSearch.bRegex,
-					"bSmart": previousSearch.bSmart ,
-					"bCaseInsensitive": previousSearch.bCaseInsensitive
-				} );
-	
-				// Need to redraw, without resorting
-				settings._iDisplayStart = 0;
-				_fnDraw( settings );
-			}
-		};
-	
-		var searchDelay = settings.searchDelay !== null ?
-			settings.searchDelay :
-			_fnDataSource( settings ) === 'ssp' ?
-				400 :
-				0;
-	
-		var jqFilter = $('input', filter)
-			.val( previousSearch.sSearch )
-			.attr( 'placeholder', language.sSearchPlaceholder )
-			.on(
-				'keyup.DT search.DT input.DT paste.DT cut.DT',
-				searchDelay ?
-					_fnThrottle( searchFn, searchDelay ) :
-					searchFn
-			)
-			.on( 'mouseup', function(e) {
-				// Edge fix! Edge 17 does not trigger anything other than mouse events when clicking
-				// on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn`
-				// checks the value to see if it has changed. In other browsers it won't have.
-				setTimeout( function () {
-					searchFn.call(jqFilter[0]);
-				}, 10);
-			} )
-			.on( 'keypress.DT', function(e) {
-				/* Prevent form submission */
-				if ( e.keyCode == 13 ) {
-					return false;
-				}
-			} )
-			.attr('aria-controls', tableId);
-	
-		// Update the input elements whenever the table is filtered
-		$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
-			if ( settings === s ) {
-				// IE9 throws an 'unknown error' if document.activeElement is used
-				// inside an iframe or frame...
-				try {
-					if ( jqFilter[0] !== document.activeElement ) {
-						jqFilter.val( previousSearch.sSearch );
-					}
-				}
-				catch ( e ) {}
-			}
-		} );
-	
-		return filter[0];
-	}
-	
-	
-	/**
-	 * Filter the table using both the global filter and column based filtering
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {object} oSearch search information
-	 *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFilterComplete ( oSettings, oInput, iForce )
-	{
-		var oPrevSearch = oSettings.oPreviousSearch;
-		var aoPrevSearch = oSettings.aoPreSearchCols;
-		var fnSaveFilter = function ( oFilter ) {
-			/* Save the filtering values */
-			oPrevSearch.sSearch = oFilter.sSearch;
-			oPrevSearch.bRegex = oFilter.bRegex;
-			oPrevSearch.bSmart = oFilter.bSmart;
-			oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
-		};
-		var fnRegex = function ( o ) {
-			// Backwards compatibility with the bEscapeRegex option
-			return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
-		};
-	
-		// Resolve any column types that are unknown due to addition or invalidation
-		// @todo As per sort - can this be moved into an event handler?
-		_fnColumnTypes( oSettings );
-	
-		/* In server-side processing all filtering is done by the server, so no point hanging around here */
-		if ( _fnDataSource( oSettings ) != 'ssp' )
-		{
-			/* Global filter */
-			_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
-			fnSaveFilter( oInput );
-	
-			/* Now do the individual column filter */
-			for ( var i=0 ; i<aoPrevSearch.length ; i++ )
-			{
-				_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
-					aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
-			}
-	
-			/* Custom filtering */
-			_fnFilterCustom( oSettings );
-		}
-		else
-		{
-			fnSaveFilter( oInput );
-		}
-	
-		/* Tell the draw function we have been filtering */
-		oSettings.bFiltered = true;
-		_fnCallbackFire( oSettings, null, 'search', [oSettings] );
-	}
-	
-	
-	/**
-	 * Apply custom filtering functions
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFilterCustom( settings )
-	{
-		var filters = DataTable.ext.search;
-		var displayRows = settings.aiDisplay;
-		var row, rowIdx;
-	
-		for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
-			var rows = [];
-	
-			// Loop over each row and see if it should be included
-			for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
-				rowIdx = displayRows[ j ];
-				row = settings.aoData[ rowIdx ];
-	
-				if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
-					rows.push( rowIdx );
-				}
-			}
-	
-			// So the array reference doesn't break set the results into the
-			// existing array
-			displayRows.length = 0;
-			$.merge( displayRows, rows );
-		}
-	}
-	
-	
-	/**
-	 * Filter the table on a per-column basis
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {string} sInput string to filter on
-	 *  @param {int} iColumn column to filter
-	 *  @param {bool} bRegex treat search string as a regular expression or not
-	 *  @param {bool} bSmart use smart filtering or not
-	 *  @param {bool} bCaseInsensitive Do case insenstive matching or not
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
-	{
-		if ( searchStr === '' ) {
-			return;
-		}
-	
-		var data;
-		var out = [];
-		var display = settings.aiDisplay;
-		var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
-	
-		for ( var i=0 ; i<display.length ; i++ ) {
-			data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
-	
-			if ( rpSearch.test( data ) ) {
-				out.push( display[i] );
-			}
-		}
-	
-		settings.aiDisplay = out;
-	}
-	
-	
-	/**
-	 * Filter the data table based on user input and draw the table
-	 *  @param {object} settings dataTables settings object
-	 *  @param {string} input string to filter on
-	 *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
-	 *  @param {bool} regex treat as a regular expression or not
-	 *  @param {bool} smart perform smart filtering or not
-	 *  @param {bool} caseInsensitive Do case insenstive matching or not
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
-	{
-		var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
-		var prevSearch = settings.oPreviousSearch.sSearch;
-		var displayMaster = settings.aiDisplayMaster;
-		var display, invalidated, i;
-		var filtered = [];
-	
-		// Need to take account of custom filtering functions - always filter
-		if ( DataTable.ext.search.length !== 0 ) {
-			force = true;
-		}
-	
-		// Check if any of the rows were invalidated
-		invalidated = _fnFilterData( settings );
-	
-		// If the input is blank - we just want the full data set
-		if ( input.length <= 0 ) {
-			settings.aiDisplay = displayMaster.slice();
-		}
-		else {
-			// New search - start from the master array
-			if ( invalidated ||
-				 force ||
-				 regex ||
-				 prevSearch.length > input.length ||
-				 input.indexOf(prevSearch) !== 0 ||
-				 settings.bSorted // On resort, the display master needs to be
-				                  // re-filtered since indexes will have changed
-			) {
-				settings.aiDisplay = displayMaster.slice();
-			}
-	
-			// Search the display array
-			display = settings.aiDisplay;
-	
-			for ( i=0 ; i<display.length ; i++ ) {
-				if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
-					filtered.push( display[i] );
-				}
-			}
-	
-			settings.aiDisplay = filtered;
-		}
-	}
-	
-	
-	/**
-	 * Build a regular expression object suitable for searching a table
-	 *  @param {string} sSearch string to search for
-	 *  @param {bool} bRegex treat as a regular expression or not
-	 *  @param {bool} bSmart perform smart filtering or not
-	 *  @param {bool} bCaseInsensitive Do case insensitive matching or not
-	 *  @returns {RegExp} constructed object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
-	{
-		search = regex ?
-			search :
-			_fnEscapeRegex( search );
-		
-		if ( smart ) {
-			/* For smart filtering we want to allow the search to work regardless of
-			 * word order. We also want double quoted text to be preserved, so word
-			 * order is important - a la google. So this is what we want to
-			 * generate:
-			 * 
-			 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
-			 */
-			var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
-				if ( word.charAt(0) === '"' ) {
-					var m = word.match( /^"(.*)"$/ );
-					word = m ? m[1] : word;
-				}
-	
-				return word.replace('"', '');
-			} );
-	
-			search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
-		}
-	
-		return new RegExp( search, caseInsensitive ? 'i' : '' );
-	}
-	
-	
-	/**
-	 * Escape a string such that it can be used in a regular expression
-	 *  @param {string} sVal string to escape
-	 *  @returns {string} escaped string
-	 *  @memberof DataTable#oApi
-	 */
-	var _fnEscapeRegex = DataTable.util.escapeRegex;
-	
-	var __filter_div = $('<div>')[0];
-	var __filter_div_textContent = __filter_div.textContent !== undefined;
-	
-	// Update the filtering data for each row if needed (by invalidation or first run)
-	function _fnFilterData ( settings )
-	{
-		var columns = settings.aoColumns;
-		var column;
-		var i, j, ien, jen, filterData, cellData, row;
-		var fomatters = DataTable.ext.type.search;
-		var wasInvalidated = false;
-	
-		for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
-			row = settings.aoData[i];
-	
-			if ( ! row._aFilterData ) {
-				filterData = [];
-	
-				for ( j=0, jen=columns.length ; j<jen ; j++ ) {
-					column = columns[j];
-	
-					if ( column.bSearchable ) {
-						cellData = _fnGetCellData( settings, i, j, 'filter' );
-	
-						if ( fomatters[ column.sType ] ) {
-							cellData = fomatters[ column.sType ]( cellData );
-						}
-	
-						// Search in DataTables 1.10 is string based. In 1.11 this
-						// should be altered to also allow strict type checking.
-						if ( cellData === null ) {
-							cellData = '';
-						}
-	
-						if ( typeof cellData !== 'string' && cellData.toString ) {
-							cellData = cellData.toString();
-						}
-					}
-					else {
-						cellData = '';
-					}
-	
-					// If it looks like there is an HTML entity in the string,
-					// attempt to decode it so sorting works as expected. Note that
-					// we could use a single line of jQuery to do this, but the DOM
-					// method used here is much faster http://jsperf.com/html-decode
-					if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
-						__filter_div.innerHTML = cellData;
-						cellData = __filter_div_textContent ?
-							__filter_div.textContent :
-							__filter_div.innerText;
-					}
-	
-					if ( cellData.replace ) {
-						cellData = cellData.replace(/[\r\n\u2028]/g, '');
-					}
-	
-					filterData.push( cellData );
-				}
-	
-				row._aFilterData = filterData;
-				row._sFilterRow = filterData.join('  ');
-				wasInvalidated = true;
-			}
-		}
-	
-		return wasInvalidated;
-	}
-	
-	
-	/**
-	 * Convert from the internal Hungarian notation to camelCase for external
-	 * interaction
-	 *  @param {object} obj Object to convert
-	 *  @returns {object} Inverted object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSearchToCamel ( obj )
-	{
-		return {
-			search:          obj.sSearch,
-			smart:           obj.bSmart,
-			regex:           obj.bRegex,
-			caseInsensitive: obj.bCaseInsensitive
-		};
-	}
-	
-	
-	
-	/**
-	 * Convert from camelCase notation to the internal Hungarian. We could use the
-	 * Hungarian convert function here, but this is cleaner
-	 *  @param {object} obj Object to convert
-	 *  @returns {object} Inverted object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSearchToHung ( obj )
-	{
-		return {
-			sSearch:          obj.search,
-			bSmart:           obj.smart,
-			bRegex:           obj.regex,
-			bCaseInsensitive: obj.caseInsensitive
-		};
-	}
-	
-	/**
-	 * Generate the node required for the info display
-	 *  @param {object} oSettings dataTables settings object
-	 *  @returns {node} Information element
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFeatureHtmlInfo ( settings )
-	{
-		var
-			tid = settings.sTableId,
-			nodes = settings.aanFeatures.i,
-			n = $('<div/>', {
-				'class': settings.oClasses.sInfo,
-				'id': ! nodes ? tid+'_info' : null
-			} );
-	
-		if ( ! nodes ) {
-			// Update display on each draw
-			settings.aoDrawCallback.push( {
-				"fn": _fnUpdateInfo,
-				"sName": "information"
-			} );
-	
-			n
-				.attr( 'role', 'status' )
-				.attr( 'aria-live', 'polite' );
-	
-			// Table is described by our info div
-			$(settings.nTable).attr( 'aria-describedby', tid+'_info' );
-		}
-	
-		return n[0];
-	}
-	
-	
-	/**
-	 * Update the information elements in the display
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnUpdateInfo ( settings )
-	{
-		/* Show information about the table */
-		var nodes = settings.aanFeatures.i;
-		if ( nodes.length === 0 ) {
-			return;
-		}
-	
-		var
-			lang  = settings.oLanguage,
-			start = settings._iDisplayStart+1,
-			end   = settings.fnDisplayEnd(),
-			max   = settings.fnRecordsTotal(),
-			total = settings.fnRecordsDisplay(),
-			out   = total ?
-				lang.sInfo :
-				lang.sInfoEmpty;
-	
-		if ( total !== max ) {
-			/* Record set after filtering */
-			out += ' ' + lang.sInfoFiltered;
-		}
-	
-		// Convert the macros
-		out += lang.sInfoPostFix;
-		out = _fnInfoMacros( settings, out );
-	
-		var callback = lang.fnInfoCallback;
-		if ( callback !== null ) {
-			out = callback.call( settings.oInstance,
-				settings, start, end, max, total, out
-			);
-		}
-	
-		$(nodes).html( out );
-	}
-	
-	
-	function _fnInfoMacros ( settings, str )
-	{
-		// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
-		// internally
-		var
-			formatter  = settings.fnFormatNumber,
-			start      = settings._iDisplayStart+1,
-			len        = settings._iDisplayLength,
-			vis        = settings.fnRecordsDisplay(),
-			all        = len === -1;
-	
-		return str.
-			replace(/_START_/g, formatter.call( settings, start ) ).
-			replace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).
-			replace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).
-			replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
-			replace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
-			replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
-	}
-	
-	
-	
-	/**
-	 * Draw the table for the first time, adding all required features
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnInitialise ( settings )
-	{
-		var i, iLen, iAjaxStart=settings.iInitDisplayStart;
-		var columns = settings.aoColumns, column;
-		var features = settings.oFeatures;
-		var deferLoading = settings.bDeferLoading; // value modified by the draw
-	
-		/* Ensure that the table data is fully initialised */
-		if ( ! settings.bInitialised ) {
-			setTimeout( function(){ _fnInitialise( settings ); }, 200 );
-			return;
-		}
-	
-		/* Show the display HTML options */
-		_fnAddOptionsHtml( settings );
-	
-		/* Build and draw the header / footer for the table */
-		_fnBuildHead( settings );
-		_fnDrawHead( settings, settings.aoHeader );
-		_fnDrawHead( settings, settings.aoFooter );
-	
-		/* Okay to show that something is going on now */
-		_fnProcessingDisplay( settings, true );
-	
-		/* Calculate sizes for columns */
-		if ( features.bAutoWidth ) {
-			_fnCalculateColumnWidths( settings );
-		}
-	
-		for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
-			column = columns[i];
-	
-			if ( column.sWidth ) {
-				column.nTh.style.width = _fnStringToCss( column.sWidth );
-			}
-		}
-	
-		_fnCallbackFire( settings, null, 'preInit', [settings] );
-	
-		// If there is default sorting required - let's do it. The sort function
-		// will do the drawing for us. Otherwise we draw the table regardless of the
-		// Ajax source - this allows the table to look initialised for Ajax sourcing
-		// data (show 'loading' message possibly)
-		_fnReDraw( settings );
-	
-		// Server-side processing init complete is done by _fnAjaxUpdateDraw
-		var dataSrc = _fnDataSource( settings );
-		if ( dataSrc != 'ssp' || deferLoading ) {
-			// if there is an ajax source load the data
-			if ( dataSrc == 'ajax' ) {
-				_fnBuildAjax( settings, [], function(json) {
-					var aData = _fnAjaxDataSrc( settings, json );
-	
-					// Got the data - add it to the table
-					for ( i=0 ; i<aData.length ; i++ ) {
-						_fnAddData( settings, aData[i] );
-					}
-	
-					// Reset the init display for cookie saving. We've already done
-					// a filter, and therefore cleared it before. So we need to make
-					// it appear 'fresh'
-					settings.iInitDisplayStart = iAjaxStart;
-	
-					_fnReDraw( settings );
-	
-					_fnProcessingDisplay( settings, false );
-					_fnInitComplete( settings, json );
-				}, settings );
-			}
-			else {
-				_fnProcessingDisplay( settings, false );
-				_fnInitComplete( settings );
-			}
-		}
-	}
-	
-	
-	/**
-	 * Draw the table for the first time, adding all required features
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {object} [json] JSON from the server that completed the table, if using Ajax source
-	 *    with client-side processing (optional)
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnInitComplete ( settings, json )
-	{
-		settings._bInitComplete = true;
-	
-		// When data was added after the initialisation (data or Ajax) we need to
-		// calculate the column sizing
-		if ( json || settings.oInit.aaData ) {
-			_fnAdjustColumnSizing( settings );
-		}
-	
-		_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
-		_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
-	}
-	
-	
-	function _fnLengthChange ( settings, val )
-	{
-		var len = parseInt( val, 10 );
-		settings._iDisplayLength = len;
-	
-		_fnLengthOverflow( settings );
-	
-		// Fire length change event
-		_fnCallbackFire( settings, null, 'length', [settings, len] );
-	}
-	
-	
-	/**
-	 * Generate the node required for user display length changing
-	 *  @param {object} settings dataTables settings object
-	 *  @returns {node} Display length feature node
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFeatureHtmlLength ( settings )
-	{
-		var
-			classes  = settings.oClasses,
-			tableId  = settings.sTableId,
-			menu     = settings.aLengthMenu,
-			d2       = Array.isArray( menu[0] ),
-			lengths  = d2 ? menu[0] : menu,
-			language = d2 ? menu[1] : menu;
-	
-		var select = $('<select/>', {
-			'name':          tableId+'_length',
-			'aria-controls': tableId,
-			'class':         classes.sLengthSelect
-		} );
-	
-		for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
-			select[0][ i ] = new Option(
-				typeof language[i] === 'number' ?
-					settings.fnFormatNumber( language[i] ) :
-					language[i],
-				lengths[i]
-			);
-		}
-	
-		var div = $('<div><label/></div>').addClass( classes.sLength );
-		if ( ! settings.aanFeatures.l ) {
-			div[0].id = tableId+'_length';
-		}
-	
-		div.children().append(
-			settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
-		);
-	
-		// Can't use `select` variable as user might provide their own and the
-		// reference is broken by the use of outerHTML
-		$('select', div)
-			.val( settings._iDisplayLength )
-			.on( 'change.DT', function(e) {
-				_fnLengthChange( settings, $(this).val() );
-				_fnDraw( settings );
-			} );
-	
-		// Update node value whenever anything changes the table's length
-		$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
-			if ( settings === s ) {
-				$('select', div).val( len );
-			}
-		} );
-	
-		return div[0];
-	}
-	
-	
-	
-	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-	 * Note that most of the paging logic is done in
-	 * DataTable.ext.pager
-	 */
-	
-	/**
-	 * Generate the node required for default pagination
-	 *  @param {object} oSettings dataTables settings object
-	 *  @returns {node} Pagination feature node
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFeatureHtmlPaginate ( settings )
-	{
-		var
-			type   = settings.sPaginationType,
-			plugin = DataTable.ext.pager[ type ],
-			modern = typeof plugin === 'function',
-			redraw = function( settings ) {
-				_fnDraw( settings );
-			},
-			node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
-			features = settings.aanFeatures;
-	
-		if ( ! modern ) {
-			plugin.fnInit( settings, node, redraw );
-		}
-	
-		/* Add a draw callback for the pagination on first instance, to update the paging display */
-		if ( ! features.p )
-		{
-			node.id = settings.sTableId+'_paginate';
-	
-			settings.aoDrawCallback.push( {
-				"fn": function( settings ) {
-					if ( modern ) {
-						var
-							start      = settings._iDisplayStart,
-							len        = settings._iDisplayLength,
-							visRecords = settings.fnRecordsDisplay(),
-							all        = len === -1,
-							page = all ? 0 : Math.ceil( start / len ),
-							pages = all ? 1 : Math.ceil( visRecords / len ),
-							buttons = plugin(page, pages),
-							i, ien;
-	
-						for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
-							_fnRenderer( settings, 'pageButton' )(
-								settings, features.p[i], i, buttons, page, pages
-							);
-						}
-					}
-					else {
-						plugin.fnUpdate( settings, redraw );
-					}
-				},
-				"sName": "pagination"
-			} );
-		}
-	
-		return node;
-	}
-	
-	
-	/**
-	 * Alter the display settings to change the page
-	 *  @param {object} settings DataTables settings object
-	 *  @param {string|int} action Paging action to take: "first", "previous",
-	 *    "next" or "last" or page number to jump to (integer)
-	 *  @param [bool] redraw Automatically draw the update or not
-	 *  @returns {bool} true page has changed, false - no change
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnPageChange ( settings, action, redraw )
-	{
-		var
-			start     = settings._iDisplayStart,
-			len       = settings._iDisplayLength,
-			records   = settings.fnRecordsDisplay();
-	
-		if ( records === 0 || len === -1 )
-		{
-			start = 0;
-		}
-		else if ( typeof action === "number" )
-		{
-			start = action * len;
-	
-			if ( start > records )
-			{
-				start = 0;
-			}
-		}
-		else if ( action == "first" )
-		{
-			start = 0;
-		}
-		else if ( action == "previous" )
-		{
-			start = len >= 0 ?
-				start - len :
-				0;
-	
-			if ( start < 0 )
-			{
-			  start = 0;
-			}
-		}
-		else if ( action == "next" )
-		{
-			if ( start + len < records )
-			{
-				start += len;
-			}
-		}
-		else if ( action == "last" )
-		{
-			start = Math.floor( (records-1) / len) * len;
-		}
-		else
-		{
-			_fnLog( settings, 0, "Unknown paging action: "+action, 5 );
-		}
-	
-		var changed = settings._iDisplayStart !== start;
-		settings._iDisplayStart = start;
-	
-		if ( changed ) {
-			_fnCallbackFire( settings, null, 'page', [settings] );
-	
-			if ( redraw ) {
-				_fnDraw( settings );
-			}
-		}
-	
-		return changed;
-	}
-	
-	
-	
-	/**
-	 * Generate the node required for the processing node
-	 *  @param {object} settings dataTables settings object
-	 *  @returns {node} Processing element
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFeatureHtmlProcessing ( settings )
-	{
-		return $('<div/>', {
-				'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
-				'class': settings.oClasses.sProcessing
-			} )
-			.html( settings.oLanguage.sProcessing )
-			.insertBefore( settings.nTable )[0];
-	}
-	
-	
-	/**
-	 * Display or hide the processing indicator
-	 *  @param {object} settings dataTables settings object
-	 *  @param {bool} show Show the processing indicator (true) or not (false)
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnProcessingDisplay ( settings, show )
-	{
-		if ( settings.oFeatures.bProcessing ) {
-			$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
-		}
-	
-		_fnCallbackFire( settings, null, 'processing', [settings, show] );
-	}
-	
-	/**
-	 * Add any control elements for the table - specifically scrolling
-	 *  @param {object} settings dataTables settings object
-	 *  @returns {node} Node to add to the DOM
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnFeatureHtmlTable ( settings )
-	{
-		var table = $(settings.nTable);
-	
-		// Add the ARIA grid role to the table
-		table.attr( 'role', 'grid' );
-	
-		// Scrolling from here on in
-		var scroll = settings.oScroll;
-	
-		if ( scroll.sX === '' && scroll.sY === '' ) {
-			return settings.nTable;
-		}
-	
-		var scrollX = scroll.sX;
-		var scrollY = scroll.sY;
-		var classes = settings.oClasses;
-		var caption = table.children('caption');
-		var captionSide = caption.length ? caption[0]._captionSide : null;
-		var headerClone = $( table[0].cloneNode(false) );
-		var footerClone = $( table[0].cloneNode(false) );
-		var footer = table.children('tfoot');
-		var _div = '<div/>';
-		var size = function ( s ) {
-			return !s ? null : _fnStringToCss( s );
-		};
-	
-		if ( ! footer.length ) {
-			footer = null;
-		}
-	
-		/*
-		 * The HTML structure that we want to generate in this function is:
-		 *  div - scroller
-		 *    div - scroll head
-		 *      div - scroll head inner
-		 *        table - scroll head table
-		 *          thead - thead
-		 *    div - scroll body
-		 *      table - table (master table)
-		 *        thead - thead clone for sizing
-		 *        tbody - tbody
-		 *    div - scroll foot
-		 *      div - scroll foot inner
-		 *        table - scroll foot table
-		 *          tfoot - tfoot
-		 */
-		var scroller = $( _div, { 'class': classes.sScrollWrapper } )
-			.append(
-				$(_div, { 'class': classes.sScrollHead } )
-					.css( {
-						overflow: 'hidden',
-						position: 'relative',
-						border: 0,
-						width: scrollX ? size(scrollX) : '100%'
-					} )
-					.append(
-						$(_div, { 'class': classes.sScrollHeadInner } )
-							.css( {
-								'box-sizing': 'content-box',
-								width: scroll.sXInner || '100%'
-							} )
-							.append(
-								headerClone
-									.removeAttr('id')
-									.css( 'margin-left', 0 )
-									.append( captionSide === 'top' ? caption : null )
-									.append(
-										table.children('thead')
-									)
-							)
-					)
-			)
-			.append(
-				$(_div, { 'class': classes.sScrollBody } )
-					.css( {
-						position: 'relative',
-						overflow: 'auto',
-						width: size( scrollX )
-					} )
-					.append( table )
-			);
-	
-		if ( footer ) {
-			scroller.append(
-				$(_div, { 'class': classes.sScrollFoot } )
-					.css( {
-						overflow: 'hidden',
-						border: 0,
-						width: scrollX ? size(scrollX) : '100%'
-					} )
-					.append(
-						$(_div, { 'class': classes.sScrollFootInner } )
-							.append(
-								footerClone
-									.removeAttr('id')
-									.css( 'margin-left', 0 )
-									.append( captionSide === 'bottom' ? caption : null )
-									.append(
-										table.children('tfoot')
-									)
-							)
-					)
-			);
-		}
-	
-		var children = scroller.children();
-		var scrollHead = children[0];
-		var scrollBody = children[1];
-		var scrollFoot = footer ? children[2] : null;
-	
-		// When the body is scrolled, then we also want to scroll the headers
-		if ( scrollX ) {
-			$(scrollBody).on( 'scroll.DT', function (e) {
-				var scrollLeft = this.scrollLeft;
-	
-				scrollHead.scrollLeft = scrollLeft;
-	
-				if ( footer ) {
-					scrollFoot.scrollLeft = scrollLeft;
-				}
-			} );
-		}
-	
-		$(scrollBody).css('max-height', scrollY);
-		if (! scroll.bCollapse) {
-			$(scrollBody).css('height', scrollY);
-		}
-	
-		settings.nScrollHead = scrollHead;
-		settings.nScrollBody = scrollBody;
-		settings.nScrollFoot = scrollFoot;
-	
-		// On redraw - align columns
-		settings.aoDrawCallback.push( {
-			"fn": _fnScrollDraw,
-			"sName": "scrolling"
-		} );
-	
-		return scroller[0];
-	}
-	
-	
-	
-	/**
-	 * Update the header, footer and body tables for resizing - i.e. column
-	 * alignment.
-	 *
-	 * Welcome to the most horrible function DataTables. The process that this
-	 * function follows is basically:
-	 *   1. Re-create the table inside the scrolling div
-	 *   2. Take live measurements from the DOM
-	 *   3. Apply the measurements to align the columns
-	 *   4. Clean up
-	 *
-	 *  @param {object} settings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnScrollDraw ( settings )
-	{
-		// Given that this is such a monster function, a lot of variables are use
-		// to try and keep the minimised size as small as possible
-		var
-			scroll         = settings.oScroll,
-			scrollX        = scroll.sX,
-			scrollXInner   = scroll.sXInner,
-			scrollY        = scroll.sY,
-			barWidth       = scroll.iBarWidth,
-			divHeader      = $(settings.nScrollHead),
-			divHeaderStyle = divHeader[0].style,
-			divHeaderInner = divHeader.children('div'),
-			divHeaderInnerStyle = divHeaderInner[0].style,
-			divHeaderTable = divHeaderInner.children('table'),
-			divBodyEl      = settings.nScrollBody,
-			divBody        = $(divBodyEl),
-			divBodyStyle   = divBodyEl.style,
-			divFooter      = $(settings.nScrollFoot),
-			divFooterInner = divFooter.children('div'),
-			divFooterTable = divFooterInner.children('table'),
-			header         = $(settings.nTHead),
-			table          = $(settings.nTable),
-			tableEl        = table[0],
-			tableStyle     = tableEl.style,
-			footer         = settings.nTFoot ? $(settings.nTFoot) : null,
-			browser        = settings.oBrowser,
-			ie67           = browser.bScrollOversize,
-			dtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),
-			headerTrgEls, footerTrgEls,
-			headerSrcEls, footerSrcEls,
-			headerCopy, footerCopy,
-			headerWidths=[], footerWidths=[],
-			headerContent=[], footerContent=[],
-			idx, correction, sanityWidth,
-			zeroOut = function(nSizer) {
-				var style = nSizer.style;
-				style.paddingTop = "0";
-				style.paddingBottom = "0";
-				style.borderTopWidth = "0";
-				style.borderBottomWidth = "0";
-				style.height = 0;
-			};
-	
-		// If the scrollbar visibility has changed from the last draw, we need to
-		// adjust the column sizes as the table width will have changed to account
-		// for the scrollbar
-		var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
-		
-		if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
-			settings.scrollBarVis = scrollBarVis;
-			_fnAdjustColumnSizing( settings );
-			return; // adjust column sizing will call this function again
-		}
-		else {
-			settings.scrollBarVis = scrollBarVis;
-		}
-	
-		/*
-		 * 1. Re-create the table inside the scrolling div
-		 */
-	
-		// Remove the old minimised thead and tfoot elements in the inner table
-		table.children('thead, tfoot').remove();
-	
-		if ( footer ) {
-			footerCopy = footer.clone().prependTo( table );
-			footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
-			footerSrcEls = footerCopy.find('tr');
-		}
-	
-		// Clone the current header and footer elements and then place it into the inner table
-		headerCopy = header.clone().prependTo( table );
-		headerTrgEls = header.find('tr'); // original header is in its own table
-		headerSrcEls = headerCopy.find('tr');
-		headerCopy.find('th, td').removeAttr('tabindex');
-	
-	
-		/*
-		 * 2. Take live measurements from the DOM - do not alter the DOM itself!
-		 */
-	
-		// Remove old sizing and apply the calculated column widths
-		// Get the unique column headers in the newly created (cloned) header. We want to apply the
-		// calculated sizes to this header
-		if ( ! scrollX )
-		{
-			divBodyStyle.width = '100%';
-			divHeader[0].style.width = '100%';
-		}
-	
-		$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
-			idx = _fnVisibleToColumnIndex( settings, i );
-			el.style.width = settings.aoColumns[idx].sWidth;
-		} );
-	
-		if ( footer ) {
-			_fnApplyToChildren( function(n) {
-				n.style.width = "";
-			}, footerSrcEls );
-		}
-	
-		// Size the table as a whole
-		sanityWidth = table.outerWidth();
-		if ( scrollX === "" ) {
-			// No x scrolling
-			tableStyle.width = "100%";
-	
-			// IE7 will make the width of the table when 100% include the scrollbar
-			// - which is shouldn't. When there is a scrollbar we need to take this
-			// into account.
-			if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
-				divBody.css('overflow-y') == "scroll")
-			) {
-				tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
-			}
-	
-			// Recalculate the sanity width
-			sanityWidth = table.outerWidth();
-		}
-		else if ( scrollXInner !== "" ) {
-			// legacy x scroll inner has been given - use it
-			tableStyle.width = _fnStringToCss(scrollXInner);
-	
-			// Recalculate the sanity width
-			sanityWidth = table.outerWidth();
-		}
-	
-		// Hidden header should have zero height, so remove padding and borders. Then
-		// set the width based on the real headers
-	
-		// Apply all styles in one pass
-		_fnApplyToChildren( zeroOut, headerSrcEls );
-	
-		// Read all widths in next pass
-		_fnApplyToChildren( function(nSizer) {
-			headerContent.push( nSizer.innerHTML );
-			headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
-		}, headerSrcEls );
-	
-		// Apply all widths in final pass
-		_fnApplyToChildren( function(nToSize, i) {
-			// Only apply widths to the DataTables detected header cells - this
-			// prevents complex headers from having contradictory sizes applied
-			if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
-				nToSize.style.width = headerWidths[i];
-			}
-		}, headerTrgEls );
-	
-		$(headerSrcEls).height(0);
-	
-		/* Same again with the footer if we have one */
-		if ( footer )
-		{
-			_fnApplyToChildren( zeroOut, footerSrcEls );
-	
-			_fnApplyToChildren( function(nSizer) {
-				footerContent.push( nSizer.innerHTML );
-				footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
-			}, footerSrcEls );
-	
-			_fnApplyToChildren( function(nToSize, i) {
-				nToSize.style.width = footerWidths[i];
-			}, footerTrgEls );
-	
-			$(footerSrcEls).height(0);
-		}
-	
-	
-		/*
-		 * 3. Apply the measurements
-		 */
-	
-		// "Hide" the header and footer that we used for the sizing. We need to keep
-		// the content of the cell so that the width applied to the header and body
-		// both match, but we want to hide it completely. We want to also fix their
-		// width to what they currently are
-		_fnApplyToChildren( function(nSizer, i) {
-			nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>';
-			nSizer.childNodes[0].style.height = "0";
-			nSizer.childNodes[0].style.overflow = "hidden";
-			nSizer.style.width = headerWidths[i];
-		}, headerSrcEls );
-	
-		if ( footer )
-		{
-			_fnApplyToChildren( function(nSizer, i) {
-				nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
-				nSizer.childNodes[0].style.height = "0";
-				nSizer.childNodes[0].style.overflow = "hidden";
-				nSizer.style.width = footerWidths[i];
-			}, footerSrcEls );
-		}
-	
-		// Sanity check that the table is of a sensible width. If not then we are going to get
-		// misalignment - try to prevent this by not allowing the table to shrink below its min width
-		if ( table.outerWidth() < sanityWidth )
-		{
-			// The min width depends upon if we have a vertical scrollbar visible or not */
-			correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
-				divBody.css('overflow-y') == "scroll")) ?
-					sanityWidth+barWidth :
-					sanityWidth;
-	
-			// IE6/7 are a law unto themselves...
-			if ( ie67 && (divBodyEl.scrollHeight >
-				divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
-			) {
-				tableStyle.width = _fnStringToCss( correction-barWidth );
-			}
-	
-			// And give the user a warning that we've stopped the table getting too small
-			if ( scrollX === "" || scrollXInner !== "" ) {
-				_fnLog( settings, 1, 'Possible column misalignment', 6 );
-			}
-		}
-		else
-		{
-			correction = '100%';
-		}
-	
-		// Apply to the container elements
-		divBodyStyle.width = _fnStringToCss( correction );
-		divHeaderStyle.width = _fnStringToCss( correction );
-	
-		if ( footer ) {
-			settings.nScrollFoot.style.width = _fnStringToCss( correction );
-		}
-	
-	
-		/*
-		 * 4. Clean up
-		 */
-		if ( ! scrollY ) {
-			/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
-			 * the scrollbar height from the visible display, rather than adding it on. We need to
-			 * set the height in order to sort this. Don't want to do it in any other browsers.
-			 */
-			if ( ie67 ) {
-				divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
-			}
-		}
-	
-		/* Finally set the width's of the header and footer tables */
-		var iOuterWidth = table.outerWidth();
-		divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
-		divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
-	
-		// Figure out if there are scrollbar present - if so then we need a the header and footer to
-		// provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
-		var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
-		var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
-		divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
-	
-		if ( footer ) {
-			divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
-			divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
-			divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
-		}
-	
-		// Correct DOM ordering for colgroup - comes before the thead
-		table.children('colgroup').insertBefore( table.children('thead') );
-	
-		/* Adjust the position of the header in case we loose the y-scrollbar */
-		divBody.trigger('scroll');
-	
-		// If sorting or filtering has occurred, jump the scrolling back to the top
-		// only if we aren't holding the position
-		if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
-			divBodyEl.scrollTop = 0;
-		}
-	}
-	
-	
-	
-	/**
-	 * Apply a given function to the display child nodes of an element array (typically
-	 * TD children of TR rows
-	 *  @param {function} fn Method to apply to the objects
-	 *  @param array {nodes} an1 List of elements to look through for display children
-	 *  @param array {nodes} an2 Another list (identical structure to the first) - optional
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnApplyToChildren( fn, an1, an2 )
-	{
-		var index=0, i=0, iLen=an1.length;
-		var nNode1, nNode2;
-	
-		while ( i < iLen ) {
-			nNode1 = an1[i].firstChild;
-			nNode2 = an2 ? an2[i].firstChild : null;
-	
-			while ( nNode1 ) {
-				if ( nNode1.nodeType === 1 ) {
-					if ( an2 ) {
-						fn( nNode1, nNode2, index );
-					}
-					else {
-						fn( nNode1, index );
-					}
-	
-					index++;
-				}
-	
-				nNode1 = nNode1.nextSibling;
-				nNode2 = an2 ? nNode2.nextSibling : null;
-			}
-	
-			i++;
-		}
-	}
-	
-	
-	
-	var __re_html_remove = /<.*?>/g;
-	
-	
-	/**
-	 * Calculate the width of columns for the table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnCalculateColumnWidths ( oSettings )
-	{
-		var
-			table = oSettings.nTable,
-			columns = oSettings.aoColumns,
-			scroll = oSettings.oScroll,
-			scrollY = scroll.sY,
-			scrollX = scroll.sX,
-			scrollXInner = scroll.sXInner,
-			columnCount = columns.length,
-			visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
-			headerCells = $('th', oSettings.nTHead),
-			tableWidthAttr = table.getAttribute('width'), // from DOM element
-			tableContainer = table.parentNode,
-			userInputs = false,
-			i, column, columnIdx, width, outerWidth,
-			browser = oSettings.oBrowser,
-			ie67 = browser.bScrollOversize;
-	
-		var styleWidth = table.style.width;
-		if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
-			tableWidthAttr = styleWidth;
-		}
-	
-		/* Convert any user input sizes into pixel sizes */
-		for ( i=0 ; i<visibleColumns.length ; i++ ) {
-			column = columns[ visibleColumns[i] ];
-	
-			if ( column.sWidth !== null ) {
-				column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
-	
-				userInputs = true;
-			}
-		}
-	
-		/* If the number of columns in the DOM equals the number that we have to
-		 * process in DataTables, then we can use the offsets that are created by
-		 * the web- browser. No custom sizes can be set in order for this to happen,
-		 * nor scrolling used
-		 */
-		if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
-		     columnCount == _fnVisbleColumns( oSettings ) &&
-		     columnCount == headerCells.length
-		) {
-			for ( i=0 ; i<columnCount ; i++ ) {
-				var colIdx = _fnVisibleToColumnIndex( oSettings, i );
-	
-				if ( colIdx !== null ) {
-					columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
-				}
-			}
-		}
-		else
-		{
-			// Otherwise construct a single row, worst case, table with the widest
-			// node in the data, assign any user defined widths, then insert it into
-			// the DOM and allow the browser to do all the hard work of calculating
-			// table widths
-			var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
-				.css( 'visibility', 'hidden' )
-				.removeAttr( 'id' );
-	
-			// Clean up the table body
-			tmpTable.find('tbody tr').remove();
-			var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
-	
-			// Clone the table header and footer - we can't use the header / footer
-			// from the cloned table, since if scrolling is active, the table's
-			// real header and footer are contained in different table tags
-			tmpTable.find('thead, tfoot').remove();
-			tmpTable
-				.append( $(oSettings.nTHead).clone() )
-				.append( $(oSettings.nTFoot).clone() );
-	
-			// Remove any assigned widths from the footer (from scrolling)
-			tmpTable.find('tfoot th, tfoot td').css('width', '');
-	
-			// Apply custom sizing to the cloned header
-			headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
-	
-			for ( i=0 ; i<visibleColumns.length ; i++ ) {
-				column = columns[ visibleColumns[i] ];
-	
-				headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
-					_fnStringToCss( column.sWidthOrig ) :
-					'';
-	
-				// For scrollX we need to force the column width otherwise the
-				// browser will collapse it. If this width is smaller than the
-				// width the column requires, then it will have no effect
-				if ( column.sWidthOrig && scrollX ) {
-					$( headerCells[i] ).append( $('<div/>').css( {
-						width: column.sWidthOrig,
-						margin: 0,
-						padding: 0,
-						border: 0,
-						height: 1
-					} ) );
-				}
-			}
-	
-			// Find the widest cell for each column and put it into the table
-			if ( oSettings.aoData.length ) {
-				for ( i=0 ; i<visibleColumns.length ; i++ ) {
-					columnIdx = visibleColumns[i];
-					column = columns[ columnIdx ];
-	
-					$( _fnGetWidestNode( oSettings, columnIdx ) )
-						.clone( false )
-						.append( column.sContentPadding )
-						.appendTo( tr );
-				}
-			}
-	
-			// Tidy the temporary table - remove name attributes so there aren't
-			// duplicated in the dom (radio elements for example)
-			$('[name]', tmpTable).removeAttr('name');
-	
-			// Table has been built, attach to the document so we can work with it.
-			// A holding element is used, positioned at the top of the container
-			// with minimal height, so it has no effect on if the container scrolls
-			// or not. Otherwise it might trigger scrolling when it actually isn't
-			// needed
-			var holder = $('<div/>').css( scrollX || scrollY ?
-					{
-						position: 'absolute',
-						top: 0,
-						left: 0,
-						height: 1,
-						right: 0,
-						overflow: 'hidden'
-					} :
-					{}
-				)
-				.append( tmpTable )
-				.appendTo( tableContainer );
-	
-			// When scrolling (X or Y) we want to set the width of the table as 
-			// appropriate. However, when not scrolling leave the table width as it
-			// is. This results in slightly different, but I think correct behaviour
-			if ( scrollX && scrollXInner ) {
-				tmpTable.width( scrollXInner );
-			}
-			else if ( scrollX ) {
-				tmpTable.css( 'width', 'auto' );
-				tmpTable.removeAttr('width');
-	
-				// If there is no width attribute or style, then allow the table to
-				// collapse
-				if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
-					tmpTable.width( tableContainer.clientWidth );
-				}
-			}
-			else if ( scrollY ) {
-				tmpTable.width( tableContainer.clientWidth );
-			}
-			else if ( tableWidthAttr ) {
-				tmpTable.width( tableWidthAttr );
-			}
-	
-			// Get the width of each column in the constructed table - we need to
-			// know the inner width (so it can be assigned to the other table's
-			// cells) and the outer width so we can calculate the full width of the
-			// table. This is safe since DataTables requires a unique cell for each
-			// column, but if ever a header can span multiple columns, this will
-			// need to be modified.
-			var total = 0;
-			for ( i=0 ; i<visibleColumns.length ; i++ ) {
-				var cell = $(headerCells[i]);
-				var border = cell.outerWidth() - cell.width();
-	
-				// Use getBounding... where possible (not IE8-) because it can give
-				// sub-pixel accuracy, which we then want to round up!
-				var bounding = browser.bBounding ?
-					Math.ceil( headerCells[i].getBoundingClientRect().width ) :
-					cell.outerWidth();
-	
-				// Total is tracked to remove any sub-pixel errors as the outerWidth
-				// of the table might not equal the total given here (IE!).
-				total += bounding;
-	
-				// Width for each column to use
-				columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
-			}
-	
-			table.style.width = _fnStringToCss( total );
-	
-			// Finished with the table - ditch it
-			holder.remove();
-		}
-	
-		// If there is a width attr, we want to attach an event listener which
-		// allows the table sizing to automatically adjust when the window is
-		// resized. Use the width attr rather than CSS, since we can't know if the
-		// CSS is a relative value or absolute - DOM read is always px.
-		if ( tableWidthAttr ) {
-			table.style.width = _fnStringToCss( tableWidthAttr );
-		}
-	
-		if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
-			var bindResize = function () {
-				$(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
-					_fnAdjustColumnSizing( oSettings );
-				} ) );
-			};
-	
-			// IE6/7 will crash if we bind a resize event handler on page load.
-			// To be removed in 1.11 which drops IE6/7 support
-			if ( ie67 ) {
-				setTimeout( bindResize, 1000 );
-			}
-			else {
-				bindResize();
-			}
-	
-			oSettings._reszEvt = true;
-		}
-	}
-	
-	
-	/**
-	 * Throttle the calls to a function. Arguments and context are maintained for
-	 * the throttled function
-	 *  @param {function} fn Function to be called
-	 *  @param {int} [freq=200] call frequency in mS
-	 *  @returns {function} wrapped function
-	 *  @memberof DataTable#oApi
-	 */
-	var _fnThrottle = DataTable.util.throttle;
-	
-	
-	/**
-	 * Convert a CSS unit width to pixels (e.g. 2em)
-	 *  @param {string} width width to be converted
-	 *  @param {node} parent parent to get the with for (required for relative widths) - optional
-	 *  @returns {int} width in pixels
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnConvertToWidth ( width, parent )
-	{
-		if ( ! width ) {
-			return 0;
-		}
-	
-		var n = $('<div/>')
-			.css( 'width', _fnStringToCss( width ) )
-			.appendTo( parent || document.body );
-	
-		var val = n[0].offsetWidth;
-		n.remove();
-	
-		return val;
-	}
-	
-	
-	/**
-	 * Get the widest node
-	 *  @param {object} settings dataTables settings object
-	 *  @param {int} colIdx column of interest
-	 *  @returns {node} widest table node
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetWidestNode( settings, colIdx )
-	{
-		var idx = _fnGetMaxLenString( settings, colIdx );
-		if ( idx < 0 ) {
-			return null;
-		}
-	
-		var data = settings.aoData[ idx ];
-		return ! data.nTr ? // Might not have been created when deferred rendering
-			$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
-			data.anCells[ colIdx ];
-	}
-	
-	
-	/**
-	 * Get the maximum strlen for each data column
-	 *  @param {object} settings dataTables settings object
-	 *  @param {int} colIdx column of interest
-	 *  @returns {string} max string length for each column
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnGetMaxLenString( settings, colIdx )
-	{
-		var s, max=-1, maxIdx = -1;
-	
-		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
-			s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
-			s = s.replace( __re_html_remove, '' );
-			s = s.replace( /&nbsp;/g, ' ' );
-	
-			if ( s.length > max ) {
-				max = s.length;
-				maxIdx = i;
-			}
-		}
-	
-		return maxIdx;
-	}
-	
-	
-	/**
-	 * Append a CSS unit (only if required) to a string
-	 *  @param {string} value to css-ify
-	 *  @returns {string} value with css unit
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnStringToCss( s )
-	{
-		if ( s === null ) {
-			return '0px';
-		}
-	
-		if ( typeof s == 'number' ) {
-			return s < 0 ?
-				'0px' :
-				s+'px';
-		}
-	
-		// Check it has a unit character already
-		return s.match(/\d$/) ?
-			s+'px' :
-			s;
-	}
-	
-	
-	
-	function _fnSortFlatten ( settings )
-	{
-		var
-			i, iLen, k, kLen,
-			aSort = [],
-			aiOrig = [],
-			aoColumns = settings.aoColumns,
-			aDataSort, iCol, sType, srcCol,
-			fixed = settings.aaSortingFixed,
-			fixedObj = $.isPlainObject( fixed ),
-			nestedSort = [],
-			add = function ( a ) {
-				if ( a.length && ! Array.isArray( a[0] ) ) {
-					// 1D array
-					nestedSort.push( a );
-				}
-				else {
-					// 2D array
-					$.merge( nestedSort, a );
-				}
-			};
-	
-		// Build the sort array, with pre-fix and post-fix options if they have been
-		// specified
-		if ( Array.isArray( fixed ) ) {
-			add( fixed );
-		}
-	
-		if ( fixedObj && fixed.pre ) {
-			add( fixed.pre );
-		}
-	
-		add( settings.aaSorting );
-	
-		if (fixedObj && fixed.post ) {
-			add( fixed.post );
-		}
-	
-		for ( i=0 ; i<nestedSort.length ; i++ )
-		{
-			srcCol = nestedSort[i][0];
-			aDataSort = aoColumns[ srcCol ].aDataSort;
-	
-			for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
-			{
-				iCol = aDataSort[k];
-				sType = aoColumns[ iCol ].sType || 'string';
-	
-				if ( nestedSort[i]._idx === undefined ) {
-					nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
-				}
-	
-				aSort.push( {
-					src:       srcCol,
-					col:       iCol,
-					dir:       nestedSort[i][1],
-					index:     nestedSort[i]._idx,
-					type:      sType,
-					formatter: DataTable.ext.type.order[ sType+"-pre" ]
-				} );
-			}
-		}
-	
-		return aSort;
-	}
-	
-	/**
-	 * Change the order of the table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 *  @todo This really needs split up!
-	 */
-	function _fnSort ( oSettings )
-	{
-		var
-			i, ien, iLen, j, jLen, k, kLen,
-			sDataType, nTh,
-			aiOrig = [],
-			oExtSort = DataTable.ext.type.order,
-			aoData = oSettings.aoData,
-			aoColumns = oSettings.aoColumns,
-			aDataSort, data, iCol, sType, oSort,
-			formatters = 0,
-			sortCol,
-			displayMaster = oSettings.aiDisplayMaster,
-			aSort;
-	
-		// Resolve any column types that are unknown due to addition or invalidation
-		// @todo Can this be moved into a 'data-ready' handler which is called when
-		//   data is going to be used in the table?
-		_fnColumnTypes( oSettings );
-	
-		aSort = _fnSortFlatten( oSettings );
-	
-		for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
-			sortCol = aSort[i];
-	
-			// Track if we can use the fast sort algorithm
-			if ( sortCol.formatter ) {
-				formatters++;
-			}
-	
-			// Load the data needed for the sort, for each cell
-			_fnSortData( oSettings, sortCol.col );
-		}
-	
-		/* No sorting required if server-side or no sorting array */
-		if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
-		{
-			// Create a value - key array of the current row positions such that we can use their
-			// current position during the sort, if values match, in order to perform stable sorting
-			for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
-				aiOrig[ displayMaster[i] ] = i;
-			}
-	
-			/* Do the sort - here we want multi-column sorting based on a given data source (column)
-			 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
-			 * follow on it's own, but this is what we want (example two column sorting):
-			 *  fnLocalSorting = function(a,b){
-			 *    var iTest;
-			 *    iTest = oSort['string-asc']('data11', 'data12');
-			 *      if (iTest !== 0)
-			 *        return iTest;
-			 *    iTest = oSort['numeric-desc']('data21', 'data22');
-			 *    if (iTest !== 0)
-			 *      return iTest;
-			 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
-			 *  }
-			 * Basically we have a test for each sorting column, if the data in that column is equal,
-			 * test the next column. If all columns match, then we use a numeric sort on the row
-			 * positions in the original data array to provide a stable sort.
-			 *
-			 * Note - I know it seems excessive to have two sorting methods, but the first is around
-			 * 15% faster, so the second is only maintained for backwards compatibility with sorting
-			 * methods which do not have a pre-sort formatting function.
-			 */
-			if ( formatters === aSort.length ) {
-				// All sort types have formatting functions
-				displayMaster.sort( function ( a, b ) {
-					var
-						x, y, k, test, sort,
-						len=aSort.length,
-						dataA = aoData[a]._aSortData,
-						dataB = aoData[b]._aSortData;
-	
-					for ( k=0 ; k<len ; k++ ) {
-						sort = aSort[k];
-	
-						x = dataA[ sort.col ];
-						y = dataB[ sort.col ];
-	
-						test = x<y ? -1 : x>y ? 1 : 0;
-						if ( test !== 0 ) {
-							return sort.dir === 'asc' ? test : -test;
-						}
-					}
-	
-					x = aiOrig[a];
-					y = aiOrig[b];
-					return x<y ? -1 : x>y ? 1 : 0;
-				} );
-			}
-			else {
-				// Depreciated - remove in 1.11 (providing a plug-in option)
-				// Not all sort types have formatting methods, so we have to call their sorting
-				// methods.
-				displayMaster.sort( function ( a, b ) {
-					var
-						x, y, k, l, test, sort, fn,
-						len=aSort.length,
-						dataA = aoData[a]._aSortData,
-						dataB = aoData[b]._aSortData;
-	
-					for ( k=0 ; k<len ; k++ ) {
-						sort = aSort[k];
-	
-						x = dataA[ sort.col ];
-						y = dataB[ sort.col ];
-	
-						fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
-						test = fn( x, y );
-						if ( test !== 0 ) {
-							return test;
-						}
-					}
-	
-					x = aiOrig[a];
-					y = aiOrig[b];
-					return x<y ? -1 : x>y ? 1 : 0;
-				} );
-			}
-		}
-	
-		/* Tell the draw function that we have sorted the data */
-		oSettings.bSorted = true;
-	}
-	
-	
-	function _fnSortAria ( settings )
-	{
-		var label;
-		var nextSort;
-		var columns = settings.aoColumns;
-		var aSort = _fnSortFlatten( settings );
-		var oAria = settings.oLanguage.oAria;
-	
-		// ARIA attributes - need to loop all columns, to update all (removing old
-		// attributes as needed)
-		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
-		{
-			var col = columns[i];
-			var asSorting = col.asSorting;
-			var sTitle = col.sTitle.replace( /<.*?>/g, "" );
-			var th = col.nTh;
-	
-			// IE7 is throwing an error when setting these properties with jQuery's
-			// attr() and removeAttr() methods...
-			th.removeAttribute('aria-sort');
-	
-			/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
-			if ( col.bSortable ) {
-				if ( aSort.length > 0 && aSort[0].col == i ) {
-					th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
-					nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
-				}
-				else {
-					nextSort = asSorting[0];
-				}
-	
-				label = sTitle + ( nextSort === "asc" ?
-					oAria.sSortAscending :
-					oAria.sSortDescending
-				);
-			}
-			else {
-				label = sTitle;
-			}
-	
-			th.setAttribute('aria-label', label);
-		}
-	}
-	
-	
-	/**
-	 * Function to run on user sort request
-	 *  @param {object} settings dataTables settings object
-	 *  @param {node} attachTo node to attach the handler to
-	 *  @param {int} colIdx column sorting index
-	 *  @param {boolean} [append=false] Append the requested sort to the existing
-	 *    sort if true (i.e. multi-column sort)
-	 *  @param {function} [callback] callback function
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSortListener ( settings, colIdx, append, callback )
-	{
-		var col = settings.aoColumns[ colIdx ];
-		var sorting = settings.aaSorting;
-		var asSorting = col.asSorting;
-		var nextSortIdx;
-		var next = function ( a, overflow ) {
-			var idx = a._idx;
-			if ( idx === undefined ) {
-				idx = $.inArray( a[1], asSorting );
-			}
-	
-			return idx+1 < asSorting.length ?
-				idx+1 :
-				overflow ?
-					null :
-					0;
-		};
-	
-		// Convert to 2D array if needed
-		if ( typeof sorting[0] === 'number' ) {
-			sorting = settings.aaSorting = [ sorting ];
-		}
-	
-		// If appending the sort then we are multi-column sorting
-		if ( append && settings.oFeatures.bSortMulti ) {
-			// Are we already doing some kind of sort on this column?
-			var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
-	
-			if ( sortIdx !== -1 ) {
-				// Yes, modify the sort
-				nextSortIdx = next( sorting[sortIdx], true );
-	
-				if ( nextSortIdx === null && sorting.length === 1 ) {
-					nextSortIdx = 0; // can't remove sorting completely
-				}
-	
-				if ( nextSortIdx === null ) {
-					sorting.splice( sortIdx, 1 );
-				}
-				else {
-					sorting[sortIdx][1] = asSorting[ nextSortIdx ];
-					sorting[sortIdx]._idx = nextSortIdx;
-				}
-			}
-			else {
-				// No sort on this column yet
-				sorting.push( [ colIdx, asSorting[0], 0 ] );
-				sorting[sorting.length-1]._idx = 0;
-			}
-		}
-		else if ( sorting.length && sorting[0][0] == colIdx ) {
-			// Single column - already sorting on this column, modify the sort
-			nextSortIdx = next( sorting[0] );
-	
-			sorting.length = 1;
-			sorting[0][1] = asSorting[ nextSortIdx ];
-			sorting[0]._idx = nextSortIdx;
-		}
-		else {
-			// Single column - sort only on this column
-			sorting.length = 0;
-			sorting.push( [ colIdx, asSorting[0] ] );
-			sorting[0]._idx = 0;
-		}
-	
-		// Run the sort by calling a full redraw
-		_fnReDraw( settings );
-	
-		// callback used for async user interaction
-		if ( typeof callback == 'function' ) {
-			callback( settings );
-		}
-	}
-	
-	
-	/**
-	 * Attach a sort handler (click) to a node
-	 *  @param {object} settings dataTables settings object
-	 *  @param {node} attachTo node to attach the handler to
-	 *  @param {int} colIdx column sorting index
-	 *  @param {function} [callback] callback function
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
-	{
-		var col = settings.aoColumns[ colIdx ];
-	
-		_fnBindAction( attachTo, {}, function (e) {
-			/* If the column is not sortable - don't to anything */
-			if ( col.bSortable === false ) {
-				return;
-			}
-	
-			// If processing is enabled use a timeout to allow the processing
-			// display to be shown - otherwise to it synchronously
-			if ( settings.oFeatures.bProcessing ) {
-				_fnProcessingDisplay( settings, true );
-	
-				setTimeout( function() {
-					_fnSortListener( settings, colIdx, e.shiftKey, callback );
-	
-					// In server-side processing, the draw callback will remove the
-					// processing display
-					if ( _fnDataSource( settings ) !== 'ssp' ) {
-						_fnProcessingDisplay( settings, false );
-					}
-				}, 0 );
-			}
-			else {
-				_fnSortListener( settings, colIdx, e.shiftKey, callback );
-			}
-		} );
-	}
-	
-	
-	/**
-	 * Set the sorting classes on table's body, Note: it is safe to call this function
-	 * when bSort and bSortClasses are false
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSortingClasses( settings )
-	{
-		var oldSort = settings.aLastSort;
-		var sortClass = settings.oClasses.sSortColumn;
-		var sort = _fnSortFlatten( settings );
-		var features = settings.oFeatures;
-		var i, ien, colIdx;
-	
-		if ( features.bSort && features.bSortClasses ) {
-			// Remove old sorting classes
-			for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
-				colIdx = oldSort[i].src;
-	
-				// Remove column sorting
-				$( _pluck( settings.aoData, 'anCells', colIdx ) )
-					.removeClass( sortClass + (i<2 ? i+1 : 3) );
-			}
-	
-			// Add new column sorting
-			for ( i=0, ien=sort.length ; i<ien ; i++ ) {
-				colIdx = sort[i].src;
-	
-				$( _pluck( settings.aoData, 'anCells', colIdx ) )
-					.addClass( sortClass + (i<2 ? i+1 : 3) );
-			}
-		}
-	
-		settings.aLastSort = sort;
-	}
-	
-	
-	// Get the data to sort a column, be it from cache, fresh (populating the
-	// cache), or from a sort formatter
-	function _fnSortData( settings, idx )
-	{
-		// Custom sorting function - provided by the sort data type
-		var column = settings.aoColumns[ idx ];
-		var customSort = DataTable.ext.order[ column.sSortDataType ];
-		var customData;
-	
-		if ( customSort ) {
-			customData = customSort.call( settings.oInstance, settings, idx,
-				_fnColumnIndexToVisible( settings, idx )
-			);
-		}
-	
-		// Use / populate cache
-		var row, cellData;
-		var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
-	
-		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
-			row = settings.aoData[i];
-	
-			if ( ! row._aSortData ) {
-				row._aSortData = [];
-			}
-	
-			if ( ! row._aSortData[idx] || customSort ) {
-				cellData = customSort ?
-					customData[i] : // If there was a custom sort function, use data from there
-					_fnGetCellData( settings, i, idx, 'sort' );
-	
-				row._aSortData[ idx ] = formatter ?
-					formatter( cellData ) :
-					cellData;
-			}
-		}
-	}
-	
-	
-	
-	/**
-	 * Save the state of a table
-	 *  @param {object} oSettings dataTables settings object
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSaveState ( settings )
-	{
-		if ( !settings.oFeatures.bStateSave || settings.bDestroying )
-		{
-			return;
-		}
-	
-		/* Store the interesting variables */
-		var state = {
-			time:    +new Date(),
-			start:   settings._iDisplayStart,
-			length:  settings._iDisplayLength,
-			order:   $.extend( true, [], settings.aaSorting ),
-			search:  _fnSearchToCamel( settings.oPreviousSearch ),
-			columns: $.map( settings.aoColumns, function ( col, i ) {
-				return {
-					visible: col.bVisible,
-					search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
-				};
-			} )
-		};
-	
-		_fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
-	
-		settings.oSavedState = state;
-		settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
-	}
-	
-	
-	/**
-	 * Attempt to load a saved table state
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {object} oInit DataTables init object so we can override settings
-	 *  @param {function} callback Callback to execute when the state has been loaded
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnLoadState ( settings, oInit, callback )
-	{
-		var i, ien;
-		var columns = settings.aoColumns;
-		var loaded = function ( s ) {
-			if ( ! s || ! s.time ) {
-				callback();
-				return;
-			}
-	
-			// Allow custom and plug-in manipulation functions to alter the saved data set and
-			// cancelling of loading by returning false
-			var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );
-			if ( $.inArray( false, abStateLoad ) !== -1 ) {
-				callback();
-				return;
-			}
-	
-			// Reject old data
-			var duration = settings.iStateDuration;
-			if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
-				callback();
-				return;
-			}
-	
-			// Number of columns have changed - all bets are off, no restore of settings
-			if ( s.columns && columns.length !== s.columns.length ) {
-				callback();
-				return;
-			}
-	
-			// Store the saved state so it might be accessed at any time
-			settings.oLoadedState = $.extend( true, {}, s );
-	
-			// Restore key features - todo - for 1.11 this needs to be done by
-			// subscribed events
-			if ( s.start !== undefined ) {
-				settings._iDisplayStart    = s.start;
-				settings.iInitDisplayStart = s.start;
-			}
-			if ( s.length !== undefined ) {
-				settings._iDisplayLength   = s.length;
-			}
-	
-			// Order
-			if ( s.order !== undefined ) {
-				settings.aaSorting = [];
-				$.each( s.order, function ( i, col ) {
-					settings.aaSorting.push( col[0] >= columns.length ?
-						[ 0, col[1] ] :
-						col
-					);
-				} );
-			}
-	
-			// Search
-			if ( s.search !== undefined ) {
-				$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
-			}
-	
-			// Columns
-			//
-			if ( s.columns ) {
-				for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
-					var col = s.columns[i];
-	
-					// Visibility
-					if ( col.visible !== undefined ) {
-						columns[i].bVisible = col.visible;
-					}
-	
-					// Search
-					if ( col.search !== undefined ) {
-						$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
-					}
-				}
-			}
-	
-			_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );
-			callback();
-		};
-	
-		if ( ! settings.oFeatures.bStateSave ) {
-			callback();
-			return;
-		}
-	
-		var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
-	
-		if ( state !== undefined ) {
-			loaded( state );
-		}
-		// otherwise, wait for the loaded callback to be executed
-	}
-	
-	
-	/**
-	 * Return the settings object for a particular table
-	 *  @param {node} table table we are using as a dataTable
-	 *  @returns {object} Settings object - or null if not found
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnSettingsFromNode ( table )
-	{
-		var settings = DataTable.settings;
-		var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
-	
-		return idx !== -1 ?
-			settings[ idx ] :
-			null;
-	}
-	
-	
-	/**
-	 * Log an error message
-	 *  @param {object} settings dataTables settings object
-	 *  @param {int} level log error messages, or display them to the user
-	 *  @param {string} msg error message
-	 *  @param {int} tn Technical note id to get more information about the error.
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnLog( settings, level, msg, tn )
-	{
-		msg = 'DataTables warning: '+
-			(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
-	
-		if ( tn ) {
-			msg += '. For more information about this error, please see '+
-			'http://datatables.net/tn/'+tn;
-		}
-	
-		if ( ! level  ) {
-			// Backwards compatibility pre 1.10
-			var ext = DataTable.ext;
-			var type = ext.sErrMode || ext.errMode;
-	
-			if ( settings ) {
-				_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
-			}
-	
-			if ( type == 'alert' ) {
-				alert( msg );
-			}
-			else if ( type == 'throw' ) {
-				throw new Error(msg);
-			}
-			else if ( typeof type == 'function' ) {
-				type( settings, tn, msg );
-			}
-		}
-		else if ( window.console && console.log ) {
-			console.log( msg );
-		}
-	}
-	
-	
-	/**
-	 * See if a property is defined on one object, if so assign it to the other object
-	 *  @param {object} ret target object
-	 *  @param {object} src source object
-	 *  @param {string} name property
-	 *  @param {string} [mappedName] name to map too - optional, name used if not given
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnMap( ret, src, name, mappedName )
-	{
-		if ( Array.isArray( name ) ) {
-			$.each( name, function (i, val) {
-				if ( Array.isArray( val ) ) {
-					_fnMap( ret, src, val[0], val[1] );
-				}
-				else {
-					_fnMap( ret, src, val );
-				}
-			} );
-	
-			return;
-		}
-	
-		if ( mappedName === undefined ) {
-			mappedName = name;
-		}
-	
-		if ( src[name] !== undefined ) {
-			ret[mappedName] = src[name];
-		}
-	}
-	
-	
-	/**
-	 * Extend objects - very similar to jQuery.extend, but deep copy objects, and
-	 * shallow copy arrays. The reason we need to do this, is that we don't want to
-	 * deep copy array init values (such as aaSorting) since the dev wouldn't be
-	 * able to override them, but we do want to deep copy arrays.
-	 *  @param {object} out Object to extend
-	 *  @param {object} extender Object from which the properties will be applied to
-	 *      out
-	 *  @param {boolean} breakRefs If true, then arrays will be sliced to take an
-	 *      independent copy with the exception of the `data` or `aaData` parameters
-	 *      if they are present. This is so you can pass in a collection to
-	 *      DataTables and have that used as your data source without breaking the
-	 *      references
-	 *  @returns {object} out Reference, just for convenience - out === the return.
-	 *  @memberof DataTable#oApi
-	 *  @todo This doesn't take account of arrays inside the deep copied objects.
-	 */
-	function _fnExtend( out, extender, breakRefs )
-	{
-		var val;
-	
-		for ( var prop in extender ) {
-			if ( extender.hasOwnProperty(prop) ) {
-				val = extender[prop];
-	
-				if ( $.isPlainObject( val ) ) {
-					if ( ! $.isPlainObject( out[prop] ) ) {
-						out[prop] = {};
-					}
-					$.extend( true, out[prop], val );
-				}
-				else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && Array.isArray(val) ) {
-					out[prop] = val.slice();
-				}
-				else {
-					out[prop] = val;
-				}
-			}
-		}
-	
-		return out;
-	}
-	
-	
-	/**
-	 * Bind an event handers to allow a click or return key to activate the callback.
-	 * This is good for accessibility since a return on the keyboard will have the
-	 * same effect as a click, if the element has focus.
-	 *  @param {element} n Element to bind the action to
-	 *  @param {object} oData Data object to pass to the triggered function
-	 *  @param {function} fn Callback function for when the event is triggered
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnBindAction( n, oData, fn )
-	{
-		$(n)
-			.on( 'click.DT', oData, function (e) {
-					$(n).trigger('blur'); // Remove focus outline for mouse users
-					fn(e);
-				} )
-			.on( 'keypress.DT', oData, function (e){
-					if ( e.which === 13 ) {
-						e.preventDefault();
-						fn(e);
-					}
-				} )
-			.on( 'selectstart.DT', function () {
-					/* Take the brutal approach to cancelling text selection */
-					return false;
-				} );
-	}
-	
-	
-	/**
-	 * Register a callback function. Easily allows a callback function to be added to
-	 * an array store of callback functions that can then all be called together.
-	 *  @param {object} oSettings dataTables settings object
-	 *  @param {string} sStore Name of the array storage for the callbacks in oSettings
-	 *  @param {function} fn Function to be called back
-	 *  @param {string} sName Identifying name for the callback (i.e. a label)
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnCallbackReg( oSettings, sStore, fn, sName )
-	{
-		if ( fn )
-		{
-			oSettings[sStore].push( {
-				"fn": fn,
-				"sName": sName
-			} );
-		}
-	}
-	
-	
-	/**
-	 * Fire callback functions and trigger events. Note that the loop over the
-	 * callback array store is done backwards! Further note that you do not want to
-	 * fire off triggers in time sensitive applications (for example cell creation)
-	 * as its slow.
-	 *  @param {object} settings dataTables settings object
-	 *  @param {string} callbackArr Name of the array storage for the callbacks in
-	 *      oSettings
-	 *  @param {string} eventName Name of the jQuery custom event to trigger. If
-	 *      null no trigger is fired
-	 *  @param {array} args Array of arguments to pass to the callback function /
-	 *      trigger
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnCallbackFire( settings, callbackArr, eventName, args )
-	{
-		var ret = [];
-	
-		if ( callbackArr ) {
-			ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
-				return val.fn.apply( settings.oInstance, args );
-			} );
-		}
-	
-		if ( eventName !== null ) {
-			var e = $.Event( eventName+'.dt' );
-	
-			$(settings.nTable).trigger( e, args );
-	
-			ret.push( e.result );
-		}
-	
-		return ret;
-	}
-	
-	
-	function _fnLengthOverflow ( settings )
-	{
-		var
-			start = settings._iDisplayStart,
-			end = settings.fnDisplayEnd(),
-			len = settings._iDisplayLength;
-	
-		/* If we have space to show extra rows (backing up from the end point - then do so */
-		if ( start >= end )
-		{
-			start = end - len;
-		}
-	
-		// Keep the start record on the current page
-		start -= (start % len);
-	
-		if ( len === -1 || start < 0 )
-		{
-			start = 0;
-		}
-	
-		settings._iDisplayStart = start;
-	}
-	
-	
-	function _fnRenderer( settings, type )
-	{
-		var renderer = settings.renderer;
-		var host = DataTable.ext.renderer[type];
-	
-		if ( $.isPlainObject( renderer ) && renderer[type] ) {
-			// Specific renderer for this type. If available use it, otherwise use
-			// the default.
-			return host[renderer[type]] || host._;
-		}
-		else if ( typeof renderer === 'string' ) {
-			// Common renderer - if there is one available for this type use it,
-			// otherwise use the default
-			return host[renderer] || host._;
-		}
-	
-		// Use the default
-		return host._;
-	}
-	
-	
-	/**
-	 * Detect the data source being used for the table. Used to simplify the code
-	 * a little (ajax) and to make it compress a little smaller.
-	 *
-	 *  @param {object} settings dataTables settings object
-	 *  @returns {string} Data source
-	 *  @memberof DataTable#oApi
-	 */
-	function _fnDataSource ( settings )
-	{
-		if ( settings.oFeatures.bServerSide ) {
-			return 'ssp';
-		}
-		else if ( settings.ajax || settings.sAjaxSource ) {
-			return 'ajax';
-		}
-		return 'dom';
-	}
-	
-
-	
-	
-	/**
-	 * Computed structure of the DataTables API, defined by the options passed to
-	 * `DataTable.Api.register()` when building the API.
-	 *
-	 * The structure is built in order to speed creation and extension of the Api
-	 * objects since the extensions are effectively pre-parsed.
-	 *
-	 * The array is an array of objects with the following structure, where this
-	 * base array represents the Api prototype base:
-	 *
-	 *     [
-	 *       {
-	 *         name:      'data'                -- string   - Property name
-	 *         val:       function () {},       -- function - Api method (or undefined if just an object
-	 *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
-	 *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
-	 *       },
-	 *       {
-	 *         name:     'row'
-	 *         val:       {},
-	 *         methodExt: [ ... ],
-	 *         propExt:   [
-	 *           {
-	 *             name:      'data'
-	 *             val:       function () {},
-	 *             methodExt: [ ... ],
-	 *             propExt:   [ ... ]
-	 *           },
-	 *           ...
-	 *         ]
-	 *       }
-	 *     ]
-	 *
-	 * @type {Array}
-	 * @ignore
-	 */
-	var __apiStruct = [];
-	
-	
-	/**
-	 * `Array.prototype` reference.
-	 *
-	 * @type object
-	 * @ignore
-	 */
-	var __arrayProto = Array.prototype;
-	
-	
-	/**
-	 * Abstraction for `context` parameter of the `Api` constructor to allow it to
-	 * take several different forms for ease of use.
-	 *
-	 * Each of the input parameter types will be converted to a DataTables settings
-	 * object where possible.
-	 *
-	 * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one
-	 *   of:
-	 *
-	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
-	 *     with be found and used.
-	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
-	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
-	 *   * `object` - DataTables settings object
-	 *   * `DataTables.Api` - API instance
-	 * @return {array|null} Matching DataTables settings objects. `null` or
-	 *   `undefined` is returned if no matching DataTable is found.
-	 * @ignore
-	 */
-	var _toSettings = function ( mixed )
-	{
-		var idx, jq;
-		var settings = DataTable.settings;
-		var tables = $.map( settings, function (el, i) {
-			return el.nTable;
-		} );
-	
-		if ( ! mixed ) {
-			return [];
-		}
-		else if ( mixed.nTable && mixed.oApi ) {
-			// DataTables settings object
-			return [ mixed ];
-		}
-		else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
-			// Table node
-			idx = $.inArray( mixed, tables );
-			return idx !== -1 ? [ settings[idx] ] : null;
-		}
-		else if ( mixed && typeof mixed.settings === 'function' ) {
-			return mixed.settings().toArray();
-		}
-		else if ( typeof mixed === 'string' ) {
-			// jQuery selector
-			jq = $(mixed);
-		}
-		else if ( mixed instanceof $ ) {
-			// jQuery object (also DataTables instance)
-			jq = mixed;
-		}
-	
-		if ( jq ) {
-			return jq.map( function(i) {
-				idx = $.inArray( this, tables );
-				return idx !== -1 ? settings[idx] : null;
-			} ).toArray();
-		}
-	};
-	
-	
-	/**
-	 * DataTables API class - used to control and interface with  one or more
-	 * DataTables enhanced tables.
-	 *
-	 * The API class is heavily based on jQuery, presenting a chainable interface
-	 * that you can use to interact with tables. Each instance of the API class has
-	 * a "context" - i.e. the tables that it will operate on. This could be a single
-	 * table, all tables on a page or a sub-set thereof.
-	 *
-	 * Additionally the API is designed to allow you to easily work with the data in
-	 * the tables, retrieving and manipulating it as required. This is done by
-	 * presenting the API class as an array like interface. The contents of the
-	 * array depend upon the actions requested by each method (for example
-	 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
-	 * return an array of objects or arrays depending upon your table's
-	 * configuration). The API object has a number of array like methods (`push`,
-	 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
-	 * `unique` etc) to assist your working with the data held in a table.
-	 *
-	 * Most methods (those which return an Api instance) are chainable, which means
-	 * the return from a method call also has all of the methods available that the
-	 * top level object had. For example, these two calls are equivalent:
-	 *
-	 *     // Not chained
-	 *     api.row.add( {...} );
-	 *     api.draw();
-	 *
-	 *     // Chained
-	 *     api.row.add( {...} ).draw();
-	 *
-	 * @class DataTable.Api
-	 * @param {array|object|string|jQuery} context DataTable identifier. This is
-	 *   used to define which DataTables enhanced tables this API will operate on.
-	 *   Can be one of:
-	 *
-	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
-	 *     with be found and used.
-	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
-	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
-	 *   * `object` - DataTables settings object
-	 * @param {array} [data] Data to initialise the Api instance with.
-	 *
-	 * @example
-	 *   // Direct initialisation during DataTables construction
-	 *   var api = $('#example').DataTable();
-	 *
-	 * @example
-	 *   // Initialisation using a DataTables jQuery object
-	 *   var api = $('#example').dataTable().api();
-	 *
-	 * @example
-	 *   // Initialisation as a constructor
-	 *   var api = new $.fn.DataTable.Api( 'table.dataTable' );
-	 */
-	_Api = function ( context, data )
-	{
-		if ( ! (this instanceof _Api) ) {
-			return new _Api( context, data );
-		}
-	
-		var settings = [];
-		var ctxSettings = function ( o ) {
-			var a = _toSettings( o );
-			if ( a ) {
-				settings.push.apply( settings, a );
-			}
-		};
-	
-		if ( Array.isArray( context ) ) {
-			for ( var i=0, ien=context.length ; i<ien ; i++ ) {
-				ctxSettings( context[i] );
-			}
-		}
-		else {
-			ctxSettings( context );
-		}
-	
-		// Remove duplicates
-		this.context = _unique( settings );
-	
-		// Initial data
-		if ( data ) {
-			$.merge( this, data );
-		}
-	
-		// selector
-		this.selector = {
-			rows: null,
-			cols: null,
-			opts: null
-		};
-	
-		_Api.extend( this, this, __apiStruct );
-	};
-	
-	DataTable.Api = _Api;
-	
-	// Don't destroy the existing prototype, just extend it. Required for jQuery 2's
-	// isPlainObject.
-	$.extend( _Api.prototype, {
-		any: function ()
-		{
-			return this.count() !== 0;
-		},
-	
-	
-		concat:  __arrayProto.concat,
-	
-	
-		context: [], // array of table settings objects
-	
-	
-		count: function ()
-		{
-			return this.flatten().length;
-		},
-	
-	
-		each: function ( fn )
-		{
-			for ( var i=0, ien=this.length ; i<ien; i++ ) {
-				fn.call( this, this[i], i, this );
-			}
-	
-			return this;
-		},
-	
-	
-		eq: function ( idx )
-		{
-			var ctx = this.context;
-	
-			return ctx.length > idx ?
-				new _Api( ctx[idx], this[idx] ) :
-				null;
-		},
-	
-	
-		filter: function ( fn )
-		{
-			var a = [];
-	
-			if ( __arrayProto.filter ) {
-				a = __arrayProto.filter.call( this, fn, this );
-			}
-			else {
-				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
-				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
-					if ( fn.call( this, this[i], i, this ) ) {
-						a.push( this[i] );
-					}
-				}
-			}
-	
-			return new _Api( this.context, a );
-		},
-	
-	
-		flatten: function ()
-		{
-			var a = [];
-			return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
-		},
-	
-	
-		join:    __arrayProto.join,
-	
-	
-		indexOf: __arrayProto.indexOf || function (obj, start)
-		{
-			for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
-				if ( this[i] === obj ) {
-					return i;
-				}
-			}
-			return -1;
-		},
-	
-		iterator: function ( flatten, type, fn, alwaysNew ) {
-			var
-				a = [], ret,
-				i, ien, j, jen,
-				context = this.context,
-				rows, items, item,
-				selector = this.selector;
-	
-			// Argument shifting
-			if ( typeof flatten === 'string' ) {
-				alwaysNew = fn;
-				fn = type;
-				type = flatten;
-				flatten = false;
-			}
-	
-			for ( i=0, ien=context.length ; i<ien ; i++ ) {
-				var apiInst = new _Api( context[i] );
-	
-				if ( type === 'table' ) {
-					ret = fn.call( apiInst, context[i], i );
-	
-					if ( ret !== undefined ) {
-						a.push( ret );
-					}
-				}
-				else if ( type === 'columns' || type === 'rows' ) {
-					// this has same length as context - one entry for each table
-					ret = fn.call( apiInst, context[i], this[i], i );
-	
-					if ( ret !== undefined ) {
-						a.push( ret );
-					}
-				}
-				else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
-					// columns and rows share the same structure.
-					// 'this' is an array of column indexes for each context
-					items = this[i];
-	
-					if ( type === 'column-rows' ) {
-						rows = _selector_row_indexes( context[i], selector.opts );
-					}
-	
-					for ( j=0, jen=items.length ; j<jen ; j++ ) {
-						item = items[j];
-	
-						if ( type === 'cell' ) {
-							ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
-						}
-						else {
-							ret = fn.call( apiInst, context[i], item, i, j, rows );
-						}
-	
-						if ( ret !== undefined ) {
-							a.push( ret );
-						}
-					}
-				}
-			}
-	
-			if ( a.length || alwaysNew ) {
-				var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
-				var apiSelector = api.selector;
-				apiSelector.rows = selector.rows;
-				apiSelector.cols = selector.cols;
-				apiSelector.opts = selector.opts;
-				return api;
-			}
-			return this;
-		},
-	
-	
-		lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
-		{
-			// Bit cheeky...
-			return this.indexOf.apply( this.toArray.reverse(), arguments );
-		},
-	
-	
-		length:  0,
-	
-	
-		map: function ( fn )
-		{
-			var a = [];
-	
-			if ( __arrayProto.map ) {
-				a = __arrayProto.map.call( this, fn, this );
-			}
-			else {
-				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
-				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
-					a.push( fn.call( this, this[i], i ) );
-				}
-			}
-	
-			return new _Api( this.context, a );
-		},
-	
-	
-		pluck: function ( prop )
-		{
-			return this.map( function ( el ) {
-				return el[ prop ];
-			} );
-		},
-	
-		pop:     __arrayProto.pop,
-	
-	
-		push:    __arrayProto.push,
-	
-	
-		// Does not return an API instance
-		reduce: __arrayProto.reduce || function ( fn, init )
-		{
-			return _fnReduce( this, fn, init, 0, this.length, 1 );
-		},
-	
-	
-		reduceRight: __arrayProto.reduceRight || function ( fn, init )
-		{
-			return _fnReduce( this, fn, init, this.length-1, -1, -1 );
-		},
-	
-	
-		reverse: __arrayProto.reverse,
-	
-	
-		// Object with rows, columns and opts
-		selector: null,
-	
-	
-		shift:   __arrayProto.shift,
-	
-	
-		slice: function () {
-			return new _Api( this.context, this );
-		},
-	
-	
-		sort:    __arrayProto.sort, // ? name - order?
-	
-	
-		splice:  __arrayProto.splice,
-	
-	
-		toArray: function ()
-		{
-			return __arrayProto.slice.call( this );
-		},
-	
-	
-		to$: function ()
-		{
-			return $( this );
-		},
-	
-	
-		toJQuery: function ()
-		{
-			return $( this );
-		},
-	
-	
-		unique: function ()
-		{
-			return new _Api( this.context, _unique(this) );
-		},
-	
-	
-		unshift: __arrayProto.unshift
-	} );
-	
-	
-	_Api.extend = function ( scope, obj, ext )
-	{
-		// Only extend API instances and static properties of the API
-		if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
-			return;
-		}
-	
-		var
-			i, ien,
-			struct,
-			methodScoping = function ( scope, fn, struc ) {
-				return function () {
-					var ret = fn.apply( scope, arguments );
-	
-					// Method extension
-					_Api.extend( ret, ret, struc.methodExt );
-					return ret;
-				};
-			};
-	
-		for ( i=0, ien=ext.length ; i<ien ; i++ ) {
-			struct = ext[i];
-	
-			// Value
-			obj[ struct.name ] = struct.type === 'function' ?
-				methodScoping( scope, struct.val, struct ) :
-				struct.type === 'object' ?
-					{} :
-					struct.val;
-	
-			obj[ struct.name ].__dt_wrapper = true;
-	
-			// Property extension
-			_Api.extend( scope, obj[ struct.name ], struct.propExt );
-		}
-	};
-	
-	
-	// @todo - Is there need for an augment function?
-	// _Api.augment = function ( inst, name )
-	// {
-	// 	// Find src object in the structure from the name
-	// 	var parts = name.split('.');
-	
-	// 	_Api.extend( inst, obj );
-	// };
-	
-	
-	//     [
-	//       {
-	//         name:      'data'                -- string   - Property name
-	//         val:       function () {},       -- function - Api method (or undefined if just an object
-	//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
-	//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
-	//       },
-	//       {
-	//         name:     'row'
-	//         val:       {},
-	//         methodExt: [ ... ],
-	//         propExt:   [
-	//           {
-	//             name:      'data'
-	//             val:       function () {},
-	//             methodExt: [ ... ],
-	//             propExt:   [ ... ]
-	//           },
-	//           ...
-	//         ]
-	//       }
-	//     ]
-	
-	_Api.register = _api_register = function ( name, val )
-	{
-		if ( Array.isArray( name ) ) {
-			for ( var j=0, jen=name.length ; j<jen ; j++ ) {
-				_Api.register( name[j], val );
-			}
-			return;
-		}
-	
-		var
-			i, ien,
-			heir = name.split('.'),
-			struct = __apiStruct,
-			key, method;
-	
-		var find = function ( src, name ) {
-			for ( var i=0, ien=src.length ; i<ien ; i++ ) {
-				if ( src[i].name === name ) {
-					return src[i];
-				}
-			}
-			return null;
-		};
-	
-		for ( i=0, ien=heir.length ; i<ien ; i++ ) {
-			method = heir[i].indexOf('()') !== -1;
-			key = method ?
-				heir[i].replace('()', '') :
-				heir[i];
-	
-			var src = find( struct, key );
-			if ( ! src ) {
-				src = {
-					name:      key,
-					val:       {},
-					methodExt: [],
-					propExt:   [],
-					type:      'object'
-				};
-				struct.push( src );
-			}
-	
-			if ( i === ien-1 ) {
-				src.val = val;
-				src.type = typeof val === 'function' ?
-					'function' :
-					$.isPlainObject( val ) ?
-						'object' :
-						'other';
-			}
-			else {
-				struct = method ?
-					src.methodExt :
-					src.propExt;
-			}
-		}
-	};
-	
-	_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
-		_Api.register( pluralName, val );
-	
-		_Api.register( singularName, function () {
-			var ret = val.apply( this, arguments );
-	
-			if ( ret === this ) {
-				// Returned item is the API instance that was passed in, return it
-				return this;
-			}
-			else if ( ret instanceof _Api ) {
-				// New API instance returned, want the value from the first item
-				// in the returned array for the singular result.
-				return ret.length ?
-					Array.isArray( ret[0] ) ?
-						new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
-						ret[0] :
-					undefined;
-			}
-	
-			// Non-API return - just fire it back
-			return ret;
-		} );
-	};
-	
-	
-	/**
-	 * Selector for HTML tables. Apply the given selector to the give array of
-	 * DataTables settings objects.
-	 *
-	 * @param {string|integer} [selector] jQuery selector string or integer
-	 * @param  {array} Array of DataTables settings objects to be filtered
-	 * @return {array}
-	 * @ignore
-	 */
-	var __table_selector = function ( selector, a )
-	{
-		if ( Array.isArray(selector) ) {
-			return $.map( selector, function (item) {
-				return __table_selector(item, a);
-			} );
-		}
-	
-		// Integer is used to pick out a table by index
-		if ( typeof selector === 'number' ) {
-			return [ a[ selector ] ];
-		}
-	
-		// Perform a jQuery selector on the table nodes
-		var nodes = $.map( a, function (el, i) {
-			return el.nTable;
-		} );
-	
-		return $(nodes)
-			.filter( selector )
-			.map( function (i) {
-				// Need to translate back from the table node to the settings
-				var idx = $.inArray( this, nodes );
-				return a[ idx ];
-			} )
-			.toArray();
-	};
-	
-	
-	
-	/**
-	 * Context selector for the API's context (i.e. the tables the API instance
-	 * refers to.
-	 *
-	 * @name    DataTable.Api#tables
-	 * @param {string|integer} [selector] Selector to pick which tables the iterator
-	 *   should operate on. If not given, all tables in the current context are
-	 *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to
-	 *   select multiple tables or as an integer to select a single table.
-	 * @returns {DataTable.Api} Returns a new API instance if a selector is given.
-	 */
-	_api_register( 'tables()', function ( selector ) {
-		// A new instance is created if there was a selector specified
-		return selector !== undefined && selector !== null ?
-			new _Api( __table_selector( selector, this.context ) ) :
-			this;
-	} );
-	
-	
-	_api_register( 'table()', function ( selector ) {
-		var tables = this.tables( selector );
-		var ctx = tables.context;
-	
-		// Truncate to the first matched table
-		return ctx.length ?
-			new _Api( ctx[0] ) :
-			tables;
-	} );
-	
-	
-	_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
-		return this.iterator( 'table', function ( ctx ) {
-			return ctx.nTable;
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'tables().body()', 'table().body()' , function () {
-		return this.iterator( 'table', function ( ctx ) {
-			return ctx.nTBody;
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'tables().header()', 'table().header()' , function () {
-		return this.iterator( 'table', function ( ctx ) {
-			return ctx.nTHead;
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
-		return this.iterator( 'table', function ( ctx ) {
-			return ctx.nTFoot;
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'tables().containers()', 'table().container()' , function () {
-		return this.iterator( 'table', function ( ctx ) {
-			return ctx.nTableWrapper;
-		}, 1 );
-	} );
-	
-	
-	
-	/**
-	 * Redraw the tables in the current context.
-	 */
-	_api_register( 'draw()', function ( paging ) {
-		return this.iterator( 'table', function ( settings ) {
-			if ( paging === 'page' ) {
-				_fnDraw( settings );
-			}
-			else {
-				if ( typeof paging === 'string' ) {
-					paging = paging === 'full-hold' ?
-						false :
-						true;
-				}
-	
-				_fnReDraw( settings, paging===false );
-			}
-		} );
-	} );
-	
-	
-	
-	/**
-	 * Get the current page index.
-	 *
-	 * @return {integer} Current page index (zero based)
-	 *//**
-	 * Set the current page.
-	 *
-	 * Note that if you attempt to show a page which does not exist, DataTables will
-	 * not throw an error, but rather reset the paging.
-	 *
-	 * @param {integer|string} action The paging action to take. This can be one of:
-	 *  * `integer` - The page index to jump to
-	 *  * `string` - An action to take:
-	 *    * `first` - Jump to first page.
-	 *    * `next` - Jump to the next page
-	 *    * `previous` - Jump to previous page
-	 *    * `last` - Jump to the last page.
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'page()', function ( action ) {
-		if ( action === undefined ) {
-			return this.page.info().page; // not an expensive call
-		}
-	
-		// else, have an action to take on all tables
-		return this.iterator( 'table', function ( settings ) {
-			_fnPageChange( settings, action );
-		} );
-	} );
-	
-	
-	/**
-	 * Paging information for the first table in the current context.
-	 *
-	 * If you require paging information for another table, use the `table()` method
-	 * with a suitable selector.
-	 *
-	 * @return {object} Object with the following properties set:
-	 *  * `page` - Current page index (zero based - i.e. the first page is `0`)
-	 *  * `pages` - Total number of pages
-	 *  * `start` - Display index for the first record shown on the current page
-	 *  * `end` - Display index for the last record shown on the current page
-	 *  * `length` - Display length (number of records). Note that generally `start
-	 *    + length = end`, but this is not always true, for example if there are
-	 *    only 2 records to show on the final page, with a length of 10.
-	 *  * `recordsTotal` - Full data set length
-	 *  * `recordsDisplay` - Data set length once the current filtering criterion
-	 *    are applied.
-	 */
-	_api_register( 'page.info()', function ( action ) {
-		if ( this.context.length === 0 ) {
-			return undefined;
-		}
-	
-		var
-			settings   = this.context[0],
-			start      = settings._iDisplayStart,
-			len        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
-			visRecords = settings.fnRecordsDisplay(),
-			all        = len === -1;
-	
-		return {
-			"page":           all ? 0 : Math.floor( start / len ),
-			"pages":          all ? 1 : Math.ceil( visRecords / len ),
-			"start":          start,
-			"end":            settings.fnDisplayEnd(),
-			"length":         len,
-			"recordsTotal":   settings.fnRecordsTotal(),
-			"recordsDisplay": visRecords,
-			"serverSide":     _fnDataSource( settings ) === 'ssp'
-		};
-	} );
-	
-	
-	/**
-	 * Get the current page length.
-	 *
-	 * @return {integer} Current page length. Note `-1` indicates that all records
-	 *   are to be shown.
-	 *//**
-	 * Set the current page length.
-	 *
-	 * @param {integer} Page length to set. Use `-1` to show all records.
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'page.len()', function ( len ) {
-		// Note that we can't call this function 'length()' because `length`
-		// is a Javascript property of functions which defines how many arguments
-		// the function expects.
-		if ( len === undefined ) {
-			return this.context.length !== 0 ?
-				this.context[0]._iDisplayLength :
-				undefined;
-		}
-	
-		// else, set the page length
-		return this.iterator( 'table', function ( settings ) {
-			_fnLengthChange( settings, len );
-		} );
-	} );
-	
-	
-	
-	var __reload = function ( settings, holdPosition, callback ) {
-		// Use the draw event to trigger a callback
-		if ( callback ) {
-			var api = new _Api( settings );
-	
-			api.one( 'draw', function () {
-				callback( api.ajax.json() );
-			} );
-		}
-	
-		if ( _fnDataSource( settings ) == 'ssp' ) {
-			_fnReDraw( settings, holdPosition );
-		}
-		else {
-			_fnProcessingDisplay( settings, true );
-	
-			// Cancel an existing request
-			var xhr = settings.jqXHR;
-			if ( xhr && xhr.readyState !== 4 ) {
-				xhr.abort();
-			}
-	
-			// Trigger xhr
-			_fnBuildAjax( settings, [], function( json ) {
-				_fnClearTable( settings );
-	
-				var data = _fnAjaxDataSrc( settings, json );
-				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
-					_fnAddData( settings, data[i] );
-				}
-	
-				_fnReDraw( settings, holdPosition );
-				_fnProcessingDisplay( settings, false );
-			} );
-		}
-	};
-	
-	
-	/**
-	 * Get the JSON response from the last Ajax request that DataTables made to the
-	 * server. Note that this returns the JSON from the first table in the current
-	 * context.
-	 *
-	 * @return {object} JSON received from the server.
-	 */
-	_api_register( 'ajax.json()', function () {
-		var ctx = this.context;
-	
-		if ( ctx.length > 0 ) {
-			return ctx[0].json;
-		}
-	
-		// else return undefined;
-	} );
-	
-	
-	/**
-	 * Get the data submitted in the last Ajax request
-	 */
-	_api_register( 'ajax.params()', function () {
-		var ctx = this.context;
-	
-		if ( ctx.length > 0 ) {
-			return ctx[0].oAjaxData;
-		}
-	
-		// else return undefined;
-	} );
-	
-	
-	/**
-	 * Reload tables from the Ajax data source. Note that this function will
-	 * automatically re-draw the table when the remote data has been loaded.
-	 *
-	 * @param {boolean} [reset=true] Reset (default) or hold the current paging
-	 *   position. A full re-sort and re-filter is performed when this method is
-	 *   called, which is why the pagination reset is the default action.
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'ajax.reload()', function ( callback, resetPaging ) {
-		return this.iterator( 'table', function (settings) {
-			__reload( settings, resetPaging===false, callback );
-		} );
-	} );
-	
-	
-	/**
-	 * Get the current Ajax URL. Note that this returns the URL from the first
-	 * table in the current context.
-	 *
-	 * @return {string} Current Ajax source URL
-	 *//**
-	 * Set the Ajax URL. Note that this will set the URL for all tables in the
-	 * current context.
-	 *
-	 * @param {string} url URL to set.
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'ajax.url()', function ( url ) {
-		var ctx = this.context;
-	
-		if ( url === undefined ) {
-			// get
-			if ( ctx.length === 0 ) {
-				return undefined;
-			}
-			ctx = ctx[0];
-	
-			return ctx.ajax ?
-				$.isPlainObject( ctx.ajax ) ?
-					ctx.ajax.url :
-					ctx.ajax :
-				ctx.sAjaxSource;
-		}
-	
-		// set
-		return this.iterator( 'table', function ( settings ) {
-			if ( $.isPlainObject( settings.ajax ) ) {
-				settings.ajax.url = url;
-			}
-			else {
-				settings.ajax = url;
-			}
-			// No need to consider sAjaxSource here since DataTables gives priority
-			// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
-			// value of `sAjaxSource` redundant.
-		} );
-	} );
-	
-	
-	/**
-	 * Load data from the newly set Ajax URL. Note that this method is only
-	 * available when `ajax.url()` is used to set a URL. Additionally, this method
-	 * has the same effect as calling `ajax.reload()` but is provided for
-	 * convenience when setting a new URL. Like `ajax.reload()` it will
-	 * automatically redraw the table once the remote data has been loaded.
-	 *
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
-		// Same as a reload, but makes sense to present it for easy access after a
-		// url change
-		return this.iterator( 'table', function ( ctx ) {
-			__reload( ctx, resetPaging===false, callback );
-		} );
-	} );
-	
-	
-	
-	
-	var _selector_run = function ( type, selector, selectFn, settings, opts )
-	{
-		var
-			out = [], res,
-			a, i, ien, j, jen,
-			selectorType = typeof selector;
-	
-		// Can't just check for isArray here, as an API or jQuery instance might be
-		// given with their array like look
-		if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
-			selector = [ selector ];
-		}
-	
-		for ( i=0, ien=selector.length ; i<ien ; i++ ) {
-			// Only split on simple strings - complex expressions will be jQuery selectors
-			a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
-				selector[i].split(',') :
-				[ selector[i] ];
-	
-			for ( j=0, jen=a.length ; j<jen ; j++ ) {
-				res = selectFn( typeof a[j] === 'string' ? (a[j]).trim() : a[j] );
-	
-				if ( res && res.length ) {
-					out = out.concat( res );
-				}
-			}
-		}
-	
-		// selector extensions
-		var ext = _ext.selector[ type ];
-		if ( ext.length ) {
-			for ( i=0, ien=ext.length ; i<ien ; i++ ) {
-				out = ext[i]( settings, opts, out );
-			}
-		}
-	
-		return _unique( out );
-	};
-	
-	
-	var _selector_opts = function ( opts )
-	{
-		if ( ! opts ) {
-			opts = {};
-		}
-	
-		// Backwards compatibility for 1.9- which used the terminology filter rather
-		// than search
-		if ( opts.filter && opts.search === undefined ) {
-			opts.search = opts.filter;
-		}
-	
-		return $.extend( {
-			search: 'none',
-			order: 'current',
-			page: 'all'
-		}, opts );
-	};
-	
-	
-	var _selector_first = function ( inst )
-	{
-		// Reduce the API instance to the first item found
-		for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
-			if ( inst[i].length > 0 ) {
-				// Assign the first element to the first item in the instance
-				// and truncate the instance and context
-				inst[0] = inst[i];
-				inst[0].length = 1;
-				inst.length = 1;
-				inst.context = [ inst.context[i] ];
-	
-				return inst;
-			}
-		}
-	
-		// Not found - return an empty instance
-		inst.length = 0;
-		return inst;
-	};
-	
-	
-	var _selector_row_indexes = function ( settings, opts )
-	{
-		var
-			i, ien, tmp, a=[],
-			displayFiltered = settings.aiDisplay,
-			displayMaster = settings.aiDisplayMaster;
-	
-		var
-			search = opts.search,  // none, applied, removed
-			order  = opts.order,   // applied, current, index (original - compatibility with 1.9)
-			page   = opts.page;    // all, current
-	
-		if ( _fnDataSource( settings ) == 'ssp' ) {
-			// In server-side processing mode, most options are irrelevant since
-			// rows not shown don't exist and the index order is the applied order
-			// Removed is a special case - for consistency just return an empty
-			// array
-			return search === 'removed' ?
-				[] :
-				_range( 0, displayMaster.length );
-		}
-		else if ( page == 'current' ) {
-			// Current page implies that order=current and fitler=applied, since it is
-			// fairly senseless otherwise, regardless of what order and search actually
-			// are
-			for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
-				a.push( displayFiltered[i] );
-			}
-		}
-		else if ( order == 'current' || order == 'applied' ) {
-			if ( search == 'none') {
-				a = displayMaster.slice();
-			}
-			else if ( search == 'applied' ) {
-				a = displayFiltered.slice();
-			}
-			else if ( search == 'removed' ) {
-				// O(n+m) solution by creating a hash map
-				var displayFilteredMap = {};
-	
-				for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
-					displayFilteredMap[displayFiltered[i]] = null;
-				}
-	
-				a = $.map( displayMaster, function (el) {
-					return ! displayFilteredMap.hasOwnProperty(el) ?
-						el :
-						null;
-				} );
-			}
-		}
-		else if ( order == 'index' || order == 'original' ) {
-			for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
-				if ( search == 'none' ) {
-					a.push( i );
-				}
-				else { // applied | removed
-					tmp = $.inArray( i, displayFiltered );
-	
-					if ((tmp === -1 && search == 'removed') ||
-						(tmp >= 0   && search == 'applied') )
-					{
-						a.push( i );
-					}
-				}
-			}
-		}
-	
-		return a;
-	};
-	
-	
-	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-	 * Rows
-	 *
-	 * {}          - no selector - use all available rows
-	 * {integer}   - row aoData index
-	 * {node}      - TR node
-	 * {string}    - jQuery selector to apply to the TR elements
-	 * {array}     - jQuery array of nodes, or simply an array of TR nodes
-	 *
-	 */
-	var __row_selector = function ( settings, selector, opts )
-	{
-		var rows;
-		var run = function ( sel ) {
-			var selInt = _intVal( sel );
-			var i, ien;
-			var aoData = settings.aoData;
-	
-			// Short cut - selector is a number and no options provided (default is
-			// all records, so no need to check if the index is in there, since it
-			// must be - dev error if the index doesn't exist).
-			if ( selInt !== null && ! opts ) {
-				return [ selInt ];
-			}
-	
-			if ( ! rows ) {
-				rows = _selector_row_indexes( settings, opts );
-			}
-	
-			if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
-				// Selector - integer
-				return [ selInt ];
-			}
-			else if ( sel === null || sel === undefined || sel === '' ) {
-				// Selector - none
-				return rows;
-			}
-	
-			// Selector - function
-			if ( typeof sel === 'function' ) {
-				return $.map( rows, function (idx) {
-					var row = aoData[ idx ];
-					return sel( idx, row._aData, row.nTr ) ? idx : null;
-				} );
-			}
-	
-			// Selector - node
-			if ( sel.nodeName ) {
-				var rowIdx = sel._DT_RowIndex;  // Property added by DT for fast lookup
-				var cellIdx = sel._DT_CellIndex;
-	
-				if ( rowIdx !== undefined ) {
-					// Make sure that the row is actually still present in the table
-					return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?
-						[ rowIdx ] :
-						[];
-				}
-				else if ( cellIdx ) {
-					return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ?
-						[ cellIdx.row ] :
-						[];
-				}
-				else {
-					var host = $(sel).closest('*[data-dt-row]');
-					return host.length ?
-						[ host.data('dt-row') ] :
-						[];
-				}
-			}
-	
-			// ID selector. Want to always be able to select rows by id, regardless
-			// of if the tr element has been created or not, so can't rely upon
-			// jQuery here - hence a custom implementation. This does not match
-			// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
-			// but to select it using a CSS selector engine (like Sizzle or
-			// querySelect) it would need to need to be escaped for some characters.
-			// DataTables simplifies this for row selectors since you can select
-			// only a row. A # indicates an id any anything that follows is the id -
-			// unescaped.
-			if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
-				// get row index from id
-				var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
-				if ( rowObj !== undefined ) {
-					return [ rowObj.idx ];
-				}
-	
-				// need to fall through to jQuery in case there is DOM id that
-				// matches
-			}
-			
-			// Get nodes in the order from the `rows` array with null values removed
-			var nodes = _removeEmpty(
-				_pluck_order( settings.aoData, rows, 'nTr' )
-			);
-	
-			// Selector - jQuery selector string, array of nodes or jQuery object/
-			// As jQuery's .filter() allows jQuery objects to be passed in filter,
-			// it also allows arrays, so this will cope with all three options
-			return $(nodes)
-				.filter( sel )
-				.map( function () {
-					return this._DT_RowIndex;
-				} )
-				.toArray();
-		};
-	
-		return _selector_run( 'row', selector, run, settings, opts );
-	};
-	
-	
-	_api_register( 'rows()', function ( selector, opts ) {
-		// argument shifting
-		if ( selector === undefined ) {
-			selector = '';
-		}
-		else if ( $.isPlainObject( selector ) ) {
-			opts = selector;
-			selector = '';
-		}
-	
-		opts = _selector_opts( opts );
-	
-		var inst = this.iterator( 'table', function ( settings ) {
-			return __row_selector( settings, selector, opts );
-		}, 1 );
-	
-		// Want argument shifting here and in __row_selector?
-		inst.selector.rows = selector;
-		inst.selector.opts = opts;
-	
-		return inst;
-	} );
-	
-	_api_register( 'rows().nodes()', function () {
-		return this.iterator( 'row', function ( settings, row ) {
-			return settings.aoData[ row ].nTr || undefined;
-		}, 1 );
-	} );
-	
-	_api_register( 'rows().data()', function () {
-		return this.iterator( true, 'rows', function ( settings, rows ) {
-			return _pluck_order( settings.aoData, rows, '_aData' );
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
-		return this.iterator( 'row', function ( settings, row ) {
-			var r = settings.aoData[ row ];
-			return type === 'search' ? r._aFilterData : r._aSortData;
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
-		return this.iterator( 'row', function ( settings, row ) {
-			_fnInvalidate( settings, row, src );
-		} );
-	} );
-	
-	_api_registerPlural( 'rows().indexes()', 'row().index()', function () {
-		return this.iterator( 'row', function ( settings, row ) {
-			return row;
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
-		var a = [];
-		var context = this.context;
-	
-		// `iterator` will drop undefined values, but in this case we want them
-		for ( var i=0, ien=context.length ; i<ien ; i++ ) {
-			for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
-				var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
-				a.push( (hash === true ? '#' : '' )+ id );
-			}
-		}
-	
-		return new _Api( context, a );
-	} );
-	
-	_api_registerPlural( 'rows().remove()', 'row().remove()', function () {
-		var that = this;
-	
-		this.iterator( 'row', function ( settings, row, thatIdx ) {
-			var data = settings.aoData;
-			var rowData = data[ row ];
-			var i, ien, j, jen;
-			var loopRow, loopCells;
-	
-			data.splice( row, 1 );
-	
-			// Update the cached indexes
-			for ( i=0, ien=data.length ; i<ien ; i++ ) {
-				loopRow = data[i];
-				loopCells = loopRow.anCells;
-	
-				// Rows
-				if ( loopRow.nTr !== null ) {
-					loopRow.nTr._DT_RowIndex = i;
-				}
-	
-				// Cells
-				if ( loopCells !== null ) {
-					for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
-						loopCells[j]._DT_CellIndex.row = i;
-					}
-				}
-			}
-	
-			// Delete from the display arrays
-			_fnDeleteIndex( settings.aiDisplayMaster, row );
-			_fnDeleteIndex( settings.aiDisplay, row );
-			_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
-	
-			// For server-side processing tables - subtract the deleted row from the count
-			if ( settings._iRecordsDisplay > 0 ) {
-				settings._iRecordsDisplay--;
-			}
-	
-			// Check for an 'overflow' they case for displaying the table
-			_fnLengthOverflow( settings );
-	
-			// Remove the row's ID reference if there is one
-			var id = settings.rowIdFn( rowData._aData );
-			if ( id !== undefined ) {
-				delete settings.aIds[ id ];
-			}
-		} );
-	
-		this.iterator( 'table', function ( settings ) {
-			for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
-				settings.aoData[i].idx = i;
-			}
-		} );
-	
-		return this;
-	} );
-	
-	
-	_api_register( 'rows.add()', function ( rows ) {
-		var newRows = this.iterator( 'table', function ( settings ) {
-				var row, i, ien;
-				var out = [];
-	
-				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
-					row = rows[i];
-	
-					if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
-						out.push( _fnAddTr( settings, row )[0] );
-					}
-					else {
-						out.push( _fnAddData( settings, row ) );
-					}
-				}
-	
-				return out;
-			}, 1 );
-	
-		// Return an Api.rows() extended instance, so rows().nodes() etc can be used
-		var modRows = this.rows( -1 );
-		modRows.pop();
-		$.merge( modRows, newRows );
-	
-		return modRows;
-	} );
-	
-	
-	
-	
-	
-	/**
-	 *
-	 */
-	_api_register( 'row()', function ( selector, opts ) {
-		return _selector_first( this.rows( selector, opts ) );
-	} );
-	
-	
-	_api_register( 'row().data()', function ( data ) {
-		var ctx = this.context;
-	
-		if ( data === undefined ) {
-			// Get
-			return ctx.length && this.length ?
-				ctx[0].aoData[ this[0] ]._aData :
-				undefined;
-		}
-	
-		// Set
-		var row = ctx[0].aoData[ this[0] ];
-		row._aData = data;
-	
-		// If the DOM has an id, and the data source is an array
-		if ( Array.isArray( data ) && row.nTr && row.nTr.id ) {
-			_fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id );
-		}
-	
-		// Automatically invalidate
-		_fnInvalidate( ctx[0], this[0], 'data' );
-	
-		return this;
-	} );
-	
-	
-	_api_register( 'row().node()', function () {
-		var ctx = this.context;
-	
-		return ctx.length && this.length ?
-			ctx[0].aoData[ this[0] ].nTr || null :
-			null;
-	} );
-	
-	
-	_api_register( 'row.add()', function ( row ) {
-		// Allow a jQuery object to be passed in - only a single row is added from
-		// it though - the first element in the set
-		if ( row instanceof $ && row.length ) {
-			row = row[0];
-		}
-	
-		var rows = this.iterator( 'table', function ( settings ) {
-			if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
-				return _fnAddTr( settings, row )[0];
-			}
-			return _fnAddData( settings, row );
-		} );
-	
-		// Return an Api.rows() extended instance, with the newly added row selected
-		return this.row( rows[0] );
-	} );
-	
-	
-	
-	var __details_add = function ( ctx, row, data, klass )
-	{
-		// Convert to array of TR elements
-		var rows = [];
-		var addRow = function ( r, k ) {
-			// Recursion to allow for arrays of jQuery objects
-			if ( Array.isArray( r ) || r instanceof $ ) {
-				for ( var i=0, ien=r.length ; i<ien ; i++ ) {
-					addRow( r[i], k );
-				}
-				return;
-			}
-	
-			// If we get a TR element, then just add it directly - up to the dev
-			// to add the correct number of columns etc
-			if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
-				rows.push( r );
-			}
-			else {
-				// Otherwise create a row with a wrapper
-				var created = $('<tr><td></td></tr>').addClass( k );
-				$('td', created)
-					.addClass( k )
-					.html( r )
-					[0].colSpan = _fnVisbleColumns( ctx );
-	
-				rows.push( created[0] );
-			}
-		};
-	
-		addRow( data, klass );
-	
-		if ( row._details ) {
-			row._details.detach();
-		}
-	
-		row._details = $(rows);
-	
-		// If the children were already shown, that state should be retained
-		if ( row._detailsShow ) {
-			row._details.insertAfter( row.nTr );
-		}
-	};
-	
-	
-	var __details_remove = function ( api, idx )
-	{
-		var ctx = api.context;
-	
-		if ( ctx.length ) {
-			var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
-	
-			if ( row && row._details ) {
-				row._details.remove();
-	
-				row._detailsShow = undefined;
-				row._details = undefined;
-			}
-		}
-	};
-	
-	
-	var __details_display = function ( api, show ) {
-		var ctx = api.context;
-	
-		if ( ctx.length && api.length ) {
-			var row = ctx[0].aoData[ api[0] ];
-	
-			if ( row._details ) {
-				row._detailsShow = show;
-	
-				if ( show ) {
-					row._details.insertAfter( row.nTr );
-				}
-				else {
-					row._details.detach();
-				}
-	
-				__details_events( ctx[0] );
-			}
-		}
-	};
-	
-	
-	var __details_events = function ( settings )
-	{
-		var api = new _Api( settings );
-		var namespace = '.dt.DT_details';
-		var drawEvent = 'draw'+namespace;
-		var colvisEvent = 'column-visibility'+namespace;
-		var destroyEvent = 'destroy'+namespace;
-		var data = settings.aoData;
-	
-		api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
-	
-		if ( _pluck( data, '_details' ).length > 0 ) {
-			// On each draw, insert the required elements into the document
-			api.on( drawEvent, function ( e, ctx ) {
-				if ( settings !== ctx ) {
-					return;
-				}
-	
-				api.rows( {page:'current'} ).eq(0).each( function (idx) {
-					// Internal data grab
-					var row = data[ idx ];
-	
-					if ( row._detailsShow ) {
-						row._details.insertAfter( row.nTr );
-					}
-				} );
-			} );
-	
-			// Column visibility change - update the colspan
-			api.on( colvisEvent, function ( e, ctx, idx, vis ) {
-				if ( settings !== ctx ) {
-					return;
-				}
-	
-				// Update the colspan for the details rows (note, only if it already has
-				// a colspan)
-				var row, visible = _fnVisbleColumns( ctx );
-	
-				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
-					row = data[i];
-	
-					if ( row._details ) {
-						row._details.children('td[colspan]').attr('colspan', visible );
-					}
-				}
-			} );
-	
-			// Table destroyed - nuke any child rows
-			api.on( destroyEvent, function ( e, ctx ) {
-				if ( settings !== ctx ) {
-					return;
-				}
-	
-				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
-					if ( data[i]._details ) {
-						__details_remove( api, i );
-					}
-				}
-			} );
-		}
-	};
-	
-	// Strings for the method names to help minification
-	var _emp = '';
-	var _child_obj = _emp+'row().child';
-	var _child_mth = _child_obj+'()';
-	
-	// data can be:
-	//  tr
-	//  string
-	//  jQuery or array of any of the above
-	_api_register( _child_mth, function ( data, klass ) {
-		var ctx = this.context;
-	
-		if ( data === undefined ) {
-			// get
-			return ctx.length && this.length ?
-				ctx[0].aoData[ this[0] ]._details :
-				undefined;
-		}
-		else if ( data === true ) {
-			// show
-			this.child.show();
-		}
-		else if ( data === false ) {
-			// remove
-			__details_remove( this );
-		}
-		else if ( ctx.length && this.length ) {
-			// set
-			__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
-		}
-	
-		return this;
-	} );
-	
-	
-	_api_register( [
-		_child_obj+'.show()',
-		_child_mth+'.show()' // only when `child()` was called with parameters (without
-	], function ( show ) {   // it returns an object and this method is not executed)
-		__details_display( this, true );
-		return this;
-	} );
-	
-	
-	_api_register( [
-		_child_obj+'.hide()',
-		_child_mth+'.hide()' // only when `child()` was called with parameters (without
-	], function () {         // it returns an object and this method is not executed)
-		__details_display( this, false );
-		return this;
-	} );
-	
-	
-	_api_register( [
-		_child_obj+'.remove()',
-		_child_mth+'.remove()' // only when `child()` was called with parameters (without
-	], function () {           // it returns an object and this method is not executed)
-		__details_remove( this );
-		return this;
-	} );
-	
-	
-	_api_register( _child_obj+'.isShown()', function () {
-		var ctx = this.context;
-	
-		if ( ctx.length && this.length ) {
-			// _detailsShown as false or undefined will fall through to return false
-			return ctx[0].aoData[ this[0] ]._detailsShow || false;
-		}
-		return false;
-	} );
-	
-	
-	
-	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-	 * Columns
-	 *
-	 * {integer}           - column index (>=0 count from left, <0 count from right)
-	 * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
-	 * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
-	 * "{string}:name"     - column name
-	 * "{string}"          - jQuery selector on column header nodes
-	 *
-	 */
-	
-	// can be an array of these items, comma separated list, or an array of comma
-	// separated lists
-	
-	var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
-	
-	
-	// r1 and r2 are redundant - but it means that the parameters match for the
-	// iterator callback in columns().data()
-	var __columnData = function ( settings, column, r1, r2, rows ) {
-		var a = [];
-		for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
-			a.push( _fnGetCellData( settings, rows[row], column ) );
-		}
-		return a;
-	};
-	
-	
-	var __column_selector = function ( settings, selector, opts )
-	{
-		var
-			columns = settings.aoColumns,
-			names = _pluck( columns, 'sName' ),
-			nodes = _pluck( columns, 'nTh' );
-	
-		var run = function ( s ) {
-			var selInt = _intVal( s );
-	
-			// Selector - all
-			if ( s === '' ) {
-				return _range( columns.length );
-			}
-	
-			// Selector - index
-			if ( selInt !== null ) {
-				return [ selInt >= 0 ?
-					selInt : // Count from left
-					columns.length + selInt // Count from right (+ because its a negative value)
-				];
-			}
-	
-			// Selector = function
-			if ( typeof s === 'function' ) {
-				var rows = _selector_row_indexes( settings, opts );
-	
-				return $.map( columns, function (col, idx) {
-					return s(
-							idx,
-							__columnData( settings, idx, 0, 0, rows ),
-							nodes[ idx ]
-						) ? idx : null;
-				} );
-			}
-	
-			// jQuery or string selector
-			var match = typeof s === 'string' ?
-				s.match( __re_column_selector ) :
-				'';
-	
-			if ( match ) {
-				switch( match[2] ) {
-					case 'visIdx':
-					case 'visible':
-						var idx = parseInt( match[1], 10 );
-						// Visible index given, convert to column index
-						if ( idx < 0 ) {
-							// Counting from the right
-							var visColumns = $.map( columns, function (col,i) {
-								return col.bVisible ? i : null;
-							} );
-							return [ visColumns[ visColumns.length + idx ] ];
-						}
-						// Counting from the left
-						return [ _fnVisibleToColumnIndex( settings, idx ) ];
-	
-					case 'name':
-						// match by name. `names` is column index complete and in order
-						return $.map( names, function (name, i) {
-							return name === match[1] ? i : null;
-						} );
-	
-					default:
-						return [];
-				}
-			}
-	
-			// Cell in the table body
-			if ( s.nodeName && s._DT_CellIndex ) {
-				return [ s._DT_CellIndex.column ];
-			}
-	
-			// jQuery selector on the TH elements for the columns
-			var jqResult = $( nodes )
-				.filter( s )
-				.map( function () {
-					return $.inArray( this, nodes ); // `nodes` is column index complete and in order
-				} )
-				.toArray();
-	
-			if ( jqResult.length || ! s.nodeName ) {
-				return jqResult;
-			}
-	
-			// Otherwise a node which might have a `dt-column` data attribute, or be
-			// a child or such an element
-			var host = $(s).closest('*[data-dt-column]');
-			return host.length ?
-				[ host.data('dt-column') ] :
-				[];
-		};
-	
-		return _selector_run( 'column', selector, run, settings, opts );
-	};
-	
-	
-	var __setColumnVis = function ( settings, column, vis ) {
-		var
-			cols = settings.aoColumns,
-			col  = cols[ column ],
-			data = settings.aoData,
-			row, cells, i, ien, tr;
-	
-		// Get
-		if ( vis === undefined ) {
-			return col.bVisible;
-		}
-	
-		// Set
-		// No change
-		if ( col.bVisible === vis ) {
-			return;
-		}
-	
-		if ( vis ) {
-			// Insert column
-			// Need to decide if we should use appendChild or insertBefore
-			var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
-	
-			for ( i=0, ien=data.length ; i<ien ; i++ ) {
-				tr = data[i].nTr;
-				cells = data[i].anCells;
-	
-				if ( tr ) {
-					// insertBefore can act like appendChild if 2nd arg is null
-					tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
-				}
-			}
-		}
-		else {
-			// Remove column
-			$( _pluck( settings.aoData, 'anCells', column ) ).detach();
-		}
-	
-		// Common actions
-		col.bVisible = vis;
-	};
-	
-	
-	_api_register( 'columns()', function ( selector, opts ) {
-		// argument shifting
-		if ( selector === undefined ) {
-			selector = '';
-		}
-		else if ( $.isPlainObject( selector ) ) {
-			opts = selector;
-			selector = '';
-		}
-	
-		opts = _selector_opts( opts );
-	
-		var inst = this.iterator( 'table', function ( settings ) {
-			return __column_selector( settings, selector, opts );
-		}, 1 );
-	
-		// Want argument shifting here and in _row_selector?
-		inst.selector.cols = selector;
-		inst.selector.opts = opts;
-	
-		return inst;
-	} );
-	
-	_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
-		return this.iterator( 'column', function ( settings, column ) {
-			return settings.aoColumns[column].nTh;
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
-		return this.iterator( 'column', function ( settings, column ) {
-			return settings.aoColumns[column].nTf;
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'columns().data()', 'column().data()', function () {
-		return this.iterator( 'column-rows', __columnData, 1 );
-	} );
-	
-	_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
-		return this.iterator( 'column', function ( settings, column ) {
-			return settings.aoColumns[column].mData;
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
-		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
-			return _pluck_order( settings.aoData, rows,
-				type === 'search' ? '_aFilterData' : '_aSortData', column
-			);
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
-		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
-			return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
-		}, 1 );
-	} );
-	
-	_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
-		var that = this;
-		var ret = this.iterator( 'column', function ( settings, column ) {
-			if ( vis === undefined ) {
-				return settings.aoColumns[ column ].bVisible;
-			} // else
-			__setColumnVis( settings, column, vis );
-		} );
-	
-		// Group the column visibility changes
-		if ( vis !== undefined ) {
-			this.iterator( 'table', function ( settings ) {
-				// Redraw the header after changes
-				_fnDrawHead( settings, settings.aoHeader );
-				_fnDrawHead( settings, settings.aoFooter );
-		
-				// Update colspan for no records display. Child rows and extensions will use their own
-				// listeners to do this - only need to update the empty table item here
-				if ( ! settings.aiDisplay.length ) {
-					$(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
-				}
-		
-				_fnSaveState( settings );
-	
-				// Second loop once the first is done for events
-				that.iterator( 'column', function ( settings, column ) {
-					_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
-				} );
-	
-				if ( calc === undefined || calc ) {
-					that.columns.adjust();
-				}
-			});
-		}
-	
-		return ret;
-	} );
-	
-	_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
-		return this.iterator( 'column', function ( settings, column ) {
-			return type === 'visible' ?
-				_fnColumnIndexToVisible( settings, column ) :
-				column;
-		}, 1 );
-	} );
-	
-	_api_register( 'columns.adjust()', function () {
-		return this.iterator( 'table', function ( settings ) {
-			_fnAdjustColumnSizing( settings );
-		}, 1 );
-	} );
-	
-	_api_register( 'column.index()', function ( type, idx ) {
-		if ( this.context.length !== 0 ) {
-			var ctx = this.context[0];
-	
-			if ( type === 'fromVisible' || type === 'toData' ) {
-				return _fnVisibleToColumnIndex( ctx, idx );
-			}
-			else if ( type === 'fromData' || type === 'toVisible' ) {
-				return _fnColumnIndexToVisible( ctx, idx );
-			}
-		}
-	} );
-	
-	_api_register( 'column()', function ( selector, opts ) {
-		return _selector_first( this.columns( selector, opts ) );
-	} );
-	
-	var __cell_selector = function ( settings, selector, opts )
-	{
-		var data = settings.aoData;
-		var rows = _selector_row_indexes( settings, opts );
-		var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
-		var allCells = $(_flatten( [], cells ));
-		var row;
-		var columns = settings.aoColumns.length;
-		var a, i, ien, j, o, host;
-	
-		var run = function ( s ) {
-			var fnSelector = typeof s === 'function';
-	
-			if ( s === null || s === undefined || fnSelector ) {
-				// All cells and function selectors
-				a = [];
-	
-				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
-					row = rows[i];
-	
-					for ( j=0 ; j<columns ; j++ ) {
-						o = {
-							row: row,
-							column: j
-						};
-	
-						if ( fnSelector ) {
-							// Selector - function
-							host = data[ row ];
-	
-							if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
-								a.push( o );
-							}
-						}
-						else {
-							// Selector - all
-							a.push( o );
-						}
-					}
-				}
-	
-				return a;
-			}
-			
-			// Selector - index
-			if ( $.isPlainObject( s ) ) {
-				// Valid cell index and its in the array of selectable rows
-				return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ?
-					[s] :
-					[];
-			}
-	
-			// Selector - jQuery filtered cells
-			var jqResult = allCells
-				.filter( s )
-				.map( function (i, el) {
-					return { // use a new object, in case someone changes the values
-						row:    el._DT_CellIndex.row,
-						column: el._DT_CellIndex.column
-	 				};
-				} )
-				.toArray();
-	
-			if ( jqResult.length || ! s.nodeName ) {
-				return jqResult;
-			}
-	
-			// Otherwise the selector is a node, and there is one last option - the
-			// element might be a child of an element which has dt-row and dt-column
-			// data attributes
-			host = $(s).closest('*[data-dt-row]');
-			return host.length ?
-				[ {
-					row: host.data('dt-row'),
-					column: host.data('dt-column')
-				} ] :
-				[];
-		};
-	
-		return _selector_run( 'cell', selector, run, settings, opts );
-	};
-	
-	
-	
-	
-	_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
-		// Argument shifting
-		if ( $.isPlainObject( rowSelector ) ) {
-			// Indexes
-			if ( rowSelector.row === undefined ) {
-				// Selector options in first parameter
-				opts = rowSelector;
-				rowSelector = null;
-			}
-			else {
-				// Cell index objects in first parameter
-				opts = columnSelector;
-				columnSelector = null;
-			}
-		}
-		if ( $.isPlainObject( columnSelector ) ) {
-			opts = columnSelector;
-			columnSelector = null;
-		}
-	
-		// Cell selector
-		if ( columnSelector === null || columnSelector === undefined ) {
-			return this.iterator( 'table', function ( settings ) {
-				return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
-			} );
-		}
-	
-		// The default built in options need to apply to row and columns
-		var internalOpts = opts ? {
-			page: opts.page,
-			order: opts.order,
-			search: opts.search
-		} : {};
-	
-		// Row + column selector
-		var columns = this.columns( columnSelector, internalOpts );
-		var rows = this.rows( rowSelector, internalOpts );
-		var i, ien, j, jen;
-	
-		var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) {
-			var a = [];
-	
-			for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
-				for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
-					a.push( {
-						row:    rows[idx][i],
-						column: columns[idx][j]
-					} );
-				}
-			}
-	
-			return a;
-		}, 1 );
-	
-		// There is currently only one extension which uses a cell selector extension
-		// It is a _major_ performance drag to run this if it isn't needed, so this is
-		// an extension specific check at the moment
-		var cells = opts && opts.selected ?
-			this.cells( cellsNoOpts, opts ) :
-			cellsNoOpts;
-	
-		$.extend( cells.selector, {
-			cols: columnSelector,
-			rows: rowSelector,
-			opts: opts
-		} );
-	
-		return cells;
-	} );
-	
-	
-	_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
-		return this.iterator( 'cell', function ( settings, row, column ) {
-			var data = settings.aoData[ row ];
-	
-			return data && data.anCells ?
-				data.anCells[ column ] :
-				undefined;
-		}, 1 );
-	} );
-	
-	
-	_api_register( 'cells().data()', function () {
-		return this.iterator( 'cell', function ( settings, row, column ) {
-			return _fnGetCellData( settings, row, column );
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
-		type = type === 'search' ? '_aFilterData' : '_aSortData';
-	
-		return this.iterator( 'cell', function ( settings, row, column ) {
-			return settings.aoData[ row ][ type ][ column ];
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
-		return this.iterator( 'cell', function ( settings, row, column ) {
-			return _fnGetCellData( settings, row, column, type );
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
-		return this.iterator( 'cell', function ( settings, row, column ) {
-			return {
-				row: row,
-				column: column,
-				columnVisible: _fnColumnIndexToVisible( settings, column )
-			};
-		}, 1 );
-	} );
-	
-	
-	_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
-		return this.iterator( 'cell', function ( settings, row, column ) {
-			_fnInvalidate( settings, row, src, column );
-		} );
-	} );
-	
-	
-	
-	_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
-		return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
-	} );
-	
-	
-	_api_register( 'cell().data()', function ( data ) {
-		var ctx = this.context;
-		var cell = this[0];
-	
-		if ( data === undefined ) {
-			// Get
-			return ctx.length && cell.length ?
-				_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
-				undefined;
-		}
-	
-		// Set
-		_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
-		_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
-	
-		return this;
-	} );
-	
-	
-	
-	/**
-	 * Get current ordering (sorting) that has been applied to the table.
-	 *
-	 * @returns {array} 2D array containing the sorting information for the first
-	 *   table in the current context. Each element in the parent array represents
-	 *   a column being sorted upon (i.e. multi-sorting with two columns would have
-	 *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
-	 *   the column index that the sorting condition applies to, the second is the
-	 *   direction of the sort (`desc` or `asc`) and, optionally, the third is the
-	 *   index of the sorting order from the `column.sorting` initialisation array.
-	 *//**
-	 * Set the ordering for the table.
-	 *
-	 * @param {integer} order Column index to sort upon.
-	 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
-	 * @returns {DataTables.Api} this
-	 *//**
-	 * Set the ordering for the table.
-	 *
-	 * @param {array} order 1D array of sorting information to be applied.
-	 * @param {array} [...] Optional additional sorting conditions
-	 * @returns {DataTables.Api} this
-	 *//**
-	 * Set the ordering for the table.
-	 *
-	 * @param {array} order 2D array of sorting information to be applied.
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'order()', function ( order, dir ) {
-		var ctx = this.context;
-	
-		if ( order === undefined ) {
-			// get
-			return ctx.length !== 0 ?
-				ctx[0].aaSorting :
-				undefined;
-		}
-	
-		// set
-		if ( typeof order === 'number' ) {
-			// Simple column / direction passed in
-			order = [ [ order, dir ] ];
-		}
-		else if ( order.length && ! Array.isArray( order[0] ) ) {
-			// Arguments passed in (list of 1D arrays)
-			order = Array.prototype.slice.call( arguments );
-		}
-		// otherwise a 2D array was passed in
-	
-		return this.iterator( 'table', function ( settings ) {
-			settings.aaSorting = order.slice();
-		} );
-	} );
-	
-	
-	/**
-	 * Attach a sort listener to an element for a given column
-	 *
-	 * @param {node|jQuery|string} node Identifier for the element(s) to attach the
-	 *   listener to. This can take the form of a single DOM node, a jQuery
-	 *   collection of nodes or a jQuery selector which will identify the node(s).
-	 * @param {integer} column the column that a click on this node will sort on
-	 * @param {function} [callback] callback function when sort is run
-	 * @returns {DataTables.Api} this
-	 */
-	_api_register( 'order.listener()', function ( node, column, callback ) {
-		return this.iterator( 'table', function ( settings ) {
-			_fnSortAttachListener( settings, node, column, callback );
-		} );
-	} );
-	
-	
-	_api_register( 'order.fixed()', function ( set ) {
-		if ( ! set ) {
-			var ctx = this.context;
-			var fixed = ctx.length ?
-				ctx[0].aaSortingFixed :
-				undefined;
-	
-			return Array.isArray( fixed ) ?
-				{ pre: fixed } :
-				fixed;
-		}
-	
-		return this.iterator( 'table', function ( settings ) {
-			settings.aaSortingFixed = $.extend( true, {}, set );
-		} );
-	} );
-	
-	
-	// Order by the selected column(s)
-	_api_register( [
-		'columns().order()',
-		'column().order()'
-	], function ( dir ) {
-		var that = this;
-	
-		return this.iterator( 'table', function ( settings, i ) {
-			var sort = [];
-	
-			$.each( that[i], function (j, col) {
-				sort.push( [ col, dir ] );
-			} );
-	
-			settings.aaSorting = sort;
-		} );
-	} );
-	
-	
-	
-	_api_register( 'search()', function ( input, regex, smart, caseInsen ) {
-		var ctx = this.context;
-	
-		if ( input === undefined ) {
-			// get
-			return ctx.length !== 0 ?
-				ctx[0].oPreviousSearch.sSearch :
-				undefined;
-		}
-	
-		// set
-		return this.iterator( 'table', function ( settings ) {
-			if ( ! settings.oFeatures.bFilter ) {
-				return;
-			}
-	
-			_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
-				"sSearch": input+"",
-				"bRegex":  regex === null ? false : regex,
-				"bSmart":  smart === null ? true  : smart,
-				"bCaseInsensitive": caseInsen === null ? true : caseInsen
-			} ), 1 );
-		} );
-	} );
-	
-	
-	_api_registerPlural(
-		'columns().search()',
-		'column().search()',
-		function ( input, regex, smart, caseInsen ) {
-			return this.iterator( 'column', function ( settings, column ) {
-				var preSearch = settings.aoPreSearchCols;
-	
-				if ( input === undefined ) {
-					// get
-					return preSearch[ column ].sSearch;
-				}
-	
-				// set
-				if ( ! settings.oFeatures.bFilter ) {
-					return;
-				}
-	
-				$.extend( preSearch[ column ], {
-					"sSearch": input+"",
-					"bRegex":  regex === null ? false : regex,
-					"bSmart":  smart === null ? true  : smart,
-					"bCaseInsensitive": caseInsen === null ? true : caseInsen
-				} );
-	
-				_fnFilterComplete( settings, settings.oPreviousSearch, 1 );
-			} );
-		}
-	);
-	
-	/*
-	 * State API methods
-	 */
-	
-	_api_register( 'state()', function () {
-		return this.context.length ?
-			this.context[0].oSavedState :
-			null;
-	} );
-	
-	
-	_api_register( 'state.clear()', function () {
-		return this.iterator( 'table', function ( settings ) {
-			// Save an empty object
-			settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
-		} );
-	} );
-	
-	
-	_api_register( 'state.loaded()', function () {
-		return this.context.length ?
-			this.context[0].oLoadedState :
-			null;
-	} );
-	
-	
-	_api_register( 'state.save()', function () {
-		return this.iterator( 'table', function ( settings ) {
-			_fnSaveState( settings );
-		} );
-	} );
-	
-	
-	
-	/**
-	 * Provide a common method for plug-ins to check the version of DataTables being
-	 * used, in order to ensure compatibility.
-	 *
-	 *  @param {string} version Version string to check for, in the format "X.Y.Z".
-	 *    Note that the formats "X" and "X.Y" are also acceptable.
-	 *  @returns {boolean} true if this version of DataTables is greater or equal to
-	 *    the required version, or false if this version of DataTales is not
-	 *    suitable
-	 *  @static
-	 *  @dtopt API-Static
-	 *
-	 *  @example
-	 *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
-	 */
-	DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
-	{
-		var aThis = DataTable.version.split('.');
-		var aThat = version.split('.');
-		var iThis, iThat;
-	
-		for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
-			iThis = parseInt( aThis[i], 10 ) || 0;
-			iThat = parseInt( aThat[i], 10 ) || 0;
-	
-			// Parts are the same, keep comparing
-			if (iThis === iThat) {
-				continue;
-			}
-	
-			// Parts are different, return immediately
-			return iThis > iThat;
-		}
-	
-		return true;
-	};
-	
-	
-	/**
-	 * Check if a `<table>` node is a DataTable table already or not.
-	 *
-	 *  @param {node|jquery|string} table Table node, jQuery object or jQuery
-	 *      selector for the table to test. Note that if more than more than one
-	 *      table is passed on, only the first will be checked
-	 *  @returns {boolean} true the table given is a DataTable, or false otherwise
-	 *  @static
-	 *  @dtopt API-Static
-	 *
-	 *  @example
-	 *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
-	 *      $('#example').dataTable();
-	 *    }
-	 */
-	DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
-	{
-		var t = $(table).get(0);
-		var is = false;
-	
-		if ( table instanceof DataTable.Api ) {
-			return true;
-		}
-	
-		$.each( DataTable.settings, function (i, o) {
-			var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
-			var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
-	
-			if ( o.nTable === t || head === t || foot === t ) {
-				is = true;
-			}
-		} );
-	
-		return is;
-	};
-	
-	
-	/**
-	 * Get all DataTable tables that have been initialised - optionally you can
-	 * select to get only currently visible tables.
-	 *
-	 *  @param {boolean} [visible=false] Flag to indicate if you want all (default)
-	 *    or visible tables only.
-	 *  @returns {array} Array of `table` nodes (not DataTable instances) which are
-	 *    DataTables
-	 *  @static
-	 *  @dtopt API-Static
-	 *
-	 *  @example
-	 *    $.each( $.fn.dataTable.tables(true), function () {
-	 *      $(table).DataTable().columns.adjust();
-	 *    } );
-	 */
-	DataTable.tables = DataTable.fnTables = function ( visible )
-	{
-		var api = false;
-	
-		if ( $.isPlainObject( visible ) ) {
-			api = visible.api;
-			visible = visible.visible;
-		}
-	
-		var a = $.map( DataTable.settings, function (o) {
-			if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
-				return o.nTable;
-			}
-		} );
-	
-		return api ?
-			new _Api( a ) :
-			a;
-	};
-	
-	
-	/**
-	 * Convert from camel case parameters to Hungarian notation. This is made public
-	 * for the extensions to provide the same ability as DataTables core to accept
-	 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
-	 * parameters.
-	 *
-	 *  @param {object} src The model object which holds all parameters that can be
-	 *    mapped.
-	 *  @param {object} user The object to convert from camel case to Hungarian.
-	 *  @param {boolean} force When set to `true`, properties which already have a
-	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
-	 *    won't be.
-	 */
-	DataTable.camelToHungarian = _fnCamelToHungarian;
-	
-	
-	
-	/**
-	 *
-	 */
-	_api_register( '$()', function ( selector, opts ) {
-		var
-			rows   = this.rows( opts ).nodes(), // Get all rows
-			jqRows = $(rows);
-	
-		return $( [].concat(
-			jqRows.filter( selector ).toArray(),
-			jqRows.find( selector ).toArray()
-		) );
-	} );
-	
-	
-	// jQuery functions to operate on the tables
-	$.each( [ 'on', 'one', 'off' ], function (i, key) {
-		_api_register( key+'()', function ( /* event, handler */ ) {
-			var args = Array.prototype.slice.call(arguments);
-	
-			// Add the `dt` namespace automatically if it isn't already present
-			args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
-				return ! e.match(/\.dt\b/) ?
-					e+'.dt' :
-					e;
-				} ).join( ' ' );
-	
-			var inst = $( this.tables().nodes() );
-			inst[key].apply( inst, args );
-			return this;
-		} );
-	} );
-	
-	
-	_api_register( 'clear()', function () {
-		return this.iterator( 'table', function ( settings ) {
-			_fnClearTable( settings );
-		} );
-	} );
-	
-	
-	_api_register( 'settings()', function () {
-		return new _Api( this.context, this.context );
-	} );
-	
-	
-	_api_register( 'init()', function () {
-		var ctx = this.context;
-		return ctx.length ? ctx[0].oInit : null;
-	} );
-	
-	
-	_api_register( 'data()', function () {
-		return this.iterator( 'table', function ( settings ) {
-			return _pluck( settings.aoData, '_aData' );
-		} ).flatten();
-	} );
-	
-	
-	_api_register( 'destroy()', function ( remove ) {
-		remove = remove || false;
-	
-		return this.iterator( 'table', function ( settings ) {
-			var orig      = settings.nTableWrapper.parentNode;
-			var classes   = settings.oClasses;
-			var table     = settings.nTable;
-			var tbody     = settings.nTBody;
-			var thead     = settings.nTHead;
-			var tfoot     = settings.nTFoot;
-			var jqTable   = $(table);
-			var jqTbody   = $(tbody);
-			var jqWrapper = $(settings.nTableWrapper);
-			var rows      = $.map( settings.aoData, function (r) { return r.nTr; } );
-			var i, ien;
-	
-			// Flag to note that the table is currently being destroyed - no action
-			// should be taken
-			settings.bDestroying = true;
-	
-			// Fire off the destroy callbacks for plug-ins etc
-			_fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
-	
-			// If not being removed from the document, make all columns visible
-			if ( ! remove ) {
-				new _Api( settings ).columns().visible( true );
-			}
-	
-			// Blitz all `DT` namespaced events (these are internal events, the
-			// lowercase, `dt` events are user subscribed and they are responsible
-			// for removing them
-			jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
-			$(window).off('.DT-'+settings.sInstance);
-	
-			// When scrolling we had to break the table up - restore it
-			if ( table != thead.parentNode ) {
-				jqTable.children('thead').detach();
-				jqTable.append( thead );
-			}
-	
-			if ( tfoot && table != tfoot.parentNode ) {
-				jqTable.children('tfoot').detach();
-				jqTable.append( tfoot );
-			}
-	
-			settings.aaSorting = [];
-			settings.aaSortingFixed = [];
-			_fnSortingClasses( settings );
-	
-			$( rows ).removeClass( settings.asStripeClasses.join(' ') );
-	
-			$('th, td', thead).removeClass( classes.sSortable+' '+
-				classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
-			);
-	
-			// Add the TR elements back into the table in their original order
-			jqTbody.children().detach();
-			jqTbody.append( rows );
-	
-			// Remove the DataTables generated nodes, events and classes
-			var removedMethod = remove ? 'remove' : 'detach';
-			jqTable[ removedMethod ]();
-			jqWrapper[ removedMethod ]();
-	
-			// If we need to reattach the table to the document
-			if ( ! remove && orig ) {
-				// insertBefore acts like appendChild if !arg[1]
-				orig.insertBefore( table, settings.nTableReinsertBefore );
-	
-				// Restore the width of the original table - was read from the style property,
-				// so we can restore directly to that
-				jqTable
-					.css( 'width', settings.sDestroyWidth )
-					.removeClass( classes.sTable );
-	
-				// If the were originally stripe classes - then we add them back here.
-				// Note this is not fool proof (for example if not all rows had stripe
-				// classes - but it's a good effort without getting carried away
-				ien = settings.asDestroyStripes.length;
-	
-				if ( ien ) {
-					jqTbody.children().each( function (i) {
-						$(this).addClass( settings.asDestroyStripes[i % ien] );
-					} );
-				}
-			}
-	
-			/* Remove the settings object from the settings array */
-			var idx = $.inArray( settings, DataTable.settings );
-			if ( idx !== -1 ) {
-				DataTable.settings.splice( idx, 1 );
-			}
-		} );
-	} );
-	
-	
-	// Add the `every()` method for rows, columns and cells in a compact form
-	$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
-		_api_register( type+'s().every()', function ( fn ) {
-			var opts = this.selector.opts;
-			var api = this;
-	
-			return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
-				// Rows and columns:
-				//  arg1 - index
-				//  arg2 - table counter
-				//  arg3 - loop counter
-				//  arg4 - undefined
-				// Cells:
-				//  arg1 - row index
-				//  arg2 - column index
-				//  arg3 - table counter
-				//  arg4 - loop counter
-				fn.call(
-					api[ type ](
-						arg1,
-						type==='cell' ? arg2 : opts,
-						type==='cell' ? opts : undefined
-					),
-					arg1, arg2, arg3, arg4
-				);
-			} );
-		} );
-	} );
-	
-	
-	// i18n method for extensions to be able to use the language object from the
-	// DataTable
-	_api_register( 'i18n()', function ( token, def, plural ) {
-		var ctx = this.context[0];
-		var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
-	
-		if ( resolved === undefined ) {
-			resolved = def;
-		}
-	
-		if ( plural !== undefined && $.isPlainObject( resolved ) ) {
-			resolved = resolved[ plural ] !== undefined ?
-				resolved[ plural ] :
-				resolved._;
-		}
-	
-		return resolved.replace( '%d', plural ); // nb: plural might be undefined,
-	} );
-	/**
-	 * Version string for plug-ins to check compatibility. Allowed format is
-	 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
-	 * only for non-release builds. See http://semver.org/ for more information.
-	 *  @member
-	 *  @type string
-	 *  @default Version number
-	 */
-	DataTable.version = "1.10.23";
-
-	/**
-	 * Private data store, containing all of the settings objects that are
-	 * created for the tables on a given page.
-	 *
-	 * Note that the `DataTable.settings` object is aliased to
-	 * `jQuery.fn.dataTableExt` through which it may be accessed and
-	 * manipulated, or `jQuery.fn.dataTable.settings`.
-	 *  @member
-	 *  @type array
-	 *  @default []
-	 *  @private
-	 */
-	DataTable.settings = [];
-
-	/**
-	 * Object models container, for the various models that DataTables has
-	 * available to it. These models define the objects that are used to hold
-	 * the active state and configuration of the table.
-	 *  @namespace
-	 */
-	DataTable.models = {};
-	
-	
-	
-	/**
-	 * Template object for the way in which DataTables holds information about
-	 * search information for the global filter and individual column filters.
-	 *  @namespace
-	 */
-	DataTable.models.oSearch = {
-		/**
-		 * Flag to indicate if the filtering should be case insensitive or not
-		 *  @type boolean
-		 *  @default true
-		 */
-		"bCaseInsensitive": true,
-	
-		/**
-		 * Applied search term
-		 *  @type string
-		 *  @default <i>Empty string</i>
-		 */
-		"sSearch": "",
-	
-		/**
-		 * Flag to indicate if the search term should be interpreted as a
-		 * regular expression (true) or not (false) and therefore and special
-		 * regex characters escaped.
-		 *  @type boolean
-		 *  @default false
-		 */
-		"bRegex": false,
-	
-		/**
-		 * Flag to indicate if DataTables is to use its smart filtering or not.
-		 *  @type boolean
-		 *  @default true
-		 */
-		"bSmart": true
-	};
-	
-	
-	
-	
-	/**
-	 * Template object for the way in which DataTables holds information about
-	 * each individual row. This is the object format used for the settings
-	 * aoData array.
-	 *  @namespace
-	 */
-	DataTable.models.oRow = {
-		/**
-		 * TR element for the row
-		 *  @type node
-		 *  @default null
-		 */
-		"nTr": null,
-	
-		/**
-		 * Array of TD elements for each row. This is null until the row has been
-		 * created.
-		 *  @type array nodes
-		 *  @default []
-		 */
-		"anCells": null,
-	
-		/**
-		 * Data object from the original data source for the row. This is either
-		 * an array if using the traditional form of DataTables, or an object if
-		 * using mData options. The exact type will depend on the passed in
-		 * data from the data source, or will be an array if using DOM a data
-		 * source.
-		 *  @type array|object
-		 *  @default []
-		 */
-		"_aData": [],
-	
-		/**
-		 * Sorting data cache - this array is ostensibly the same length as the
-		 * number of columns (although each index is generated only as it is
-		 * needed), and holds the data that is used for sorting each column in the
-		 * row. We do this cache generation at the start of the sort in order that
-		 * the formatting of the sort data need be done only once for each cell
-		 * per sort. This array should not be read from or written to by anything
-		 * other than the master sorting methods.
-		 *  @type array
-		 *  @default null
-		 *  @private
-		 */
-		"_aSortData": null,
-	
-		/**
-		 * Per cell filtering data cache. As per the sort data cache, used to
-		 * increase the performance of the filtering in DataTables
-		 *  @type array
-		 *  @default null
-		 *  @private
-		 */
-		"_aFilterData": null,
-	
-		/**
-		 * Filtering data cache. This is the same as the cell filtering cache, but
-		 * in this case a string rather than an array. This is easily computed with
-		 * a join on `_aFilterData`, but is provided as a cache so the join isn't
-		 * needed on every search (memory traded for performance)
-		 *  @type array
-		 *  @default null
-		 *  @private
-		 */
-		"_sFilterRow": null,
-	
-		/**
-		 * Cache of the class name that DataTables has applied to the row, so we
-		 * can quickly look at this variable rather than needing to do a DOM check
-		 * on className for the nTr property.
-		 *  @type string
-		 *  @default <i>Empty string</i>
-		 *  @private
-		 */
-		"_sRowStripe": "",
-	
-		/**
-		 * Denote if the original data source was from the DOM, or the data source
-		 * object. This is used for invalidating data, so DataTables can
-		 * automatically read data from the original source, unless uninstructed
-		 * otherwise.
-		 *  @type string
-		 *  @default null
-		 *  @private
-		 */
-		"src": null,
-	
-		/**
-		 * Index in the aoData array. This saves an indexOf lookup when we have the
-		 * object, but want to know the index
-		 *  @type integer
-		 *  @default -1
-		 *  @private
-		 */
-		"idx": -1
-	};
-	
-	
-	/**
-	 * Template object for the column information object in DataTables. This object
-	 * is held in the settings aoColumns array and contains all the information that
-	 * DataTables needs about each individual column.
-	 *
-	 * Note that this object is related to {@link DataTable.defaults.column}
-	 * but this one is the internal data store for DataTables's cache of columns.
-	 * It should NOT be manipulated outside of DataTables. Any configuration should
-	 * be done through the initialisation options.
-	 *  @namespace
-	 */
-	DataTable.models.oColumn = {
-		/**
-		 * Column index. This could be worked out on-the-fly with $.inArray, but it
-		 * is faster to just hold it as a variable
-		 *  @type integer
-		 *  @default null
-		 */
-		"idx": null,
-	
-		/**
-		 * A list of the columns that sorting should occur on when this column
-		 * is sorted. That this property is an array allows multi-column sorting
-		 * to be defined for a column (for example first name / last name columns
-		 * would benefit from this). The values are integers pointing to the
-		 * columns to be sorted on (typically it will be a single integer pointing
-		 * at itself, but that doesn't need to be the case).
-		 *  @type array
-		 */
-		"aDataSort": null,
-	
-		/**
-		 * Define the sorting directions that are applied to the column, in sequence
-		 * as the column is repeatedly sorted upon - i.e. the first value is used
-		 * as the sorting direction when the column if first sorted (clicked on).
-		 * Sort it again (click again) and it will move on to the next index.
-		 * Repeat until loop.
-		 *  @type array
-		 */
-		"asSorting": null,
-	
-		/**
-		 * Flag to indicate if the column is searchable, and thus should be included
-		 * in the filtering or not.
-		 *  @type boolean
-		 */
-		"bSearchable": null,
-	
-		/**
-		 * Flag to indicate if the column is sortable or not.
-		 *  @type boolean
-		 */
-		"bSortable": null,
-	
-		/**
-		 * Flag to indicate if the column is currently visible in the table or not
-		 *  @type boolean
-		 */
-		"bVisible": null,
-	
-		/**
-		 * Store for manual type assignment using the `column.type` option. This
-		 * is held in store so we can manipulate the column's `sType` property.
-		 *  @type string
-		 *  @default null
-		 *  @private
-		 */
-		"_sManualType": null,
-	
-		/**
-		 * Flag to indicate if HTML5 data attributes should be used as the data
-		 * source for filtering or sorting. True is either are.
-		 *  @type boolean
-		 *  @default false
-		 *  @private
-		 */
-		"_bAttrSrc": false,
-	
-		/**
-		 * Developer definable function that is called whenever a cell is created (Ajax source,
-		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
-		 * allowing you to modify the DOM element (add background colour for example) when the
-		 * element is available.
-		 *  @type function
-		 *  @param {element} nTd The TD node that has been created
-		 *  @param {*} sData The Data for the cell
-		 *  @param {array|object} oData The data for the whole row
-		 *  @param {int} iRow The row index for the aoData data store
-		 *  @default null
-		 */
-		"fnCreatedCell": null,
-	
-		/**
-		 * Function to get data from a cell in a column. You should <b>never</b>
-		 * access data directly through _aData internally in DataTables - always use
-		 * the method attached to this property. It allows mData to function as
-		 * required. This function is automatically assigned by the column
-		 * initialisation method
-		 *  @type function
-		 *  @param {array|object} oData The data array/object for the array
-		 *    (i.e. aoData[]._aData)
-		 *  @param {string} sSpecific The specific data type you want to get -
-		 *    'display', 'type' 'filter' 'sort'
-		 *  @returns {*} The data for the cell from the given row's data
-		 *  @default null
-		 */
-		"fnGetData": null,
-	
-		/**
-		 * Function to set data for a cell in the column. You should <b>never</b>
-		 * set the data directly to _aData internally in DataTables - always use
-		 * this method. It allows mData to function as required. This function
-		 * is automatically assigned by the column initialisation method
-		 *  @type function
-		 *  @param {array|object} oData The data array/object for the array
-		 *    (i.e. aoData[]._aData)
-		 *  @param {*} sValue Value to set
-		 *  @default null
-		 */
-		"fnSetData": null,
-	
-		/**
-		 * Property to read the value for the cells in the column from the data
-		 * source array / object. If null, then the default content is used, if a
-		 * function is given then the return from the function is used.
-		 *  @type function|int|string|null
-		 *  @default null
-		 */
-		"mData": null,
-	
-		/**
-		 * Partner property to mData which is used (only when defined) to get
-		 * the data - i.e. it is basically the same as mData, but without the
-		 * 'set' option, and also the data fed to it is the result from mData.
-		 * This is the rendering method to match the data method of mData.
-		 *  @type function|int|string|null
-		 *  @default null
-		 */
-		"mRender": null,
-	
-		/**
-		 * Unique header TH/TD element for this column - this is what the sorting
-		 * listener is attached to (if sorting is enabled.)
-		 *  @type node
-		 *  @default null
-		 */
-		"nTh": null,
-	
-		/**
-		 * Unique footer TH/TD element for this column (if there is one). Not used
-		 * in DataTables as such, but can be used for plug-ins to reference the
-		 * footer for each column.
-		 *  @type node
-		 *  @default null
-		 */
-		"nTf": null,
-	
-		/**
-		 * The class to apply to all TD elements in the table's TBODY for the column
-		 *  @type string
-		 *  @default null
-		 */
-		"sClass": null,
-	
-		/**
-		 * When DataTables calculates the column widths to assign to each column,
-		 * it finds the longest string in each column and then constructs a
-		 * temporary table and reads the widths from that. The problem with this
-		 * is that "mmm" is much wider then "iiii", but the latter is a longer
-		 * string - thus the calculation can go wrong (doing it properly and putting
-		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
-		 * a "work around" we provide this option. It will append its value to the
-		 * text that is found to be the longest string for the column - i.e. padding.
-		 *  @type string
-		 */
-		"sContentPadding": null,
-	
-		/**
-		 * Allows a default value to be given for a column's data, and will be used
-		 * whenever a null data source is encountered (this can be because mData
-		 * is set to null, or because the data source itself is null).
-		 *  @type string
-		 *  @default null
-		 */
-		"sDefaultContent": null,
-	
-		/**
-		 * Name for the column, allowing reference to the column by name as well as
-		 * by index (needs a lookup to work by name).
-		 *  @type string
-		 */
-		"sName": null,
-	
-		/**
-		 * Custom sorting data type - defines which of the available plug-ins in
-		 * afnSortData the custom sorting will use - if any is defined.
-		 *  @type string
-		 *  @default std
-		 */
-		"sSortDataType": 'std',
-	
-		/**
-		 * Class to be applied to the header element when sorting on this column
-		 *  @type string
-		 *  @default null
-		 */
-		"sSortingClass": null,
-	
-		/**
-		 * Class to be applied to the header element when sorting on this column -
-		 * when jQuery UI theming is used.
-		 *  @type string
-		 *  @default null
-		 */
-		"sSortingClassJUI": null,
-	
-		/**
-		 * Title of the column - what is seen in the TH element (nTh).
-		 *  @type string
-		 */
-		"sTitle": null,
-	
-		/**
-		 * Column sorting and filtering type
-		 *  @type string
-		 *  @default null
-		 */
-		"sType": null,
-	
-		/**
-		 * Width of the column
-		 *  @type string
-		 *  @default null
-		 */
-		"sWidth": null,
-	
-		/**
-		 * Width of the column when it was first "encountered"
-		 *  @type string
-		 *  @default null
-		 */
-		"sWidthOrig": null
-	};
-	
-	
-	/*
-	 * Developer note: The properties of the object below are given in Hungarian
-	 * notation, that was used as the interface for DataTables prior to v1.10, however
-	 * from v1.10 onwards the primary interface is camel case. In order to avoid
-	 * breaking backwards compatibility utterly with this change, the Hungarian
-	 * version is still, internally the primary interface, but is is not documented
-	 * - hence the @name tags in each doc comment. This allows a Javascript function
-	 * to create a map from Hungarian notation to camel case (going the other direction
-	 * would require each property to be listed, which would add around 3K to the size
-	 * of DataTables, while this method is about a 0.5K hit).
-	 *
-	 * Ultimately this does pave the way for Hungarian notation to be dropped
-	 * completely, but that is a massive amount of work and will break current
-	 * installs (therefore is on-hold until v2).
-	 */
-	
-	/**
-	 * Initialisation options that can be given to DataTables at initialisation
-	 * time.
-	 *  @namespace
-	 */
-	DataTable.defaults = {
-		/**
-		 * An array of data to use for the table, passed in at initialisation which
-		 * will be used in preference to any data which is already in the DOM. This is
-		 * particularly useful for constructing tables purely in Javascript, for
-		 * example with a custom Ajax call.
-		 *  @type array
-		 *  @default null
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.data
-		 *
-		 *  @example
-		 *    // Using a 2D array data source
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "data": [
-		 *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
-		 *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
-		 *        ],
-		 *        "columns": [
-		 *          { "title": "Engine" },
-		 *          { "title": "Browser" },
-		 *          { "title": "Platform" },
-		 *          { "title": "Version" },
-		 *          { "title": "Grade" }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using an array of objects as a data source (`data`)
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "data": [
-		 *          {
-		 *            "engine":   "Trident",
-		 *            "browser":  "Internet Explorer 4.0",
-		 *            "platform": "Win 95+",
-		 *            "version":  4,
-		 *            "grade":    "X"
-		 *          },
-		 *          {
-		 *            "engine":   "Trident",
-		 *            "browser":  "Internet Explorer 5.0",
-		 *            "platform": "Win 95+",
-		 *            "version":  5,
-		 *            "grade":    "C"
-		 *          }
-		 *        ],
-		 *        "columns": [
-		 *          { "title": "Engine",   "data": "engine" },
-		 *          { "title": "Browser",  "data": "browser" },
-		 *          { "title": "Platform", "data": "platform" },
-		 *          { "title": "Version",  "data": "version" },
-		 *          { "title": "Grade",    "data": "grade" }
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"aaData": null,
-	
-	
-		/**
-		 * If ordering is enabled, then DataTables will perform a first pass sort on
-		 * initialisation. You can define which column(s) the sort is performed
-		 * upon, and the sorting direction, with this variable. The `sorting` array
-		 * should contain an array for each column to be sorted initially containing
-		 * the column's index and a direction string ('asc' or 'desc').
-		 *  @type array
-		 *  @default [[0,'asc']]
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.order
-		 *
-		 *  @example
-		 *    // Sort by 3rd column first, and then 4th column
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "order": [[2,'asc'], [3,'desc']]
-		 *      } );
-		 *    } );
-		 *
-		 *    // No initial sorting
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "order": []
-		 *      } );
-		 *    } );
-		 */
-		"aaSorting": [[0,'asc']],
-	
-	
-		/**
-		 * This parameter is basically identical to the `sorting` parameter, but
-		 * cannot be overridden by user interaction with the table. What this means
-		 * is that you could have a column (visible or hidden) which the sorting
-		 * will always be forced on first - any sorting after that (from the user)
-		 * will then be performed as required. This can be useful for grouping rows
-		 * together.
-		 *  @type array
-		 *  @default null
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.orderFixed
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "orderFixed": [[0,'asc']]
-		 *      } );
-		 *    } )
-		 */
-		"aaSortingFixed": [],
-	
-	
-		/**
-		 * DataTables can be instructed to load data to display in the table from a
-		 * Ajax source. This option defines how that Ajax call is made and where to.
-		 *
-		 * The `ajax` property has three different modes of operation, depending on
-		 * how it is defined. These are:
-		 *
-		 * * `string` - Set the URL from where the data should be loaded from.
-		 * * `object` - Define properties for `jQuery.ajax`.
-		 * * `function` - Custom data get function
-		 *
-		 * `string`
-		 * --------
-		 *
-		 * As a string, the `ajax` property simply defines the URL from which
-		 * DataTables will load data.
-		 *
-		 * `object`
-		 * --------
-		 *
-		 * As an object, the parameters in the object are passed to
-		 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
-		 * of the Ajax request. DataTables has a number of default parameters which
-		 * you can override using this option. Please refer to the jQuery
-		 * documentation for a full description of the options available, although
-		 * the following parameters provide additional options in DataTables or
-		 * require special consideration:
-		 *
-		 * * `data` - As with jQuery, `data` can be provided as an object, but it
-		 *   can also be used as a function to manipulate the data DataTables sends
-		 *   to the server. The function takes a single parameter, an object of
-		 *   parameters with the values that DataTables has readied for sending. An
-		 *   object may be returned which will be merged into the DataTables
-		 *   defaults, or you can add the items to the object that was passed in and
-		 *   not return anything from the function. This supersedes `fnServerParams`
-		 *   from DataTables 1.9-.
-		 *
-		 * * `dataSrc` - By default DataTables will look for the property `data` (or
-		 *   `aaData` for compatibility with DataTables 1.9-) when obtaining data
-		 *   from an Ajax source or for server-side processing - this parameter
-		 *   allows that property to be changed. You can use Javascript dotted
-		 *   object notation to get a data source for multiple levels of nesting, or
-		 *   it my be used as a function. As a function it takes a single parameter,
-		 *   the JSON returned from the server, which can be manipulated as
-		 *   required, with the returned value being that used by DataTables as the
-		 *   data source for the table. This supersedes `sAjaxDataProp` from
-		 *   DataTables 1.9-.
-		 *
-		 * * `success` - Should not be overridden it is used internally in
-		 *   DataTables. To manipulate / transform the data returned by the server
-		 *   use `ajax.dataSrc`, or use `ajax` as a function (see below).
-		 *
-		 * `function`
-		 * ----------
-		 *
-		 * As a function, making the Ajax call is left up to yourself allowing
-		 * complete control of the Ajax request. Indeed, if desired, a method other
-		 * than Ajax could be used to obtain the required data, such as Web storage
-		 * or an AIR database.
-		 *
-		 * The function is given four parameters and no return is required. The
-		 * parameters are:
-		 *
-		 * 1. _object_ - Data to send to the server
-		 * 2. _function_ - Callback function that must be executed when the required
-		 *    data has been obtained. That data should be passed into the callback
-		 *    as the only parameter
-		 * 3. _object_ - DataTables settings object for the table
-		 *
-		 * Note that this supersedes `fnServerData` from DataTables 1.9-.
-		 *
-		 *  @type string|object|function
-		 *  @default null
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.ajax
-		 *  @since 1.10.0
-		 *
-		 * @example
-		 *   // Get JSON data from a file via Ajax.
-		 *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
-		 *   $('#example').dataTable( {
-		 *     "ajax": "data.json"
-		 *   } );
-		 *
-		 * @example
-		 *   // Get JSON data from a file via Ajax, using `dataSrc` to change
-		 *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
-		 *   $('#example').dataTable( {
-		 *     "ajax": {
-		 *       "url": "data.json",
-		 *       "dataSrc": "tableData"
-		 *     }
-		 *   } );
-		 *
-		 * @example
-		 *   // Get JSON data from a file via Ajax, using `dataSrc` to read data
-		 *   // from a plain array rather than an array in an object
-		 *   $('#example').dataTable( {
-		 *     "ajax": {
-		 *       "url": "data.json",
-		 *       "dataSrc": ""
-		 *     }
-		 *   } );
-		 *
-		 * @example
-		 *   // Manipulate the data returned from the server - add a link to data
-		 *   // (note this can, should, be done using `render` for the column - this
-		 *   // is just a simple example of how the data can be manipulated).
-		 *   $('#example').dataTable( {
-		 *     "ajax": {
-		 *       "url": "data.json",
-		 *       "dataSrc": function ( json ) {
-		 *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {
-		 *           json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
-		 *         }
-		 *         return json;
-		 *       }
-		 *     }
-		 *   } );
-		 *
-		 * @example
-		 *   // Add data to the request
-		 *   $('#example').dataTable( {
-		 *     "ajax": {
-		 *       "url": "data.json",
-		 *       "data": function ( d ) {
-		 *         return {
-		 *           "extra_search": $('#extra').val()
-		 *         };
-		 *       }
-		 *     }
-		 *   } );
-		 *
-		 * @example
-		 *   // Send request as POST
-		 *   $('#example').dataTable( {
-		 *     "ajax": {
-		 *       "url": "data.json",
-		 *       "type": "POST"
-		 *     }
-		 *   } );
-		 *
-		 * @example
-		 *   // Get the data from localStorage (could interface with a form for
-		 *   // adding, editing and removing rows).
-		 *   $('#example').dataTable( {
-		 *     "ajax": function (data, callback, settings) {
-		 *       callback(
-		 *         JSON.parse( localStorage.getItem('dataTablesData') )
-		 *       );
-		 *     }
-		 *   } );
-		 */
-		"ajax": null,
-	
-	
-		/**
-		 * This parameter allows you to readily specify the entries in the length drop
-		 * down menu that DataTables shows when pagination is enabled. It can be
-		 * either a 1D array of options which will be used for both the displayed
-		 * option and the value, or a 2D array which will use the array in the first
-		 * position as the value, and the array in the second position as the
-		 * displayed options (useful for language strings such as 'All').
-		 *
-		 * Note that the `pageLength` property will be automatically set to the
-		 * first value given in this array, unless `pageLength` is also provided.
-		 *  @type array
-		 *  @default [ 10, 25, 50, 100 ]
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.lengthMenu
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
-		 *      } );
-		 *    } );
-		 */
-		"aLengthMenu": [ 10, 25, 50, 100 ],
-	
-	
-		/**
-		 * The `columns` option in the initialisation parameter allows you to define
-		 * details about the way individual columns behave. For a full list of
-		 * column options that can be set, please see
-		 * {@link DataTable.defaults.column}. Note that if you use `columns` to
-		 * define your columns, you must have an entry in the array for every single
-		 * column that you have in your table (these can be null if you don't which
-		 * to specify any options).
-		 *  @member
-		 *
-		 *  @name DataTable.defaults.column
-		 */
-		"aoColumns": null,
-	
-		/**
-		 * Very similar to `columns`, `columnDefs` allows you to target a specific
-		 * column, multiple columns, or all columns, using the `targets` property of
-		 * each object in the array. This allows great flexibility when creating
-		 * tables, as the `columnDefs` arrays can be of any length, targeting the
-		 * columns you specifically want. `columnDefs` may use any of the column
-		 * options available: {@link DataTable.defaults.column}, but it _must_
-		 * have `targets` defined in each object in the array. Values in the `targets`
-		 * array may be:
-		 *   <ul>
-		 *     <li>a string - class name will be matched on the TH for the column</li>
-		 *     <li>0 or a positive integer - column index counting from the left</li>
-		 *     <li>a negative integer - column index counting from the right</li>
-		 *     <li>the string "_all" - all columns (i.e. assign a default)</li>
-		 *   </ul>
-		 *  @member
-		 *
-		 *  @name DataTable.defaults.columnDefs
-		 */
-		"aoColumnDefs": null,
-	
-	
-		/**
-		 * Basically the same as `search`, this parameter defines the individual column
-		 * filtering state at initialisation time. The array must be of the same size
-		 * as the number of columns, and each element be an object with the parameters
-		 * `search` and `escapeRegex` (the latter is optional). 'null' is also
-		 * accepted and the default will be used.
-		 *  @type array
-		 *  @default []
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.searchCols
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "searchCols": [
-		 *          null,
-		 *          { "search": "My filter" },
-		 *          null,
-		 *          { "search": "^[0-9]", "escapeRegex": false }
-		 *        ]
-		 *      } );
-		 *    } )
-		 */
-		"aoSearchCols": [],
-	
-	
-		/**
-		 * An array of CSS classes that should be applied to displayed rows. This
-		 * array may be of any length, and DataTables will apply each class
-		 * sequentially, looping when required.
-		 *  @type array
-		 *  @default null <i>Will take the values determined by the `oClasses.stripe*`
-		 *    options</i>
-		 *
-		 *  @dtopt Option
-		 *  @name DataTable.defaults.stripeClasses
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
-		 *      } );
-		 *    } )
-		 */
-		"asStripeClasses": null,
-	
-	
-		/**
-		 * Enable or disable automatic column width calculation. This can be disabled
-		 * as an optimisation (it takes some time to calculate the widths) if the
-		 * tables widths are passed in using `columns`.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.autoWidth
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "autoWidth": false
-		 *      } );
-		 *    } );
-		 */
-		"bAutoWidth": true,
-	
-	
-		/**
-		 * Deferred rendering can provide DataTables with a huge speed boost when you
-		 * are using an Ajax or JS data source for the table. This option, when set to
-		 * true, will cause DataTables to defer the creation of the table elements for
-		 * each row until they are needed for a draw - saving a significant amount of
-		 * time.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.deferRender
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "ajax": "sources/arrays.txt",
-		 *        "deferRender": true
-		 *      } );
-		 *    } );
-		 */
-		"bDeferRender": false,
-	
-	
-		/**
-		 * Replace a DataTable which matches the given selector and replace it with
-		 * one which has the properties of the new initialisation object passed. If no
-		 * table matches the selector, then the new DataTable will be constructed as
-		 * per normal.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.destroy
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "srollY": "200px",
-		 *        "paginate": false
-		 *      } );
-		 *
-		 *      // Some time later....
-		 *      $('#example').dataTable( {
-		 *        "filter": false,
-		 *        "destroy": true
-		 *      } );
-		 *    } );
-		 */
-		"bDestroy": false,
-	
-	
-		/**
-		 * Enable or disable filtering of data. Filtering in DataTables is "smart" in
-		 * that it allows the end user to input multiple words (space separated) and
-		 * will match a row containing those words, even if not in the order that was
-		 * specified (this allow matching across multiple columns). Note that if you
-		 * wish to use filtering in DataTables this must remain 'true' - to remove the
-		 * default filtering input box and retain filtering abilities, please use
-		 * {@link DataTable.defaults.dom}.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.searching
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "searching": false
-		 *      } );
-		 *    } );
-		 */
-		"bFilter": true,
-	
-	
-		/**
-		 * Enable or disable the table information display. This shows information
-		 * about the data that is currently visible on the page, including information
-		 * about filtered data if that action is being performed.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.info
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "info": false
-		 *      } );
-		 *    } );
-		 */
-		"bInfo": true,
-	
-	
-		/**
-		 * Allows the end user to select the size of a formatted page from a select
-		 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.lengthChange
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "lengthChange": false
-		 *      } );
-		 *    } );
-		 */
-		"bLengthChange": true,
-	
-	
-		/**
-		 * Enable or disable pagination.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.paging
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "paging": false
-		 *      } );
-		 *    } );
-		 */
-		"bPaginate": true,
-	
-	
-		/**
-		 * Enable or disable the display of a 'processing' indicator when the table is
-		 * being processed (e.g. a sort). This is particularly useful for tables with
-		 * large amounts of data where it can take a noticeable amount of time to sort
-		 * the entries.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.processing
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "processing": true
-		 *      } );
-		 *    } );
-		 */
-		"bProcessing": false,
-	
-	
-		/**
-		 * Retrieve the DataTables object for the given selector. Note that if the
-		 * table has already been initialised, this parameter will cause DataTables
-		 * to simply return the object that has already been set up - it will not take
-		 * account of any changes you might have made to the initialisation object
-		 * passed to DataTables (setting this parameter to true is an acknowledgement
-		 * that you understand this). `destroy` can be used to reinitialise a table if
-		 * you need.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.retrieve
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      initTable();
-		 *      tableActions();
-		 *    } );
-		 *
-		 *    function initTable ()
-		 *    {
-		 *      return $('#example').dataTable( {
-		 *        "scrollY": "200px",
-		 *        "paginate": false,
-		 *        "retrieve": true
-		 *      } );
-		 *    }
-		 *
-		 *    function tableActions ()
-		 *    {
-		 *      var table = initTable();
-		 *      // perform API operations with oTable
-		 *    }
-		 */
-		"bRetrieve": false,
-	
-	
-		/**
-		 * When vertical (y) scrolling is enabled, DataTables will force the height of
-		 * the table's viewport to the given height at all times (useful for layout).
-		 * However, this can look odd when filtering data down to a small data set,
-		 * and the footer is left "floating" further down. This parameter (when
-		 * enabled) will cause DataTables to collapse the table's viewport down when
-		 * the result set will fit within the given Y height.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.scrollCollapse
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "scrollY": "200",
-		 *        "scrollCollapse": true
-		 *      } );
-		 *    } );
-		 */
-		"bScrollCollapse": false,
-	
-	
-		/**
-		 * Configure DataTables to use server-side processing. Note that the
-		 * `ajax` parameter must also be given in order to give DataTables a
-		 * source to obtain the required data for each draw.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Features
-		 *  @dtopt Server-side
-		 *  @name DataTable.defaults.serverSide
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "serverSide": true,
-		 *        "ajax": "xhr.php"
-		 *      } );
-		 *    } );
-		 */
-		"bServerSide": false,
-	
-	
-		/**
-		 * Enable or disable sorting of columns. Sorting of individual columns can be
-		 * disabled by the `sortable` option for each column.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.ordering
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "ordering": false
-		 *      } );
-		 *    } );
-		 */
-		"bSort": true,
-	
-	
-		/**
-		 * Enable or display DataTables' ability to sort multiple columns at the
-		 * same time (activated by shift-click by the user).
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.orderMulti
-		 *
-		 *  @example
-		 *    // Disable multiple column sorting ability
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "orderMulti": false
-		 *      } );
-		 *    } );
-		 */
-		"bSortMulti": true,
-	
-	
-		/**
-		 * Allows control over whether DataTables should use the top (true) unique
-		 * cell that is found for a single column, or the bottom (false - default).
-		 * This is useful when using complex headers.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.orderCellsTop
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "orderCellsTop": true
-		 *      } );
-		 *    } );
-		 */
-		"bSortCellsTop": false,
-	
-	
-		/**
-		 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
-		 * `sorting\_3` to the columns which are currently being sorted on. This is
-		 * presented as a feature switch as it can increase processing time (while
-		 * classes are removed and added) so for large data sets you might want to
-		 * turn this off.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.orderClasses
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "orderClasses": false
-		 *      } );
-		 *    } );
-		 */
-		"bSortClasses": true,
-	
-	
-		/**
-		 * Enable or disable state saving. When enabled HTML5 `localStorage` will be
-		 * used to save table display information such as pagination information,
-		 * display length, filtering and sorting. As such when the end user reloads
-		 * the page the display display will match what thy had previously set up.
-		 *
-		 * Due to the use of `localStorage` the default state saving is not supported
-		 * in IE6 or 7. If state saving is required in those browsers, use
-		 * `stateSaveCallback` to provide a storage solution such as cookies.
-		 *  @type boolean
-		 *  @default false
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.stateSave
-		 *
-		 *  @example
-		 *    $(document).ready( function () {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true
-		 *      } );
-		 *    } );
-		 */
-		"bStateSave": false,
-	
-	
-		/**
-		 * This function is called when a TR element is created (and all TD child
-		 * elements have been inserted), or registered if using a DOM source, allowing
-		 * manipulation of the TR element (adding classes etc).
-		 *  @type function
-		 *  @param {node} row "TR" element for the current row
-		 *  @param {array} data Raw data array for this row
-		 *  @param {int} dataIndex The index of this row in the internal aoData array
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.createdRow
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "createdRow": function( row, data, dataIndex ) {
-		 *          // Bold the grade for all 'A' grade browsers
-		 *          if ( data[4] == "A" )
-		 *          {
-		 *            $('td:eq(4)', row).html( '<b>A</b>' );
-		 *          }
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnCreatedRow": null,
-	
-	
-		/**
-		 * This function is called on every 'draw' event, and allows you to
-		 * dynamically modify any aspect you want about the created DOM.
-		 *  @type function
-		 *  @param {object} settings DataTables settings object
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.drawCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "drawCallback": function( settings ) {
-		 *          alert( 'DataTables has redrawn the table' );
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnDrawCallback": null,
-	
-	
-		/**
-		 * Identical to fnHeaderCallback() but for the table footer this function
-		 * allows you to modify the table footer on every 'draw' event.
-		 *  @type function
-		 *  @param {node} foot "TR" element for the footer
-		 *  @param {array} data Full table data (as derived from the original HTML)
-		 *  @param {int} start Index for the current display starting point in the
-		 *    display array
-		 *  @param {int} end Index for the current display ending point in the
-		 *    display array
-		 *  @param {array int} display Index array to translate the visual position
-		 *    to the full data array
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.footerCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "footerCallback": function( tfoot, data, start, end, display ) {
-		 *          tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
-		 *        }
-		 *      } );
-		 *    } )
-		 */
-		"fnFooterCallback": null,
-	
-	
-		/**
-		 * When rendering large numbers in the information element for the table
-		 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
-		 * to have a comma separator for the 'thousands' units (e.g. 1 million is
-		 * rendered as "1,000,000") to help readability for the end user. This
-		 * function will override the default method DataTables uses.
-		 *  @type function
-		 *  @member
-		 *  @param {int} toFormat number to be formatted
-		 *  @returns {string} formatted string for DataTables to show the number
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.formatNumber
-		 *
-		 *  @example
-		 *    // Format a number using a single quote for the separator (note that
-		 *    // this can also be done with the language.thousands option)
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "formatNumber": function ( toFormat ) {
-		 *          return toFormat.toString().replace(
-		 *            /\B(?=(\d{3})+(?!\d))/g, "'"
-		 *          );
-		 *        };
-		 *      } );
-		 *    } );
-		 */
-		"fnFormatNumber": function ( toFormat ) {
-			return toFormat.toString().replace(
-				/\B(?=(\d{3})+(?!\d))/g,
-				this.oLanguage.sThousands
-			);
-		},
-	
-	
-		/**
-		 * This function is called on every 'draw' event, and allows you to
-		 * dynamically modify the header row. This can be used to calculate and
-		 * display useful information about the table.
-		 *  @type function
-		 *  @param {node} head "TR" element for the header
-		 *  @param {array} data Full table data (as derived from the original HTML)
-		 *  @param {int} start Index for the current display starting point in the
-		 *    display array
-		 *  @param {int} end Index for the current display ending point in the
-		 *    display array
-		 *  @param {array int} display Index array to translate the visual position
-		 *    to the full data array
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.headerCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "fheaderCallback": function( head, data, start, end, display ) {
-		 *          head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
-		 *        }
-		 *      } );
-		 *    } )
-		 */
-		"fnHeaderCallback": null,
-	
-	
-		/**
-		 * The information element can be used to convey information about the current
-		 * state of the table. Although the internationalisation options presented by
-		 * DataTables are quite capable of dealing with most customisations, there may
-		 * be times where you wish to customise the string further. This callback
-		 * allows you to do exactly that.
-		 *  @type function
-		 *  @param {object} oSettings DataTables settings object
-		 *  @param {int} start Starting position in data for the draw
-		 *  @param {int} end End position in data for the draw
-		 *  @param {int} max Total number of rows in the table (regardless of
-		 *    filtering)
-		 *  @param {int} total Total number of rows in the data set, after filtering
-		 *  @param {string} pre The string that DataTables has formatted using it's
-		 *    own rules
-		 *  @returns {string} The string to be displayed in the information element.
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.infoCallback
-		 *
-		 *  @example
-		 *    $('#example').dataTable( {
-		 *      "infoCallback": function( settings, start, end, max, total, pre ) {
-		 *        return start +" to "+ end;
-		 *      }
-		 *    } );
-		 */
-		"fnInfoCallback": null,
-	
-	
-		/**
-		 * Called when the table has been initialised. Normally DataTables will
-		 * initialise sequentially and there will be no need for this function,
-		 * however, this does not hold true when using external language information
-		 * since that is obtained using an async XHR call.
-		 *  @type function
-		 *  @param {object} settings DataTables settings object
-		 *  @param {object} json The JSON object request from the server - only
-		 *    present if client-side Ajax sourced data is used
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.initComplete
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "initComplete": function(settings, json) {
-		 *          alert( 'DataTables has finished its initialisation.' );
-		 *        }
-		 *      } );
-		 *    } )
-		 */
-		"fnInitComplete": null,
-	
-	
-		/**
-		 * Called at the very start of each table draw and can be used to cancel the
-		 * draw by returning false, any other return (including undefined) results in
-		 * the full draw occurring).
-		 *  @type function
-		 *  @param {object} settings DataTables settings object
-		 *  @returns {boolean} False will cancel the draw, anything else (including no
-		 *    return) will allow it to complete.
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.preDrawCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "preDrawCallback": function( settings ) {
-		 *          if ( $('#test').val() == 1 ) {
-		 *            return false;
-		 *          }
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnPreDrawCallback": null,
-	
-	
-		/**
-		 * This function allows you to 'post process' each row after it have been
-		 * generated for each table draw, but before it is rendered on screen. This
-		 * function might be used for setting the row class name etc.
-		 *  @type function
-		 *  @param {node} row "TR" element for the current row
-		 *  @param {array} data Raw data array for this row
-		 *  @param {int} displayIndex The display index for the current table draw
-		 *  @param {int} displayIndexFull The index of the data in the full list of
-		 *    rows (after filtering)
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.rowCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
-		 *          // Bold the grade for all 'A' grade browsers
-		 *          if ( data[4] == "A" ) {
-		 *            $('td:eq(4)', row).html( '<b>A</b>' );
-		 *          }
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnRowCallback": null,
-	
-	
-		/**
-		 * __Deprecated__ The functionality provided by this parameter has now been
-		 * superseded by that provided through `ajax`, which should be used instead.
-		 *
-		 * This parameter allows you to override the default function which obtains
-		 * the data from the server so something more suitable for your application.
-		 * For example you could use POST data, or pull information from a Gears or
-		 * AIR database.
-		 *  @type function
-		 *  @member
-		 *  @param {string} source HTTP source to obtain the data from (`ajax`)
-		 *  @param {array} data A key/value pair object containing the data to send
-		 *    to the server
-		 *  @param {function} callback to be called on completion of the data get
-		 *    process that will draw the data on the page.
-		 *  @param {object} settings DataTables settings object
-		 *
-		 *  @dtopt Callbacks
-		 *  @dtopt Server-side
-		 *  @name DataTable.defaults.serverData
-		 *
-		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
-		 */
-		"fnServerData": null,
-	
-	
-		/**
-		 * __Deprecated__ The functionality provided by this parameter has now been
-		 * superseded by that provided through `ajax`, which should be used instead.
-		 *
-		 *  It is often useful to send extra data to the server when making an Ajax
-		 * request - for example custom filtering information, and this callback
-		 * function makes it trivial to send extra information to the server. The
-		 * passed in parameter is the data set that has been constructed by
-		 * DataTables, and you can add to this or modify it as you require.
-		 *  @type function
-		 *  @param {array} data Data array (array of objects which are name/value
-		 *    pairs) that has been constructed by DataTables and will be sent to the
-		 *    server. In the case of Ajax sourced data with server-side processing
-		 *    this will be an empty array, for server-side processing there will be a
-		 *    significant number of parameters!
-		 *  @returns {undefined} Ensure that you modify the data array passed in,
-		 *    as this is passed by reference.
-		 *
-		 *  @dtopt Callbacks
-		 *  @dtopt Server-side
-		 *  @name DataTable.defaults.serverParams
-		 *
-		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
-		 */
-		"fnServerParams": null,
-	
-	
-		/**
-		 * Load the table state. With this function you can define from where, and how, the
-		 * state of a table is loaded. By default DataTables will load from `localStorage`
-		 * but you might wish to use a server-side database or cookies.
-		 *  @type function
-		 *  @member
-		 *  @param {object} settings DataTables settings object
-		 *  @param {object} callback Callback that can be executed when done. It
-		 *    should be passed the loaded state object.
-		 *  @return {object} The DataTables state object to be loaded
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.stateLoadCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true,
-		 *        "stateLoadCallback": function (settings, callback) {
-		 *          $.ajax( {
-		 *            "url": "/state_load",
-		 *            "dataType": "json",
-		 *            "success": function (json) {
-		 *              callback( json );
-		 *            }
-		 *          } );
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnStateLoadCallback": function ( settings ) {
-			try {
-				return JSON.parse(
-					(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
-						'DataTables_'+settings.sInstance+'_'+location.pathname
-					)
-				);
-			} catch (e) {
-				return {};
-			}
-		},
-	
-	
-		/**
-		 * Callback which allows modification of the saved state prior to loading that state.
-		 * This callback is called when the table is loading state from the stored data, but
-		 * prior to the settings object being modified by the saved state. Note that for
-		 * plug-in authors, you should use the `stateLoadParams` event to load parameters for
-		 * a plug-in.
-		 *  @type function
-		 *  @param {object} settings DataTables settings object
-		 *  @param {object} data The state object that is to be loaded
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.stateLoadParams
-		 *
-		 *  @example
-		 *    // Remove a saved filter, so filtering is never loaded
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true,
-		 *        "stateLoadParams": function (settings, data) {
-		 *          data.oSearch.sSearch = "";
-		 *        }
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Disallow state loading by returning false
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true,
-		 *        "stateLoadParams": function (settings, data) {
-		 *          return false;
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnStateLoadParams": null,
-	
-	
-		/**
-		 * Callback that is called when the state has been loaded from the state saving method
-		 * and the DataTables settings object has been modified as a result of the loaded state.
-		 *  @type function
-		 *  @param {object} settings DataTables settings object
-		 *  @param {object} data The state object that was loaded
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.stateLoaded
-		 *
-		 *  @example
-		 *    // Show an alert with the filtering value that was saved
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true,
-		 *        "stateLoaded": function (settings, data) {
-		 *          alert( 'Saved filter was: '+data.oSearch.sSearch );
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnStateLoaded": null,
-	
-	
-		/**
-		 * Save the table state. This function allows you to define where and how the state
-		 * information for the table is stored By default DataTables will use `localStorage`
-		 * but you might wish to use a server-side database or cookies.
-		 *  @type function
-		 *  @member
-		 *  @param {object} settings DataTables settings object
-		 *  @param {object} data The state object to be saved
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.stateSaveCallback
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true,
-		 *        "stateSaveCallback": function (settings, data) {
-		 *          // Send an Ajax request to the server with the state object
-		 *          $.ajax( {
-		 *            "url": "/state_save",
-		 *            "data": data,
-		 *            "dataType": "json",
-		 *            "method": "POST"
-		 *            "success": function () {}
-		 *          } );
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnStateSaveCallback": function ( settings, data ) {
-			try {
-				(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
-					'DataTables_'+settings.sInstance+'_'+location.pathname,
-					JSON.stringify( data )
-				);
-			} catch (e) {}
-		},
-	
-	
-		/**
-		 * Callback which allows modification of the state to be saved. Called when the table
-		 * has changed state a new state save is required. This method allows modification of
-		 * the state saving object prior to actually doing the save, including addition or
-		 * other state properties or modification. Note that for plug-in authors, you should
-		 * use the `stateSaveParams` event to save parameters for a plug-in.
-		 *  @type function
-		 *  @param {object} settings DataTables settings object
-		 *  @param {object} data The state object to be saved
-		 *
-		 *  @dtopt Callbacks
-		 *  @name DataTable.defaults.stateSaveParams
-		 *
-		 *  @example
-		 *    // Remove a saved filter, so filtering is never saved
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateSave": true,
-		 *        "stateSaveParams": function (settings, data) {
-		 *          data.oSearch.sSearch = "";
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"fnStateSaveParams": null,
-	
-	
-		/**
-		 * Duration for which the saved state information is considered valid. After this period
-		 * has elapsed the state will be returned to the default.
-		 * Value is given in seconds.
-		 *  @type int
-		 *  @default 7200 <i>(2 hours)</i>
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.stateDuration
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "stateDuration": 60*60*24; // 1 day
-		 *      } );
-		 *    } )
-		 */
-		"iStateDuration": 7200,
-	
-	
-		/**
-		 * When enabled DataTables will not make a request to the server for the first
-		 * page draw - rather it will use the data already on the page (no sorting etc
-		 * will be applied to it), thus saving on an XHR at load time. `deferLoading`
-		 * is used to indicate that deferred loading is required, but it is also used
-		 * to tell DataTables how many records there are in the full table (allowing
-		 * the information element and pagination to be displayed correctly). In the case
-		 * where a filtering is applied to the table on initial load, this can be
-		 * indicated by giving the parameter as an array, where the first element is
-		 * the number of records available after filtering and the second element is the
-		 * number of records without filtering (allowing the table information element
-		 * to be shown correctly).
-		 *  @type int | array
-		 *  @default null
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.deferLoading
-		 *
-		 *  @example
-		 *    // 57 records available in the table, no filtering applied
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "serverSide": true,
-		 *        "ajax": "scripts/server_processing.php",
-		 *        "deferLoading": 57
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // 57 records after filtering, 100 without filtering (an initial filter applied)
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "serverSide": true,
-		 *        "ajax": "scripts/server_processing.php",
-		 *        "deferLoading": [ 57, 100 ],
-		 *        "search": {
-		 *          "search": "my_filter"
-		 *        }
-		 *      } );
-		 *    } );
-		 */
-		"iDeferLoading": null,
-	
-	
-		/**
-		 * Number of rows to display on a single page when using pagination. If
-		 * feature enabled (`lengthChange`) then the end user will be able to override
-		 * this to a custom setting using a pop-up menu.
-		 *  @type int
-		 *  @default 10
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.pageLength
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "pageLength": 50
-		 *      } );
-		 *    } )
-		 */
-		"iDisplayLength": 10,
-	
-	
-		/**
-		 * Define the starting point for data display when using DataTables with
-		 * pagination. Note that this parameter is the number of records, rather than
-		 * the page number, so if you have 10 records per page and want to start on
-		 * the third page, it should be "20".
-		 *  @type int
-		 *  @default 0
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.displayStart
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "displayStart": 20
-		 *      } );
-		 *    } )
-		 */
-		"iDisplayStart": 0,
-	
-	
-		/**
-		 * By default DataTables allows keyboard navigation of the table (sorting, paging,
-		 * and filtering) by adding a `tabindex` attribute to the required elements. This
-		 * allows you to tab through the controls and press the enter key to activate them.
-		 * The tabindex is default 0, meaning that the tab follows the flow of the document.
-		 * You can overrule this using this parameter if you wish. Use a value of -1 to
-		 * disable built-in keyboard navigation.
-		 *  @type int
-		 *  @default 0
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.tabIndex
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "tabIndex": 1
-		 *      } );
-		 *    } );
-		 */
-		"iTabIndex": 0,
-	
-	
-		/**
-		 * Classes that DataTables assigns to the various components and features
-		 * that it adds to the HTML table. This allows classes to be configured
-		 * during initialisation in addition to through the static
-		 * {@link DataTable.ext.oStdClasses} object).
-		 *  @namespace
-		 *  @name DataTable.defaults.classes
-		 */
-		"oClasses": {},
-	
-	
-		/**
-		 * All strings that DataTables uses in the user interface that it creates
-		 * are defined in this object, allowing you to modified them individually or
-		 * completely replace them all as required.
-		 *  @namespace
-		 *  @name DataTable.defaults.language
-		 */
-		"oLanguage": {
-			/**
-			 * Strings that are used for WAI-ARIA labels and controls only (these are not
-			 * actually visible on the page, but will be read by screenreaders, and thus
-			 * must be internationalised as well).
-			 *  @namespace
-			 *  @name DataTable.defaults.language.aria
-			 */
-			"oAria": {
-				/**
-				 * ARIA label that is added to the table headers when the column may be
-				 * sorted ascending by activing the column (click or return when focused).
-				 * Note that the column header is prefixed to this string.
-				 *  @type string
-				 *  @default : activate to sort column ascending
-				 *
-				 *  @dtopt Language
-				 *  @name DataTable.defaults.language.aria.sortAscending
-				 *
-				 *  @example
-				 *    $(document).ready( function() {
-				 *      $('#example').dataTable( {
-				 *        "language": {
-				 *          "aria": {
-				 *            "sortAscending": " - click/return to sort ascending"
-				 *          }
-				 *        }
-				 *      } );
-				 *    } );
-				 */
-				"sSortAscending": ": activate to sort column ascending",
-	
-				/**
-				 * ARIA label that is added to the table headers when the column may be
-				 * sorted descending by activing the column (click or return when focused).
-				 * Note that the column header is prefixed to this string.
-				 *  @type string
-				 *  @default : activate to sort column ascending
-				 *
-				 *  @dtopt Language
-				 *  @name DataTable.defaults.language.aria.sortDescending
-				 *
-				 *  @example
-				 *    $(document).ready( function() {
-				 *      $('#example').dataTable( {
-				 *        "language": {
-				 *          "aria": {
-				 *            "sortDescending": " - click/return to sort descending"
-				 *          }
-				 *        }
-				 *      } );
-				 *    } );
-				 */
-				"sSortDescending": ": activate to sort column descending"
-			},
-	
-			/**
-			 * Pagination string used by DataTables for the built-in pagination
-			 * control types.
-			 *  @namespace
-			 *  @name DataTable.defaults.language.paginate
-			 */
-			"oPaginate": {
-				/**
-				 * Text to use when using the 'full_numbers' type of pagination for the
-				 * button to take the user to the first page.
-				 *  @type string
-				 *  @default First
-				 *
-				 *  @dtopt Language
-				 *  @name DataTable.defaults.language.paginate.first
-				 *
-				 *  @example
-				 *    $(document).ready( function() {
-				 *      $('#example').dataTable( {
-				 *        "language": {
-				 *          "paginate": {
-				 *            "first": "First page"
-				 *          }
-				 *        }
-				 *      } );
-				 *    } );
-				 */
-				"sFirst": "First",
-	
-	
-				/**
-				 * Text to use when using the 'full_numbers' type of pagination for the
-				 * button to take the user to the last page.
-				 *  @type string
-				 *  @default Last
-				 *
-				 *  @dtopt Language
-				 *  @name DataTable.defaults.language.paginate.last
-				 *
-				 *  @example
-				 *    $(document).ready( function() {
-				 *      $('#example').dataTable( {
-				 *        "language": {
-				 *          "paginate": {
-				 *            "last": "Last page"
-				 *          }
-				 *        }
-				 *      } );
-				 *    } );
-				 */
-				"sLast": "Last",
-	
-	
-				/**
-				 * Text to use for the 'next' pagination button (to take the user to the
-				 * next page).
-				 *  @type string
-				 *  @default Next
-				 *
-				 *  @dtopt Language
-				 *  @name DataTable.defaults.language.paginate.next
-				 *
-				 *  @example
-				 *    $(document).ready( function() {
-				 *      $('#example').dataTable( {
-				 *        "language": {
-				 *          "paginate": {
-				 *            "next": "Next page"
-				 *          }
-				 *        }
-				 *      } );
-				 *    } );
-				 */
-				"sNext": "Next",
-	
-	
-				/**
-				 * Text to use for the 'previous' pagination button (to take the user to
-				 * the previous page).
-				 *  @type string
-				 *  @default Previous
-				 *
-				 *  @dtopt Language
-				 *  @name DataTable.defaults.language.paginate.previous
-				 *
-				 *  @example
-				 *    $(document).ready( function() {
-				 *      $('#example').dataTable( {
-				 *        "language": {
-				 *          "paginate": {
-				 *            "previous": "Previous page"
-				 *          }
-				 *        }
-				 *      } );
-				 *    } );
-				 */
-				"sPrevious": "Previous"
-			},
-	
-			/**
-			 * This string is shown in preference to `zeroRecords` when the table is
-			 * empty of data (regardless of filtering). Note that this is an optional
-			 * parameter - if it is not given, the value of `zeroRecords` will be used
-			 * instead (either the default or given value).
-			 *  @type string
-			 *  @default No data available in table
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.emptyTable
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "emptyTable": "No data available in table"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sEmptyTable": "No data available in table",
-	
-	
-			/**
-			 * This string gives information to the end user about the information
-			 * that is current on display on the page. The following tokens can be
-			 * used in the string and will be dynamically replaced as the table
-			 * display updates. This tokens can be placed anywhere in the string, or
-			 * removed as needed by the language requires:
-			 *
-			 * * `\_START\_` - Display index of the first record on the current page
-			 * * `\_END\_` - Display index of the last record on the current page
-			 * * `\_TOTAL\_` - Number of records in the table after filtering
-			 * * `\_MAX\_` - Number of records in the table without filtering
-			 * * `\_PAGE\_` - Current page number
-			 * * `\_PAGES\_` - Total number of pages of data in the table
-			 *
-			 *  @type string
-			 *  @default Showing _START_ to _END_ of _TOTAL_ entries
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.info
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "info": "Showing page _PAGE_ of _PAGES_"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
-	
-	
-			/**
-			 * Display information string for when the table is empty. Typically the
-			 * format of this string should match `info`.
-			 *  @type string
-			 *  @default Showing 0 to 0 of 0 entries
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.infoEmpty
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "infoEmpty": "No entries to show"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sInfoEmpty": "Showing 0 to 0 of 0 entries",
-	
-	
-			/**
-			 * When a user filters the information in a table, this string is appended
-			 * to the information (`info`) to give an idea of how strong the filtering
-			 * is. The variable _MAX_ is dynamically updated.
-			 *  @type string
-			 *  @default (filtered from _MAX_ total entries)
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.infoFiltered
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "infoFiltered": " - filtering from _MAX_ records"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sInfoFiltered": "(filtered from _MAX_ total entries)",
-	
-	
-			/**
-			 * If can be useful to append extra information to the info string at times,
-			 * and this variable does exactly that. This information will be appended to
-			 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
-			 * being used) at all times.
-			 *  @type string
-			 *  @default <i>Empty string</i>
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.infoPostFix
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "infoPostFix": "All records shown are derived from real information."
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sInfoPostFix": "",
-	
-	
-			/**
-			 * This decimal place operator is a little different from the other
-			 * language options since DataTables doesn't output floating point
-			 * numbers, so it won't ever use this for display of a number. Rather,
-			 * what this parameter does is modify the sort methods of the table so
-			 * that numbers which are in a format which has a character other than
-			 * a period (`.`) as a decimal place will be sorted numerically.
-			 *
-			 * Note that numbers with different decimal places cannot be shown in
-			 * the same table and still be sortable, the table must be consistent.
-			 * However, multiple different tables on the page can use different
-			 * decimal place characters.
-			 *  @type string
-			 *  @default 
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.decimal
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "decimal": ","
-			 *          "thousands": "."
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sDecimal": "",
-	
-	
-			/**
-			 * DataTables has a build in number formatter (`formatNumber`) which is
-			 * used to format large numbers that are used in the table information.
-			 * By default a comma is used, but this can be trivially changed to any
-			 * character you wish with this parameter.
-			 *  @type string
-			 *  @default ,
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.thousands
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "thousands": "'"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sThousands": ",",
-	
-	
-			/**
-			 * Detail the action that will be taken when the drop down menu for the
-			 * pagination length option is changed. The '_MENU_' variable is replaced
-			 * with a default select list of 10, 25, 50 and 100, and can be replaced
-			 * with a custom select box if required.
-			 *  @type string
-			 *  @default Show _MENU_ entries
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.lengthMenu
-			 *
-			 *  @example
-			 *    // Language change only
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "lengthMenu": "Display _MENU_ records"
-			 *        }
-			 *      } );
-			 *    } );
-			 *
-			 *  @example
-			 *    // Language and options change
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "lengthMenu": 'Display <select>'+
-			 *            '<option value="10">10</option>'+
-			 *            '<option value="20">20</option>'+
-			 *            '<option value="30">30</option>'+
-			 *            '<option value="40">40</option>'+
-			 *            '<option value="50">50</option>'+
-			 *            '<option value="-1">All</option>'+
-			 *            '</select> records'
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sLengthMenu": "Show _MENU_ entries",
-	
-	
-			/**
-			 * When using Ajax sourced data and during the first draw when DataTables is
-			 * gathering the data, this message is shown in an empty row in the table to
-			 * indicate to the end user the the data is being loaded. Note that this
-			 * parameter is not used when loading data by server-side processing, just
-			 * Ajax sourced data with client-side processing.
-			 *  @type string
-			 *  @default Loading...
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.loadingRecords
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "loadingRecords": "Please wait - loading..."
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sLoadingRecords": "Loading...",
-	
-	
-			/**
-			 * Text which is displayed when the table is processing a user action
-			 * (usually a sort command or similar).
-			 *  @type string
-			 *  @default Processing...
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.processing
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "processing": "DataTables is currently busy"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sProcessing": "Processing...",
-	
-	
-			/**
-			 * Details the actions that will be taken when the user types into the
-			 * filtering input text box. The variable "_INPUT_", if used in the string,
-			 * is replaced with the HTML text box for the filtering input allowing
-			 * control over where it appears in the string. If "_INPUT_" is not given
-			 * then the input box is appended to the string automatically.
-			 *  @type string
-			 *  @default Search:
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.search
-			 *
-			 *  @example
-			 *    // Input text box will be appended at the end automatically
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "search": "Filter records:"
-			 *        }
-			 *      } );
-			 *    } );
-			 *
-			 *  @example
-			 *    // Specify where the filter should appear
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "search": "Apply filter _INPUT_ to table"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sSearch": "Search:",
-	
-	
-			/**
-			 * Assign a `placeholder` attribute to the search `input` element
-			 *  @type string
-			 *  @default 
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.searchPlaceholder
-			 */
-			"sSearchPlaceholder": "",
-	
-	
-			/**
-			 * All of the language information can be stored in a file on the
-			 * server-side, which DataTables will look up if this parameter is passed.
-			 * It must store the URL of the language file, which is in a JSON format,
-			 * and the object has the same properties as the oLanguage object in the
-			 * initialiser object (i.e. the above parameters). Please refer to one of
-			 * the example language files to see how this works in action.
-			 *  @type string
-			 *  @default <i>Empty string - i.e. disabled</i>
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.url
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sUrl": "",
-	
-	
-			/**
-			 * Text shown inside the table records when the is no information to be
-			 * displayed after filtering. `emptyTable` is shown when there is simply no
-			 * information in the table at all (regardless of filtering).
-			 *  @type string
-			 *  @default No matching records found
-			 *
-			 *  @dtopt Language
-			 *  @name DataTable.defaults.language.zeroRecords
-			 *
-			 *  @example
-			 *    $(document).ready( function() {
-			 *      $('#example').dataTable( {
-			 *        "language": {
-			 *          "zeroRecords": "No records to display"
-			 *        }
-			 *      } );
-			 *    } );
-			 */
-			"sZeroRecords": "No matching records found"
-		},
-	
-	
-		/**
-		 * This parameter allows you to have define the global filtering state at
-		 * initialisation time. As an object the `search` parameter must be
-		 * defined, but all other parameters are optional. When `regex` is true,
-		 * the search string will be treated as a regular expression, when false
-		 * (default) it will be treated as a straight string. When `smart`
-		 * DataTables will use it's smart filtering methods (to word match at
-		 * any point in the data), when false this will not be done.
-		 *  @namespace
-		 *  @extends DataTable.models.oSearch
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.search
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "search": {"search": "Initial search"}
-		 *      } );
-		 *    } )
-		 */
-		"oSearch": $.extend( {}, DataTable.models.oSearch ),
-	
-	
-		/**
-		 * __Deprecated__ The functionality provided by this parameter has now been
-		 * superseded by that provided through `ajax`, which should be used instead.
-		 *
-		 * By default DataTables will look for the property `data` (or `aaData` for
-		 * compatibility with DataTables 1.9-) when obtaining data from an Ajax
-		 * source or for server-side processing - this parameter allows that
-		 * property to be changed. You can use Javascript dotted object notation to
-		 * get a data source for multiple levels of nesting.
-		 *  @type string
-		 *  @default data
-		 *
-		 *  @dtopt Options
-		 *  @dtopt Server-side
-		 *  @name DataTable.defaults.ajaxDataProp
-		 *
-		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
-		 */
-		"sAjaxDataProp": "data",
-	
-	
-		/**
-		 * __Deprecated__ The functionality provided by this parameter has now been
-		 * superseded by that provided through `ajax`, which should be used instead.
-		 *
-		 * You can instruct DataTables to load data from an external
-		 * source using this parameter (use aData if you want to pass data in you
-		 * already have). Simply provide a url a JSON object can be obtained from.
-		 *  @type string
-		 *  @default null
-		 *
-		 *  @dtopt Options
-		 *  @dtopt Server-side
-		 *  @name DataTable.defaults.ajaxSource
-		 *
-		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
-		 */
-		"sAjaxSource": null,
-	
-	
-		/**
-		 * This initialisation variable allows you to specify exactly where in the
-		 * DOM you want DataTables to inject the various controls it adds to the page
-		 * (for example you might want the pagination controls at the top of the
-		 * table). DIV elements (with or without a custom class) can also be added to
-		 * aid styling. The follow syntax is used:
-		 *   <ul>
-		 *     <li>The following options are allowed:
-		 *       <ul>
-		 *         <li>'l' - Length changing</li>
-		 *         <li>'f' - Filtering input</li>
-		 *         <li>'t' - The table!</li>
-		 *         <li>'i' - Information</li>
-		 *         <li>'p' - Pagination</li>
-		 *         <li>'r' - pRocessing</li>
-		 *       </ul>
-		 *     </li>
-		 *     <li>The following constants are allowed:
-		 *       <ul>
-		 *         <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
-		 *         <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
-		 *       </ul>
-		 *     </li>
-		 *     <li>The following syntax is expected:
-		 *       <ul>
-		 *         <li>'&lt;' and '&gt;' - div elements</li>
-		 *         <li>'&lt;"class" and '&gt;' - div with a class</li>
-		 *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
-		 *       </ul>
-		 *     </li>
-		 *     <li>Examples:
-		 *       <ul>
-		 *         <li>'&lt;"wrapper"flipt&gt;'</li>
-		 *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
-		 *       </ul>
-		 *     </li>
-		 *   </ul>
-		 *  @type string
-		 *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
-		 *    <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.dom
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
-		 *      } );
-		 *    } );
-		 */
-		"sDom": "lfrtip",
-	
-	
-		/**
-		 * Search delay option. This will throttle full table searches that use the
-		 * DataTables provided search input element (it does not effect calls to
-		 * `dt-api search()`, providing a delay before the search is made.
-		 *  @type integer
-		 *  @default 0
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.searchDelay
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "searchDelay": 200
-		 *      } );
-		 *    } )
-		 */
-		"searchDelay": null,
-	
-	
-		/**
-		 * DataTables features six different built-in options for the buttons to
-		 * display for pagination control:
-		 *
-		 * * `numbers` - Page number buttons only
-		 * * `simple` - 'Previous' and 'Next' buttons only
-		 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
-		 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
-		 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
-		 * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
-		 *  
-		 * Further methods can be added using {@link DataTable.ext.oPagination}.
-		 *  @type string
-		 *  @default simple_numbers
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.pagingType
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "pagingType": "full_numbers"
-		 *      } );
-		 *    } )
-		 */
-		"sPaginationType": "simple_numbers",
-	
-	
-		/**
-		 * Enable horizontal scrolling. When a table is too wide to fit into a
-		 * certain layout, or you have a large number of columns in the table, you
-		 * can enable x-scrolling to show the table in a viewport, which can be
-		 * scrolled. This property can be `true` which will allow the table to
-		 * scroll horizontally when needed, or any CSS unit, or a number (in which
-		 * case it will be treated as a pixel measurement). Setting as simply `true`
-		 * is recommended.
-		 *  @type boolean|string
-		 *  @default <i>blank string - i.e. disabled</i>
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.scrollX
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "scrollX": true,
-		 *        "scrollCollapse": true
-		 *      } );
-		 *    } );
-		 */
-		"sScrollX": "",
-	
-	
-		/**
-		 * This property can be used to force a DataTable to use more width than it
-		 * might otherwise do when x-scrolling is enabled. For example if you have a
-		 * table which requires to be well spaced, this parameter is useful for
-		 * "over-sizing" the table, and thus forcing scrolling. This property can by
-		 * any CSS unit, or a number (in which case it will be treated as a pixel
-		 * measurement).
-		 *  @type string
-		 *  @default <i>blank string - i.e. disabled</i>
-		 *
-		 *  @dtopt Options
-		 *  @name DataTable.defaults.scrollXInner
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "scrollX": "100%",
-		 *        "scrollXInner": "110%"
-		 *      } );
-		 *    } );
-		 */
-		"sScrollXInner": "",
-	
-	
-		/**
-		 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
-		 * to the given height, and enable scrolling for any data which overflows the
-		 * current viewport. This can be used as an alternative to paging to display
-		 * a lot of data in a small area (although paging and scrolling can both be
-		 * enabled at the same time). This property can be any CSS unit, or a number
-		 * (in which case it will be treated as a pixel measurement).
-		 *  @type string
-		 *  @default <i>blank string - i.e. disabled</i>
-		 *
-		 *  @dtopt Features
-		 *  @name DataTable.defaults.scrollY
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "scrollY": "200px",
-		 *        "paginate": false
-		 *      } );
-		 *    } );
-		 */
-		"sScrollY": "",
-	
-	
-		/**
-		 * __Deprecated__ The functionality provided by this parameter has now been
-		 * superseded by that provided through `ajax`, which should be used instead.
-		 *
-		 * Set the HTTP method that is used to make the Ajax call for server-side
-		 * processing or Ajax sourced data.
-		 *  @type string
-		 *  @default GET
-		 *
-		 *  @dtopt Options
-		 *  @dtopt Server-side
-		 *  @name DataTable.defaults.serverMethod
-		 *
-		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
-		 */
-		"sServerMethod": "GET",
-	
-	
-		/**
-		 * DataTables makes use of renderers when displaying HTML elements for
-		 * a table. These renderers can be added or modified by plug-ins to
-		 * generate suitable mark-up for a site. For example the Bootstrap
-		 * integration plug-in for DataTables uses a paging button renderer to
-		 * display pagination buttons in the mark-up required by Bootstrap.
-		 *
-		 * For further information about the renderers available see
-		 * DataTable.ext.renderer
-		 *  @type string|object
-		 *  @default null
-		 *
-		 *  @name DataTable.defaults.renderer
-		 *
-		 */
-		"renderer": null,
-	
-	
-		/**
-		 * Set the data property name that DataTables should use to get a row's id
-		 * to set as the `id` property in the node.
-		 *  @type string
-		 *  @default DT_RowId
-		 *
-		 *  @name DataTable.defaults.rowId
-		 */
-		"rowId": "DT_RowId"
-	};
-	
-	_fnHungarianMap( DataTable.defaults );
-	
-	
-	
-	/*
-	 * Developer note - See note in model.defaults.js about the use of Hungarian
-	 * notation and camel case.
-	 */
-	
-	/**
-	 * Column options that can be given to DataTables at initialisation time.
-	 *  @namespace
-	 */
-	DataTable.defaults.column = {
-		/**
-		 * Define which column(s) an order will occur on for this column. This
-		 * allows a column's ordering to take multiple columns into account when
-		 * doing a sort or use the data from a different column. For example first
-		 * name / last name columns make sense to do a multi-column sort over the
-		 * two columns.
-		 *  @type array|int
-		 *  @default null <i>Takes the value of the column index automatically</i>
-		 *
-		 *  @name DataTable.defaults.column.orderData
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "orderData": [ 0, 1 ], "targets": [ 0 ] },
-		 *          { "orderData": [ 1, 0 ], "targets": [ 1 ] },
-		 *          { "orderData": 2, "targets": [ 2 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "orderData": [ 0, 1 ] },
-		 *          { "orderData": [ 1, 0 ] },
-		 *          { "orderData": 2 },
-		 *          null,
-		 *          null
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"aDataSort": null,
-		"iDataSort": -1,
-	
-	
-		/**
-		 * You can control the default ordering direction, and even alter the
-		 * behaviour of the sort handler (i.e. only allow ascending ordering etc)
-		 * using this parameter.
-		 *  @type array
-		 *  @default [ 'asc', 'desc' ]
-		 *
-		 *  @name DataTable.defaults.column.orderSequence
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "orderSequence": [ "asc" ], "targets": [ 1 ] },
-		 *          { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
-		 *          { "orderSequence": [ "desc" ], "targets": [ 3 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          null,
-		 *          { "orderSequence": [ "asc" ] },
-		 *          { "orderSequence": [ "desc", "asc", "asc" ] },
-		 *          { "orderSequence": [ "desc" ] },
-		 *          null
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"asSorting": [ 'asc', 'desc' ],
-	
-	
-		/**
-		 * Enable or disable filtering on the data in this column.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @name DataTable.defaults.column.searchable
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "searchable": false, "targets": [ 0 ] }
-		 *        ] } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "searchable": false },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ] } );
-		 *    } );
-		 */
-		"bSearchable": true,
-	
-	
-		/**
-		 * Enable or disable ordering on this column.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @name DataTable.defaults.column.orderable
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "orderable": false, "targets": [ 0 ] }
-		 *        ] } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "orderable": false },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ] } );
-		 *    } );
-		 */
-		"bSortable": true,
-	
-	
-		/**
-		 * Enable or disable the display of this column.
-		 *  @type boolean
-		 *  @default true
-		 *
-		 *  @name DataTable.defaults.column.visible
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "visible": false, "targets": [ 0 ] }
-		 *        ] } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "visible": false },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ] } );
-		 *    } );
-		 */
-		"bVisible": true,
-	
-	
-		/**
-		 * Developer definable function that is called whenever a cell is created (Ajax source,
-		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
-		 * allowing you to modify the DOM element (add background colour for example) when the
-		 * element is available.
-		 *  @type function
-		 *  @param {element} td The TD node that has been created
-		 *  @param {*} cellData The Data for the cell
-		 *  @param {array|object} rowData The data for the whole row
-		 *  @param {int} row The row index for the aoData data store
-		 *  @param {int} col The column index for aoColumns
-		 *
-		 *  @name DataTable.defaults.column.createdCell
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [3],
-		 *          "createdCell": function (td, cellData, rowData, row, col) {
-		 *            if ( cellData == "1.7" ) {
-		 *              $(td).css('color', 'blue')
-		 *            }
-		 *          }
-		 *        } ]
-		 *      });
-		 *    } );
-		 */
-		"fnCreatedCell": null,
-	
-	
-		/**
-		 * This parameter has been replaced by `data` in DataTables to ensure naming
-		 * consistency. `dataProp` can still be used, as there is backwards
-		 * compatibility in DataTables for this option, but it is strongly
-		 * recommended that you use `data` in preference to `dataProp`.
-		 *  @name DataTable.defaults.column.dataProp
-		 */
-	
-	
-		/**
-		 * This property can be used to read data from any data source property,
-		 * including deeply nested objects / properties. `data` can be given in a
-		 * number of different ways which effect its behaviour:
-		 *
-		 * * `integer` - treated as an array index for the data source. This is the
-		 *   default that DataTables uses (incrementally increased for each column).
-		 * * `string` - read an object property from the data source. There are
-		 *   three 'special' options that can be used in the string to alter how
-		 *   DataTables reads the data from the source object:
-		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
-		 *      Javascript to read from nested objects, so to can the options
-		 *      specified in `data`. For example: `browser.version` or
-		 *      `browser.name`. If your object parameter name contains a period, use
-		 *      `\\` to escape it - i.e. `first\\.name`.
-		 *    * `[]` - Array notation. DataTables can automatically combine data
-		 *      from and array source, joining the data with the characters provided
-		 *      between the two brackets. For example: `name[, ]` would provide a
-		 *      comma-space separated list from the source array. If no characters
-		 *      are provided between the brackets, the original array source is
-		 *      returned.
-		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
-		 *      execute a function of the name given. For example: `browser()` for a
-		 *      simple function on the data source, `browser.version()` for a
-		 *      function in a nested property or even `browser().version` to get an
-		 *      object property if the function called returns an object. Note that
-		 *      function notation is recommended for use in `render` rather than
-		 *      `data` as it is much simpler to use as a renderer.
-		 * * `null` - use the original data source for the row rather than plucking
-		 *   data directly from it. This action has effects on two other
-		 *   initialisation options:
-		 *    * `defaultContent` - When null is given as the `data` option and
-		 *      `defaultContent` is specified for the column, the value defined by
-		 *      `defaultContent` will be used for the cell.
-		 *    * `render` - When null is used for the `data` option and the `render`
-		 *      option is specified for the column, the whole data source for the
-		 *      row is used for the renderer.
-		 * * `function` - the function given will be executed whenever DataTables
-		 *   needs to set or get the data for a cell in the column. The function
-		 *   takes three parameters:
-		 *    * Parameters:
-		 *      * `{array|object}` The data source for the row
-		 *      * `{string}` The type call data requested - this will be 'set' when
-		 *        setting data or 'filter', 'display', 'type', 'sort' or undefined
-		 *        when gathering data. Note that when `undefined` is given for the
-		 *        type DataTables expects to get the raw data for the object back<
-		 *      * `{*}` Data to set when the second parameter is 'set'.
-		 *    * Return:
-		 *      * The return value from the function is not required when 'set' is
-		 *        the type of call, but otherwise the return is what will be used
-		 *        for the data requested.
-		 *
-		 * Note that `data` is a getter and setter option. If you just require
-		 * formatting of data for output, you will likely want to use `render` which
-		 * is simply a getter and thus simpler to use.
-		 *
-		 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
-		 * name change reflects the flexibility of this property and is consistent
-		 * with the naming of mRender. If 'mDataProp' is given, then it will still
-		 * be used by DataTables, as it automatically maps the old name to the new
-		 * if required.
-		 *
-		 *  @type string|int|function|null
-		 *  @default null <i>Use automatically calculated column index</i>
-		 *
-		 *  @name DataTable.defaults.column.data
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Read table data from objects
-		 *    // JSON structure for each row:
-		 *    //   {
-		 *    //      "engine": {value},
-		 *    //      "browser": {value},
-		 *    //      "platform": {value},
-		 *    //      "version": {value},
-		 *    //      "grade": {value}
-		 *    //   }
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "ajaxSource": "sources/objects.txt",
-		 *        "columns": [
-		 *          { "data": "engine" },
-		 *          { "data": "browser" },
-		 *          { "data": "platform" },
-		 *          { "data": "version" },
-		 *          { "data": "grade" }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Read information from deeply nested objects
-		 *    // JSON structure for each row:
-		 *    //   {
-		 *    //      "engine": {value},
-		 *    //      "browser": {value},
-		 *    //      "platform": {
-		 *    //         "inner": {value}
-		 *    //      },
-		 *    //      "details": [
-		 *    //         {value}, {value}
-		 *    //      ]
-		 *    //   }
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "ajaxSource": "sources/deep.txt",
-		 *        "columns": [
-		 *          { "data": "engine" },
-		 *          { "data": "browser" },
-		 *          { "data": "platform.inner" },
-		 *          { "data": "details.0" },
-		 *          { "data": "details.1" }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `data` as a function to provide different information for
-		 *    // sorting, filtering and display. In this case, currency (price)
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "data": function ( source, type, val ) {
-		 *            if (type === 'set') {
-		 *              source.price = val;
-		 *              // Store the computed dislay and filter values for efficiency
-		 *              source.price_display = val=="" ? "" : "$"+numberFormat(val);
-		 *              source.price_filter  = val=="" ? "" : "$"+numberFormat(val)+" "+val;
-		 *              return;
-		 *            }
-		 *            else if (type === 'display') {
-		 *              return source.price_display;
-		 *            }
-		 *            else if (type === 'filter') {
-		 *              return source.price_filter;
-		 *            }
-		 *            // 'sort', 'type' and undefined all just use the integer
-		 *            return source.price;
-		 *          }
-		 *        } ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using default content
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "data": null,
-		 *          "defaultContent": "Click to edit"
-		 *        } ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using array notation - outputting a list from an array
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "data": "name[, ]"
-		 *        } ]
-		 *      } );
-		 *    } );
-		 *
-		 */
-		"mData": null,
-	
-	
-		/**
-		 * This property is the rendering partner to `data` and it is suggested that
-		 * when you want to manipulate data for display (including filtering,
-		 * sorting etc) without altering the underlying data for the table, use this
-		 * property. `render` can be considered to be the the read only companion to
-		 * `data` which is read / write (then as such more complex). Like `data`
-		 * this option can be given in a number of different ways to effect its
-		 * behaviour:
-		 *
-		 * * `integer` - treated as an array index for the data source. This is the
-		 *   default that DataTables uses (incrementally increased for each column).
-		 * * `string` - read an object property from the data source. There are
-		 *   three 'special' options that can be used in the string to alter how
-		 *   DataTables reads the data from the source object:
-		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
-		 *      Javascript to read from nested objects, so to can the options
-		 *      specified in `data`. For example: `browser.version` or
-		 *      `browser.name`. If your object parameter name contains a period, use
-		 *      `\\` to escape it - i.e. `first\\.name`.
-		 *    * `[]` - Array notation. DataTables can automatically combine data
-		 *      from and array source, joining the data with the characters provided
-		 *      between the two brackets. For example: `name[, ]` would provide a
-		 *      comma-space separated list from the source array. If no characters
-		 *      are provided between the brackets, the original array source is
-		 *      returned.
-		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
-		 *      execute a function of the name given. For example: `browser()` for a
-		 *      simple function on the data source, `browser.version()` for a
-		 *      function in a nested property or even `browser().version` to get an
-		 *      object property if the function called returns an object.
-		 * * `object` - use different data for the different data types requested by
-		 *   DataTables ('filter', 'display', 'type' or 'sort'). The property names
-		 *   of the object is the data type the property refers to and the value can
-		 *   defined using an integer, string or function using the same rules as
-		 *   `render` normally does. Note that an `_` option _must_ be specified.
-		 *   This is the default value to use if you haven't specified a value for
-		 *   the data type requested by DataTables.
-		 * * `function` - the function given will be executed whenever DataTables
-		 *   needs to set or get the data for a cell in the column. The function
-		 *   takes three parameters:
-		 *    * Parameters:
-		 *      * {array|object} The data source for the row (based on `data`)
-		 *      * {string} The type call data requested - this will be 'filter',
-		 *        'display', 'type' or 'sort'.
-		 *      * {array|object} The full data source for the row (not based on
-		 *        `data`)
-		 *    * Return:
-		 *      * The return value from the function is what will be used for the
-		 *        data requested.
-		 *
-		 *  @type string|int|function|object|null
-		 *  @default null Use the data source value.
-		 *
-		 *  @name DataTable.defaults.column.render
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Create a comma separated list from an array of objects
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "ajaxSource": "sources/deep.txt",
-		 *        "columns": [
-		 *          { "data": "engine" },
-		 *          { "data": "browser" },
-		 *          {
-		 *            "data": "platform",
-		 *            "render": "[, ].name"
-		 *          }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Execute a function to obtain data
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "data": null, // Use the full data source object for the renderer's source
-		 *          "render": "browserName()"
-		 *        } ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // As an object, extracting different data for the different types
-		 *    // This would be used with a data source such as:
-		 *    //   { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
-		 *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
-		 *    // (which has both forms) is used for filtering for if a user inputs either format, while
-		 *    // the formatted phone number is the one that is shown in the table.
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "data": null, // Use the full data source object for the renderer's source
-		 *          "render": {
-		 *            "_": "phone",
-		 *            "filter": "phone_filter",
-		 *            "display": "phone_display"
-		 *          }
-		 *        } ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Use as a function to create a link from the data source
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "data": "download_link",
-		 *          "render": function ( data, type, full ) {
-		 *            return '<a href="'+data+'">Download</a>';
-		 *          }
-		 *        } ]
-		 *      } );
-		 *    } );
-		 */
-		"mRender": null,
-	
-	
-		/**
-		 * Change the cell type created for the column - either TD cells or TH cells. This
-		 * can be useful as TH cells have semantic meaning in the table body, allowing them
-		 * to act as a header for a row (you may wish to add scope='row' to the TH elements).
-		 *  @type string
-		 *  @default td
-		 *
-		 *  @name DataTable.defaults.column.cellType
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Make the first column use TH cells
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [ {
-		 *          "targets": [ 0 ],
-		 *          "cellType": "th"
-		 *        } ]
-		 *      } );
-		 *    } );
-		 */
-		"sCellType": "td",
-	
-	
-		/**
-		 * Class to give to each cell in this column.
-		 *  @type string
-		 *  @default <i>Empty string</i>
-		 *
-		 *  @name DataTable.defaults.column.class
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "class": "my_class", "targets": [ 0 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "class": "my_class" },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sClass": "",
-	
-		/**
-		 * When DataTables calculates the column widths to assign to each column,
-		 * it finds the longest string in each column and then constructs a
-		 * temporary table and reads the widths from that. The problem with this
-		 * is that "mmm" is much wider then "iiii", but the latter is a longer
-		 * string - thus the calculation can go wrong (doing it properly and putting
-		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
-		 * a "work around" we provide this option. It will append its value to the
-		 * text that is found to be the longest string for the column - i.e. padding.
-		 * Generally you shouldn't need this!
-		 *  @type string
-		 *  @default <i>Empty string<i>
-		 *
-		 *  @name DataTable.defaults.column.contentPadding
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          {
-		 *            "contentPadding": "mmm"
-		 *          }
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sContentPadding": "",
-	
-	
-		/**
-		 * Allows a default value to be given for a column's data, and will be used
-		 * whenever a null data source is encountered (this can be because `data`
-		 * is set to null, or because the data source itself is null).
-		 *  @type string
-		 *  @default null
-		 *
-		 *  @name DataTable.defaults.column.defaultContent
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          {
-		 *            "data": null,
-		 *            "defaultContent": "Edit",
-		 *            "targets": [ -1 ]
-		 *          }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          {
-		 *            "data": null,
-		 *            "defaultContent": "Edit"
-		 *          }
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sDefaultContent": null,
-	
-	
-		/**
-		 * This parameter is only used in DataTables' server-side processing. It can
-		 * be exceptionally useful to know what columns are being displayed on the
-		 * client side, and to map these to database fields. When defined, the names
-		 * also allow DataTables to reorder information from the server if it comes
-		 * back in an unexpected order (i.e. if you switch your columns around on the
-		 * client-side, your server-side code does not also need updating).
-		 *  @type string
-		 *  @default <i>Empty string</i>
-		 *
-		 *  @name DataTable.defaults.column.name
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "name": "engine", "targets": [ 0 ] },
-		 *          { "name": "browser", "targets": [ 1 ] },
-		 *          { "name": "platform", "targets": [ 2 ] },
-		 *          { "name": "version", "targets": [ 3 ] },
-		 *          { "name": "grade", "targets": [ 4 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "name": "engine" },
-		 *          { "name": "browser" },
-		 *          { "name": "platform" },
-		 *          { "name": "version" },
-		 *          { "name": "grade" }
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sName": "",
-	
-	
-		/**
-		 * Defines a data source type for the ordering which can be used to read
-		 * real-time information from the table (updating the internally cached
-		 * version) prior to ordering. This allows ordering to occur on user
-		 * editable elements such as form inputs.
-		 *  @type string
-		 *  @default std
-		 *
-		 *  @name DataTable.defaults.column.orderDataType
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
-		 *          { "type": "numeric", "targets": [ 3 ] },
-		 *          { "orderDataType": "dom-select", "targets": [ 4 ] },
-		 *          { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          null,
-		 *          null,
-		 *          { "orderDataType": "dom-text" },
-		 *          { "orderDataType": "dom-text", "type": "numeric" },
-		 *          { "orderDataType": "dom-select" },
-		 *          { "orderDataType": "dom-checkbox" }
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sSortDataType": "std",
-	
-	
-		/**
-		 * The title of this column.
-		 *  @type string
-		 *  @default null <i>Derived from the 'TH' value for this column in the
-		 *    original HTML table.</i>
-		 *
-		 *  @name DataTable.defaults.column.title
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "title": "My column title", "targets": [ 0 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "title": "My column title" },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sTitle": null,
-	
-	
-		/**
-		 * The type allows you to specify how the data for this column will be
-		 * ordered. Four types (string, numeric, date and html (which will strip
-		 * HTML tags before ordering)) are currently available. Note that only date
-		 * formats understood by Javascript's Date() object will be accepted as type
-		 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
-		 * 'numeric', 'date' or 'html' (by default). Further types can be adding
-		 * through plug-ins.
-		 *  @type string
-		 *  @default null <i>Auto-detected from raw data</i>
-		 *
-		 *  @name DataTable.defaults.column.type
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "type": "html", "targets": [ 0 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "type": "html" },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sType": null,
-	
-	
-		/**
-		 * Defining the width of the column, this parameter may take any CSS value
-		 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
-		 * been given a specific width through this interface ensuring that the table
-		 * remains readable.
-		 *  @type string
-		 *  @default null <i>Automatic</i>
-		 *
-		 *  @name DataTable.defaults.column.width
-		 *  @dtopt Columns
-		 *
-		 *  @example
-		 *    // Using `columnDefs`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columnDefs": [
-		 *          { "width": "20%", "targets": [ 0 ] }
-		 *        ]
-		 *      } );
-		 *    } );
-		 *
-		 *  @example
-		 *    // Using `columns`
-		 *    $(document).ready( function() {
-		 *      $('#example').dataTable( {
-		 *        "columns": [
-		 *          { "width": "20%" },
-		 *          null,
-		 *          null,
-		 *          null,
-		 *          null
-		 *        ]
-		 *      } );
-		 *    } );
-		 */
-		"sWidth": null
-	};
-	
-	_fnHungarianMap( DataTable.defaults.column );
-	
-	
-	
-	/**
-	 * DataTables settings object - this holds all the information needed for a
-	 * given table, including configuration, data and current application of the
-	 * table options. DataTables does not have a single instance for each DataTable
-	 * with the settings attached to that instance, but rather instances of the
-	 * DataTable "class" are created on-the-fly as needed (typically by a
-	 * $().dataTable() call) and the settings object is then applied to that
-	 * instance.
-	 *
-	 * Note that this object is related to {@link DataTable.defaults} but this
-	 * one is the internal data store for DataTables's cache of columns. It should
-	 * NOT be manipulated outside of DataTables. Any configuration should be done
-	 * through the initialisation options.
-	 *  @namespace
-	 *  @todo Really should attach the settings object to individual instances so we
-	 *    don't need to create new instances on each $().dataTable() call (if the
-	 *    table already exists). It would also save passing oSettings around and
-	 *    into every single function. However, this is a very significant
-	 *    architecture change for DataTables and will almost certainly break
-	 *    backwards compatibility with older installations. This is something that
-	 *    will be done in 2.0.
-	 */
-	DataTable.models.oSettings = {
-		/**
-		 * Primary features of DataTables and their enablement state.
-		 *  @namespace
-		 */
-		"oFeatures": {
-	
-			/**
-			 * Flag to say if DataTables should automatically try to calculate the
-			 * optimum table and columns widths (true) or not (false).
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bAutoWidth": null,
-	
-			/**
-			 * Delay the creation of TR and TD elements until they are actually
-			 * needed by a driven page draw. This can give a significant speed
-			 * increase for Ajax source and Javascript source data, but makes no
-			 * difference at all fro DOM and server-side processing tables.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bDeferRender": null,
-	
-			/**
-			 * Enable filtering on the table or not. Note that if this is disabled
-			 * then there is no filtering at all on the table, including fnFilter.
-			 * To just remove the filtering input use sDom and remove the 'f' option.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bFilter": null,
-	
-			/**
-			 * Table information element (the 'Showing x of y records' div) enable
-			 * flag.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bInfo": null,
-	
-			/**
-			 * Present a user control allowing the end user to change the page size
-			 * when pagination is enabled.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bLengthChange": null,
-	
-			/**
-			 * Pagination enabled or not. Note that if this is disabled then length
-			 * changing must also be disabled.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bPaginate": null,
-	
-			/**
-			 * Processing indicator enable flag whenever DataTables is enacting a
-			 * user request - typically an Ajax request for server-side processing.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bProcessing": null,
-	
-			/**
-			 * Server-side processing enabled flag - when enabled DataTables will
-			 * get all data from the server for every draw - there is no filtering,
-			 * sorting or paging done on the client-side.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bServerSide": null,
-	
-			/**
-			 * Sorting enablement flag.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bSort": null,
-	
-			/**
-			 * Multi-column sorting
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bSortMulti": null,
-	
-			/**
-			 * Apply a class to the columns which are being sorted to provide a
-			 * visual highlight or not. This can slow things down when enabled since
-			 * there is a lot of DOM interaction.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bSortClasses": null,
-	
-			/**
-			 * State saving enablement flag.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bStateSave": null
-		},
-	
-	
-		/**
-		 * Scrolling settings for a table.
-		 *  @namespace
-		 */
-		"oScroll": {
-			/**
-			 * When the table is shorter in height than sScrollY, collapse the
-			 * table container down to the height of the table (when true).
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type boolean
-			 */
-			"bCollapse": null,
-	
-			/**
-			 * Width of the scrollbar for the web-browser's platform. Calculated
-			 * during table initialisation.
-			 *  @type int
-			 *  @default 0
-			 */
-			"iBarWidth": 0,
-	
-			/**
-			 * Viewport width for horizontal scrolling. Horizontal scrolling is
-			 * disabled if an empty string.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type string
-			 */
-			"sX": null,
-	
-			/**
-			 * Width to expand the table to when using x-scrolling. Typically you
-			 * should not need to use this.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type string
-			 *  @deprecated
-			 */
-			"sXInner": null,
-	
-			/**
-			 * Viewport height for vertical scrolling. Vertical scrolling is disabled
-			 * if an empty string.
-			 * Note that this parameter will be set by the initialisation routine. To
-			 * set a default use {@link DataTable.defaults}.
-			 *  @type string
-			 */
-			"sY": null
-		},
-	
-		/**
-		 * Language information for the table.
-		 *  @namespace
-		 *  @extends DataTable.defaults.oLanguage
-		 */
-		"oLanguage": {
-			/**
-			 * Information callback function. See
-			 * {@link DataTable.defaults.fnInfoCallback}
-			 *  @type function
-			 *  @default null
-			 */
-			"fnInfoCallback": null
-		},
-	
-		/**
-		 * Browser support parameters
-		 *  @namespace
-		 */
-		"oBrowser": {
-			/**
-			 * Indicate if the browser incorrectly calculates width:100% inside a
-			 * scrolling element (IE6/7)
-			 *  @type boolean
-			 *  @default false
-			 */
-			"bScrollOversize": false,
-	
-			/**
-			 * Determine if the vertical scrollbar is on the right or left of the
-			 * scrolling container - needed for rtl language layout, although not
-			 * all browsers move the scrollbar (Safari).
-			 *  @type boolean
-			 *  @default false
-			 */
-			"bScrollbarLeft": false,
-	
-			/**
-			 * Flag for if `getBoundingClientRect` is fully supported or not
-			 *  @type boolean
-			 *  @default false
-			 */
-			"bBounding": false,
-	
-			/**
-			 * Browser scrollbar width
-			 *  @type integer
-			 *  @default 0
-			 */
-			"barWidth": 0
-		},
-	
-	
-		"ajax": null,
-	
-	
-		/**
-		 * Array referencing the nodes which are used for the features. The
-		 * parameters of this object match what is allowed by sDom - i.e.
-		 *   <ul>
-		 *     <li>'l' - Length changing</li>
-		 *     <li>'f' - Filtering input</li>
-		 *     <li>'t' - The table!</li>
-		 *     <li>'i' - Information</li>
-		 *     <li>'p' - Pagination</li>
-		 *     <li>'r' - pRocessing</li>
-		 *   </ul>
-		 *  @type array
-		 *  @default []
-		 */
-		"aanFeatures": [],
-	
-		/**
-		 * Store data information - see {@link DataTable.models.oRow} for detailed
-		 * information.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoData": [],
-	
-		/**
-		 * Array of indexes which are in the current display (after filtering etc)
-		 *  @type array
-		 *  @default []
-		 */
-		"aiDisplay": [],
-	
-		/**
-		 * Array of indexes for display - no filtering
-		 *  @type array
-		 *  @default []
-		 */
-		"aiDisplayMaster": [],
-	
-		/**
-		 * Map of row ids to data indexes
-		 *  @type object
-		 *  @default {}
-		 */
-		"aIds": {},
-	
-		/**
-		 * Store information about each column that is in use
-		 *  @type array
-		 *  @default []
-		 */
-		"aoColumns": [],
-	
-		/**
-		 * Store information about the table's header
-		 *  @type array
-		 *  @default []
-		 */
-		"aoHeader": [],
-	
-		/**
-		 * Store information about the table's footer
-		 *  @type array
-		 *  @default []
-		 */
-		"aoFooter": [],
-	
-		/**
-		 * Store the applied global search information in case we want to force a
-		 * research or compare the old search to a new one.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @namespace
-		 *  @extends DataTable.models.oSearch
-		 */
-		"oPreviousSearch": {},
-	
-		/**
-		 * Store the applied search for each column - see
-		 * {@link DataTable.models.oSearch} for the format that is used for the
-		 * filtering information for each column.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoPreSearchCols": [],
-	
-		/**
-		 * Sorting that is applied to the table. Note that the inner arrays are
-		 * used in the following manner:
-		 * <ul>
-		 *   <li>Index 0 - column number</li>
-		 *   <li>Index 1 - current sorting direction</li>
-		 * </ul>
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type array
-		 *  @todo These inner arrays should really be objects
-		 */
-		"aaSorting": null,
-	
-		/**
-		 * Sorting that is always applied to the table (i.e. prefixed in front of
-		 * aaSorting).
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type array
-		 *  @default []
-		 */
-		"aaSortingFixed": [],
-	
-		/**
-		 * Classes to use for the striping of a table.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type array
-		 *  @default []
-		 */
-		"asStripeClasses": null,
-	
-		/**
-		 * If restoring a table - we should restore its striping classes as well
-		 *  @type array
-		 *  @default []
-		 */
-		"asDestroyStripes": [],
-	
-		/**
-		 * If restoring a table - we should restore its width
-		 *  @type int
-		 *  @default 0
-		 */
-		"sDestroyWidth": 0,
-	
-		/**
-		 * Callback functions array for every time a row is inserted (i.e. on a draw).
-		 *  @type array
-		 *  @default []
-		 */
-		"aoRowCallback": [],
-	
-		/**
-		 * Callback functions for the header on each draw.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoHeaderCallback": [],
-	
-		/**
-		 * Callback function for the footer on each draw.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoFooterCallback": [],
-	
-		/**
-		 * Array of callback functions for draw callback functions
-		 *  @type array
-		 *  @default []
-		 */
-		"aoDrawCallback": [],
-	
-		/**
-		 * Array of callback functions for row created function
-		 *  @type array
-		 *  @default []
-		 */
-		"aoRowCreatedCallback": [],
-	
-		/**
-		 * Callback functions for just before the table is redrawn. A return of
-		 * false will be used to cancel the draw.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoPreDrawCallback": [],
-	
-		/**
-		 * Callback functions for when the table has been initialised.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoInitComplete": [],
-	
-	
-		/**
-		 * Callbacks for modifying the settings to be stored for state saving, prior to
-		 * saving state.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoStateSaveParams": [],
-	
-		/**
-		 * Callbacks for modifying the settings that have been stored for state saving
-		 * prior to using the stored values to restore the state.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoStateLoadParams": [],
-	
-		/**
-		 * Callbacks for operating on the settings object once the saved state has been
-		 * loaded
-		 *  @type array
-		 *  @default []
-		 */
-		"aoStateLoaded": [],
-	
-		/**
-		 * Cache the table ID for quick access
-		 *  @type string
-		 *  @default <i>Empty string</i>
-		 */
-		"sTableId": "",
-	
-		/**
-		 * The TABLE node for the main table
-		 *  @type node
-		 *  @default null
-		 */
-		"nTable": null,
-	
-		/**
-		 * Permanent ref to the thead element
-		 *  @type node
-		 *  @default null
-		 */
-		"nTHead": null,
-	
-		/**
-		 * Permanent ref to the tfoot element - if it exists
-		 *  @type node
-		 *  @default null
-		 */
-		"nTFoot": null,
-	
-		/**
-		 * Permanent ref to the tbody element
-		 *  @type node
-		 *  @default null
-		 */
-		"nTBody": null,
-	
-		/**
-		 * Cache the wrapper node (contains all DataTables controlled elements)
-		 *  @type node
-		 *  @default null
-		 */
-		"nTableWrapper": null,
-	
-		/**
-		 * Indicate if when using server-side processing the loading of data
-		 * should be deferred until the second draw.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type boolean
-		 *  @default false
-		 */
-		"bDeferLoading": false,
-	
-		/**
-		 * Indicate if all required information has been read in
-		 *  @type boolean
-		 *  @default false
-		 */
-		"bInitialised": false,
-	
-		/**
-		 * Information about open rows. Each object in the array has the parameters
-		 * 'nTr' and 'nParent'
-		 *  @type array
-		 *  @default []
-		 */
-		"aoOpenRows": [],
-	
-		/**
-		 * Dictate the positioning of DataTables' control elements - see
-		 * {@link DataTable.model.oInit.sDom}.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type string
-		 *  @default null
-		 */
-		"sDom": null,
-	
-		/**
-		 * Search delay (in mS)
-		 *  @type integer
-		 *  @default null
-		 */
-		"searchDelay": null,
-	
-		/**
-		 * Which type of pagination should be used.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type string
-		 *  @default two_button
-		 */
-		"sPaginationType": "two_button",
-	
-		/**
-		 * The state duration (for `stateSave`) in seconds.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type int
-		 *  @default 0
-		 */
-		"iStateDuration": 0,
-	
-		/**
-		 * Array of callback functions for state saving. Each array element is an
-		 * object with the following parameters:
-		 *   <ul>
-		 *     <li>function:fn - function to call. Takes two parameters, oSettings
-		 *       and the JSON string to save that has been thus far created. Returns
-		 *       a JSON string to be inserted into a json object
-		 *       (i.e. '"param": [ 0, 1, 2]')</li>
-		 *     <li>string:sName - name of callback</li>
-		 *   </ul>
-		 *  @type array
-		 *  @default []
-		 */
-		"aoStateSave": [],
-	
-		/**
-		 * Array of callback functions for state loading. Each array element is an
-		 * object with the following parameters:
-		 *   <ul>
-		 *     <li>function:fn - function to call. Takes two parameters, oSettings
-		 *       and the object stored. May return false to cancel state loading</li>
-		 *     <li>string:sName - name of callback</li>
-		 *   </ul>
-		 *  @type array
-		 *  @default []
-		 */
-		"aoStateLoad": [],
-	
-		/**
-		 * State that was saved. Useful for back reference
-		 *  @type object
-		 *  @default null
-		 */
-		"oSavedState": null,
-	
-		/**
-		 * State that was loaded. Useful for back reference
-		 *  @type object
-		 *  @default null
-		 */
-		"oLoadedState": null,
-	
-		/**
-		 * Source url for AJAX data for the table.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type string
-		 *  @default null
-		 */
-		"sAjaxSource": null,
-	
-		/**
-		 * Property from a given object from which to read the table data from. This
-		 * can be an empty string (when not server-side processing), in which case
-		 * it is  assumed an an array is given directly.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type string
-		 */
-		"sAjaxDataProp": null,
-	
-		/**
-		 * Note if draw should be blocked while getting data
-		 *  @type boolean
-		 *  @default true
-		 */
-		"bAjaxDataGet": true,
-	
-		/**
-		 * The last jQuery XHR object that was used for server-side data gathering.
-		 * This can be used for working with the XHR information in one of the
-		 * callbacks
-		 *  @type object
-		 *  @default null
-		 */
-		"jqXHR": null,
-	
-		/**
-		 * JSON returned from the server in the last Ajax request
-		 *  @type object
-		 *  @default undefined
-		 */
-		"json": undefined,
-	
-		/**
-		 * Data submitted as part of the last Ajax request
-		 *  @type object
-		 *  @default undefined
-		 */
-		"oAjaxData": undefined,
-	
-		/**
-		 * Function to get the server-side data.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type function
-		 */
-		"fnServerData": null,
-	
-		/**
-		 * Functions which are called prior to sending an Ajax request so extra
-		 * parameters can easily be sent to the server
-		 *  @type array
-		 *  @default []
-		 */
-		"aoServerParams": [],
-	
-		/**
-		 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
-		 * required).
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type string
-		 */
-		"sServerMethod": null,
-	
-		/**
-		 * Format numbers for display.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type function
-		 */
-		"fnFormatNumber": null,
-	
-		/**
-		 * List of options that can be used for the user selectable length menu.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type array
-		 *  @default []
-		 */
-		"aLengthMenu": null,
-	
-		/**
-		 * Counter for the draws that the table does. Also used as a tracker for
-		 * server-side processing
-		 *  @type int
-		 *  @default 0
-		 */
-		"iDraw": 0,
-	
-		/**
-		 * Indicate if a redraw is being done - useful for Ajax
-		 *  @type boolean
-		 *  @default false
-		 */
-		"bDrawing": false,
-	
-		/**
-		 * Draw index (iDraw) of the last error when parsing the returned data
-		 *  @type int
-		 *  @default -1
-		 */
-		"iDrawError": -1,
-	
-		/**
-		 * Paging display length
-		 *  @type int
-		 *  @default 10
-		 */
-		"_iDisplayLength": 10,
-	
-		/**
-		 * Paging start point - aiDisplay index
-		 *  @type int
-		 *  @default 0
-		 */
-		"_iDisplayStart": 0,
-	
-		/**
-		 * Server-side processing - number of records in the result set
-		 * (i.e. before filtering), Use fnRecordsTotal rather than
-		 * this property to get the value of the number of records, regardless of
-		 * the server-side processing setting.
-		 *  @type int
-		 *  @default 0
-		 *  @private
-		 */
-		"_iRecordsTotal": 0,
-	
-		/**
-		 * Server-side processing - number of records in the current display set
-		 * (i.e. after filtering). Use fnRecordsDisplay rather than
-		 * this property to get the value of the number of records, regardless of
-		 * the server-side processing setting.
-		 *  @type boolean
-		 *  @default 0
-		 *  @private
-		 */
-		"_iRecordsDisplay": 0,
-	
-		/**
-		 * The classes to use for the table
-		 *  @type object
-		 *  @default {}
-		 */
-		"oClasses": {},
-	
-		/**
-		 * Flag attached to the settings object so you can check in the draw
-		 * callback if filtering has been done in the draw. Deprecated in favour of
-		 * events.
-		 *  @type boolean
-		 *  @default false
-		 *  @deprecated
-		 */
-		"bFiltered": false,
-	
-		/**
-		 * Flag attached to the settings object so you can check in the draw
-		 * callback if sorting has been done in the draw. Deprecated in favour of
-		 * events.
-		 *  @type boolean
-		 *  @default false
-		 *  @deprecated
-		 */
-		"bSorted": false,
-	
-		/**
-		 * Indicate that if multiple rows are in the header and there is more than
-		 * one unique cell per column, if the top one (true) or bottom one (false)
-		 * should be used for sorting / title by DataTables.
-		 * Note that this parameter will be set by the initialisation routine. To
-		 * set a default use {@link DataTable.defaults}.
-		 *  @type boolean
-		 */
-		"bSortCellsTop": null,
-	
-		/**
-		 * Initialisation object that is used for the table
-		 *  @type object
-		 *  @default null
-		 */
-		"oInit": null,
-	
-		/**
-		 * Destroy callback functions - for plug-ins to attach themselves to the
-		 * destroy so they can clean up markup and events.
-		 *  @type array
-		 *  @default []
-		 */
-		"aoDestroyCallback": [],
-	
-	
-		/**
-		 * Get the number of records in the current record set, before filtering
-		 *  @type function
-		 */
-		"fnRecordsTotal": function ()
-		{
-			return _fnDataSource( this ) == 'ssp' ?
-				this._iRecordsTotal * 1 :
-				this.aiDisplayMaster.length;
-		},
-	
-		/**
-		 * Get the number of records in the current record set, after filtering
-		 *  @type function
-		 */
-		"fnRecordsDisplay": function ()
-		{
-			return _fnDataSource( this ) == 'ssp' ?
-				this._iRecordsDisplay * 1 :
-				this.aiDisplay.length;
-		},
-	
-		/**
-		 * Get the display end point - aiDisplay index
-		 *  @type function
-		 */
-		"fnDisplayEnd": function ()
-		{
-			var
-				len      = this._iDisplayLength,
-				start    = this._iDisplayStart,
-				calc     = start + len,
-				records  = this.aiDisplay.length,
-				features = this.oFeatures,
-				paginate = features.bPaginate;
-	
-			if ( features.bServerSide ) {
-				return paginate === false || len === -1 ?
-					start + records :
-					Math.min( start+len, this._iRecordsDisplay );
-			}
-			else {
-				return ! paginate || calc>records || len===-1 ?
-					records :
-					calc;
-			}
-		},
-	
-		/**
-		 * The DataTables object for this table
-		 *  @type object
-		 *  @default null
-		 */
-		"oInstance": null,
-	
-		/**
-		 * Unique identifier for each instance of the DataTables object. If there
-		 * is an ID on the table node, then it takes that value, otherwise an
-		 * incrementing internal counter is used.
-		 *  @type string
-		 *  @default null
-		 */
-		"sInstance": null,
-	
-		/**
-		 * tabindex attribute value that is added to DataTables control elements, allowing
-		 * keyboard navigation of the table and its controls.
-		 */
-		"iTabIndex": 0,
-	
-		/**
-		 * DIV container for the footer scrolling table if scrolling
-		 */
-		"nScrollHead": null,
-	
-		/**
-		 * DIV container for the footer scrolling table if scrolling
-		 */
-		"nScrollFoot": null,
-	
-		/**
-		 * Last applied sort
-		 *  @type array
-		 *  @default []
-		 */
-		"aLastSort": [],
-	
-		/**
-		 * Stored plug-in instances
-		 *  @type object
-		 *  @default {}
-		 */
-		"oPlugins": {},
-	
-		/**
-		 * Function used to get a row's id from the row's data
-		 *  @type function
-		 *  @default null
-		 */
-		"rowIdFn": null,
-	
-		/**
-		 * Data location where to store a row's id
-		 *  @type string
-		 *  @default null
-		 */
-		"rowId": null
-	};
-
-	/**
-	 * Extension object for DataTables that is used to provide all extension
-	 * options.
-	 *
-	 * Note that the `DataTable.ext` object is available through
-	 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
-	 * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
-	 *  @namespace
-	 *  @extends DataTable.models.ext
-	 */
-	
-	
-	/**
-	 * DataTables extensions
-	 * 
-	 * This namespace acts as a collection area for plug-ins that can be used to
-	 * extend DataTables capabilities. Indeed many of the build in methods
-	 * use this method to provide their own capabilities (sorting methods for
-	 * example).
-	 *
-	 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
-	 * reasons
-	 *
-	 *  @namespace
-	 */
-	DataTable.ext = _ext = {
-		/**
-		 * Buttons. For use with the Buttons extension for DataTables. This is
-		 * defined here so other extensions can define buttons regardless of load
-		 * order. It is _not_ used by DataTables core.
-		 *
-		 *  @type object
-		 *  @default {}
-		 */
-		buttons: {},
-	
-	
-		/**
-		 * Element class names
-		 *
-		 *  @type object
-		 *  @default {}
-		 */
-		classes: {},
-	
-	
-		/**
-		 * DataTables build type (expanded by the download builder)
-		 *
-		 *  @type string
-		 */
-		builder: "-source-",
-	
-	
-		/**
-		 * Error reporting.
-		 * 
-		 * How should DataTables report an error. Can take the value 'alert',
-		 * 'throw', 'none' or a function.
-		 *
-		 *  @type string|function
-		 *  @default alert
-		 */
-		errMode: "alert",
-	
-	
-		/**
-		 * Feature plug-ins.
-		 * 
-		 * This is an array of objects which describe the feature plug-ins that are
-		 * available to DataTables. These feature plug-ins are then available for
-		 * use through the `dom` initialisation option.
-		 * 
-		 * Each feature plug-in is described by an object which must have the
-		 * following properties:
-		 * 
-		 * * `fnInit` - function that is used to initialise the plug-in,
-		 * * `cFeature` - a character so the feature can be enabled by the `dom`
-		 *   instillation option. This is case sensitive.
-		 *
-		 * The `fnInit` function has the following input parameters:
-		 *
-		 * 1. `{object}` DataTables settings object: see
-		 *    {@link DataTable.models.oSettings}
-		 *
-		 * And the following return is expected:
-		 * 
-		 * * {node|null} The element which contains your feature. Note that the
-		 *   return may also be void if your plug-in does not require to inject any
-		 *   DOM elements into DataTables control (`dom`) - for example this might
-		 *   be useful when developing a plug-in which allows table control via
-		 *   keyboard entry
-		 *
-		 *  @type array
-		 *
-		 *  @example
-		 *    $.fn.dataTable.ext.features.push( {
-		 *      "fnInit": function( oSettings ) {
-		 *        return new TableTools( { "oDTSettings": oSettings } );
-		 *      },
-		 *      "cFeature": "T"
-		 *    } );
-		 */
-		feature: [],
-	
-	
-		/**
-		 * Row searching.
-		 * 
-		 * This method of searching is complimentary to the default type based
-		 * searching, and a lot more comprehensive as it allows you complete control
-		 * over the searching logic. Each element in this array is a function
-		 * (parameters described below) that is called for every row in the table,
-		 * and your logic decides if it should be included in the searching data set
-		 * or not.
-		 *
-		 * Searching functions have the following input parameters:
-		 *
-		 * 1. `{object}` DataTables settings object: see
-		 *    {@link DataTable.models.oSettings}
-		 * 2. `{array|object}` Data for the row to be processed (same as the
-		 *    original format that was passed in as the data source, or an array
-		 *    from a DOM data source
-		 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
-		 *    can be useful to retrieve the `TR` element if you need DOM interaction.
-		 *
-		 * And the following return is expected:
-		 *
-		 * * {boolean} Include the row in the searched result set (true) or not
-		 *   (false)
-		 *
-		 * Note that as with the main search ability in DataTables, technically this
-		 * is "filtering", since it is subtractive. However, for consistency in
-		 * naming we call it searching here.
-		 *
-		 *  @type array
-		 *  @default []
-		 *
-		 *  @example
-		 *    // The following example shows custom search being applied to the
-		 *    // fourth column (i.e. the data[3] index) based on two input values
-		 *    // from the end-user, matching the data in a certain range.
-		 *    $.fn.dataTable.ext.search.push(
-		 *      function( settings, data, dataIndex ) {
-		 *        var min = document.getElementById('min').value * 1;
-		 *        var max = document.getElementById('max').value * 1;
-		 *        var version = data[3] == "-" ? 0 : data[3]*1;
-		 *
-		 *        if ( min == "" && max == "" ) {
-		 *          return true;
-		 *        }
-		 *        else if ( min == "" && version < max ) {
-		 *          return true;
-		 *        }
-		 *        else if ( min < version && "" == max ) {
-		 *          return true;
-		 *        }
-		 *        else if ( min < version && version < max ) {
-		 *          return true;
-		 *        }
-		 *        return false;
-		 *      }
-		 *    );
-		 */
-		search: [],
-	
-	
-		/**
-		 * Selector extensions
-		 *
-		 * The `selector` option can be used to extend the options available for the
-		 * selector modifier options (`selector-modifier` object data type) that
-		 * each of the three built in selector types offer (row, column and cell +
-		 * their plural counterparts). For example the Select extension uses this
-		 * mechanism to provide an option to select only rows, columns and cells
-		 * that have been marked as selected by the end user (`{selected: true}`),
-		 * which can be used in conjunction with the existing built in selector
-		 * options.
-		 *
-		 * Each property is an array to which functions can be pushed. The functions
-		 * take three attributes:
-		 *
-		 * * Settings object for the host table
-		 * * Options object (`selector-modifier` object type)
-		 * * Array of selected item indexes
-		 *
-		 * The return is an array of the resulting item indexes after the custom
-		 * selector has been applied.
-		 *
-		 *  @type object
-		 */
-		selector: {
-			cell: [],
-			column: [],
-			row: []
-		},
-	
-	
-		/**
-		 * Internal functions, exposed for used in plug-ins.
-		 * 
-		 * Please note that you should not need to use the internal methods for
-		 * anything other than a plug-in (and even then, try to avoid if possible).
-		 * The internal function may change between releases.
-		 *
-		 *  @type object
-		 *  @default {}
-		 */
-		internal: {},
-	
-	
-		/**
-		 * Legacy configuration options. Enable and disable legacy options that
-		 * are available in DataTables.
-		 *
-		 *  @type object
-		 */
-		legacy: {
-			/**
-			 * Enable / disable DataTables 1.9 compatible server-side processing
-			 * requests
-			 *
-			 *  @type boolean
-			 *  @default null
-			 */
-			ajax: null
-		},
-	
-	
-		/**
-		 * Pagination plug-in methods.
-		 * 
-		 * Each entry in this object is a function and defines which buttons should
-		 * be shown by the pagination rendering method that is used for the table:
-		 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
-		 * buttons are displayed in the document, while the functions here tell it
-		 * what buttons to display. This is done by returning an array of button
-		 * descriptions (what each button will do).
-		 *
-		 * Pagination types (the four built in options and any additional plug-in
-		 * options defined here) can be used through the `paginationType`
-		 * initialisation parameter.
-		 *
-		 * The functions defined take two parameters:
-		 *
-		 * 1. `{int} page` The current page index
-		 * 2. `{int} pages` The number of pages in the table
-		 *
-		 * Each function is expected to return an array where each element of the
-		 * array can be one of:
-		 *
-		 * * `first` - Jump to first page when activated
-		 * * `last` - Jump to last page when activated
-		 * * `previous` - Show previous page when activated
-		 * * `next` - Show next page when activated
-		 * * `{int}` - Show page of the index given
-		 * * `{array}` - A nested array containing the above elements to add a
-		 *   containing 'DIV' element (might be useful for styling).
-		 *
-		 * Note that DataTables v1.9- used this object slightly differently whereby
-		 * an object with two functions would be defined for each plug-in. That
-		 * ability is still supported by DataTables 1.10+ to provide backwards
-		 * compatibility, but this option of use is now decremented and no longer
-		 * documented in DataTables 1.10+.
-		 *
-		 *  @type object
-		 *  @default {}
-		 *
-		 *  @example
-		 *    // Show previous, next and current page buttons only
-		 *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
-		 *      return [ 'previous', page, 'next' ];
-		 *    };
-		 */
-		pager: {},
-	
-	
-		renderer: {
-			pageButton: {},
-			header: {}
-		},
-	
-	
-		/**
-		 * Ordering plug-ins - custom data source
-		 * 
-		 * The extension options for ordering of data available here is complimentary
-		 * to the default type based ordering that DataTables typically uses. It
-		 * allows much greater control over the the data that is being used to
-		 * order a column, but is necessarily therefore more complex.
-		 * 
-		 * This type of ordering is useful if you want to do ordering based on data
-		 * live from the DOM (for example the contents of an 'input' element) rather
-		 * than just the static string that DataTables knows of.
-		 * 
-		 * The way these plug-ins work is that you create an array of the values you
-		 * wish to be ordering for the column in question and then return that
-		 * array. The data in the array much be in the index order of the rows in
-		 * the table (not the currently ordering order!). Which order data gathering
-		 * function is run here depends on the `dt-init columns.orderDataType`
-		 * parameter that is used for the column (if any).
-		 *
-		 * The functions defined take two parameters:
-		 *
-		 * 1. `{object}` DataTables settings object: see
-		 *    {@link DataTable.models.oSettings}
-		 * 2. `{int}` Target column index
-		 *
-		 * Each function is expected to return an array:
-		 *
-		 * * `{array}` Data for the column to be ordering upon
-		 *
-		 *  @type array
-		 *
-		 *  @example
-		 *    // Ordering using `input` node values
-		 *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
-		 *    {
-		 *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
-		 *        return $('input', td).val();
-		 *      } );
-		 *    }
-		 */
-		order: {},
-	
-	
-		/**
-		 * Type based plug-ins.
-		 *
-		 * Each column in DataTables has a type assigned to it, either by automatic
-		 * detection or by direct assignment using the `type` option for the column.
-		 * The type of a column will effect how it is ordering and search (plug-ins
-		 * can also make use of the column type if required).
-		 *
-		 * @namespace
-		 */
-		type: {
-			/**
-			 * Type detection functions.
-			 *
-			 * The functions defined in this object are used to automatically detect
-			 * a column's type, making initialisation of DataTables super easy, even
-			 * when complex data is in the table.
-			 *
-			 * The functions defined take two parameters:
-			 *
-		     *  1. `{*}` Data from the column cell to be analysed
-		     *  2. `{settings}` DataTables settings object. This can be used to
-		     *     perform context specific type detection - for example detection
-		     *     based on language settings such as using a comma for a decimal
-		     *     place. Generally speaking the options from the settings will not
-		     *     be required
-			 *
-			 * Each function is expected to return:
-			 *
-			 * * `{string|null}` Data type detected, or null if unknown (and thus
-			 *   pass it on to the other type detection functions.
-			 *
-			 *  @type array
-			 *
-			 *  @example
-			 *    // Currency type detection plug-in:
-			 *    $.fn.dataTable.ext.type.detect.push(
-			 *      function ( data, settings ) {
-			 *        // Check the numeric part
-			 *        if ( ! data.substring(1).match(/[0-9]/) ) {
-			 *          return null;
-			 *        }
-			 *
-			 *        // Check prefixed by currency
-			 *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
-			 *          return 'currency';
-			 *        }
-			 *        return null;
-			 *      }
-			 *    );
-			 */
-			detect: [],
-	
-	
-			/**
-			 * Type based search formatting.
-			 *
-			 * The type based searching functions can be used to pre-format the
-			 * data to be search on. For example, it can be used to strip HTML
-			 * tags or to de-format telephone numbers for numeric only searching.
-			 *
-			 * Note that is a search is not defined for a column of a given type,
-			 * no search formatting will be performed.
-			 * 
-			 * Pre-processing of searching data plug-ins - When you assign the sType
-			 * for a column (or have it automatically detected for you by DataTables
-			 * or a type detection plug-in), you will typically be using this for
-			 * custom sorting, but it can also be used to provide custom searching
-			 * by allowing you to pre-processing the data and returning the data in
-			 * the format that should be searched upon. This is done by adding
-			 * functions this object with a parameter name which matches the sType
-			 * for that target column. This is the corollary of <i>afnSortData</i>
-			 * for searching data.
-			 *
-			 * The functions defined take a single parameter:
-			 *
-		     *  1. `{*}` Data from the column cell to be prepared for searching
-			 *
-			 * Each function is expected to return:
-			 *
-			 * * `{string|null}` Formatted string that will be used for the searching.
-			 *
-			 *  @type object
-			 *  @default {}
-			 *
-			 *  @example
-			 *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
-			 *      return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
-			 *    }
-			 */
-			search: {},
-	
-	
-			/**
-			 * Type based ordering.
-			 *
-			 * The column type tells DataTables what ordering to apply to the table
-			 * when a column is sorted upon. The order for each type that is defined,
-			 * is defined by the functions available in this object.
-			 *
-			 * Each ordering option can be described by three properties added to
-			 * this object:
-			 *
-			 * * `{type}-pre` - Pre-formatting function
-			 * * `{type}-asc` - Ascending order function
-			 * * `{type}-desc` - Descending order function
-			 *
-			 * All three can be used together, only `{type}-pre` or only
-			 * `{type}-asc` and `{type}-desc` together. It is generally recommended
-			 * that only `{type}-pre` is used, as this provides the optimal
-			 * implementation in terms of speed, although the others are provided
-			 * for compatibility with existing Javascript sort functions.
-			 *
-			 * `{type}-pre`: Functions defined take a single parameter:
-			 *
-		     *  1. `{*}` Data from the column cell to be prepared for ordering
-			 *
-			 * And return:
-			 *
-			 * * `{*}` Data to be sorted upon
-			 *
-			 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
-			 * functions, taking two parameters:
-			 *
-		     *  1. `{*}` Data to compare to the second parameter
-		     *  2. `{*}` Data to compare to the first parameter
-			 *
-			 * And returning:
-			 *
-			 * * `{*}` Ordering match: <0 if first parameter should be sorted lower
-			 *   than the second parameter, ===0 if the two parameters are equal and
-			 *   >0 if the first parameter should be sorted height than the second
-			 *   parameter.
-			 * 
-			 *  @type object
-			 *  @default {}
-			 *
-			 *  @example
-			 *    // Numeric ordering of formatted numbers with a pre-formatter
-			 *    $.extend( $.fn.dataTable.ext.type.order, {
-			 *      "string-pre": function(x) {
-			 *        a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
-			 *        return parseFloat( a );
-			 *      }
-			 *    } );
-			 *
-			 *  @example
-			 *    // Case-sensitive string ordering, with no pre-formatting method
-			 *    $.extend( $.fn.dataTable.ext.order, {
-			 *      "string-case-asc": function(x,y) {
-			 *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
-			 *      },
-			 *      "string-case-desc": function(x,y) {
-			 *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
-			 *      }
-			 *    } );
-			 */
-			order: {}
-		},
-	
-		/**
-		 * Unique DataTables instance counter
-		 *
-		 * @type int
-		 * @private
-		 */
-		_unique: 0,
-	
-	
-		//
-		// Depreciated
-		// The following properties are retained for backwards compatiblity only.
-		// The should not be used in new projects and will be removed in a future
-		// version
-		//
-	
-		/**
-		 * Version check function.
-		 *  @type function
-		 *  @depreciated Since 1.10
-		 */
-		fnVersionCheck: DataTable.fnVersionCheck,
-	
-	
-		/**
-		 * Index for what 'this' index API functions should use
-		 *  @type int
-		 *  @deprecated Since v1.10
-		 */
-		iApiIndex: 0,
-	
-	
-		/**
-		 * jQuery UI class container
-		 *  @type object
-		 *  @deprecated Since v1.10
-		 */
-		oJUIClasses: {},
-	
-	
-		/**
-		 * Software version
-		 *  @type string
-		 *  @deprecated Since v1.10
-		 */
-		sVersion: DataTable.version
-	};
-	
-	
-	//
-	// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
-	//
-	$.extend( _ext, {
-		afnFiltering: _ext.search,
-		aTypes:       _ext.type.detect,
-		ofnSearch:    _ext.type.search,
-		oSort:        _ext.type.order,
-		afnSortData:  _ext.order,
-		aoFeatures:   _ext.feature,
-		oApi:         _ext.internal,
-		oStdClasses:  _ext.classes,
-		oPagination:  _ext.pager
-	} );
-	
-	
-	$.extend( DataTable.ext.classes, {
-		"sTable": "dataTable",
-		"sNoFooter": "no-footer",
-	
-		/* Paging buttons */
-		"sPageButton": "paginate_button",
-		"sPageButtonActive": "current",
-		"sPageButtonDisabled": "disabled",
-	
-		/* Striping classes */
-		"sStripeOdd": "odd",
-		"sStripeEven": "even",
-	
-		/* Empty row */
-		"sRowEmpty": "dataTables_empty",
-	
-		/* Features */
-		"sWrapper": "dataTables_wrapper",
-		"sFilter": "dataTables_filter",
-		"sInfo": "dataTables_info",
-		"sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
-		"sLength": "dataTables_length",
-		"sProcessing": "dataTables_processing",
-	
-		/* Sorting */
-		"sSortAsc": "sorting_asc",
-		"sSortDesc": "sorting_desc",
-		"sSortable": "sorting", /* Sortable in both directions */
-		"sSortableAsc": "sorting_asc_disabled",
-		"sSortableDesc": "sorting_desc_disabled",
-		"sSortableNone": "sorting_disabled",
-		"sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
-	
-		/* Filtering */
-		"sFilterInput": "",
-	
-		/* Page length */
-		"sLengthSelect": "",
-	
-		/* Scrolling */
-		"sScrollWrapper": "dataTables_scroll",
-		"sScrollHead": "dataTables_scrollHead",
-		"sScrollHeadInner": "dataTables_scrollHeadInner",
-		"sScrollBody": "dataTables_scrollBody",
-		"sScrollFoot": "dataTables_scrollFoot",
-		"sScrollFootInner": "dataTables_scrollFootInner",
-	
-		/* Misc */
-		"sHeaderTH": "",
-		"sFooterTH": "",
-	
-		// Deprecated
-		"sSortJUIAsc": "",
-		"sSortJUIDesc": "",
-		"sSortJUI": "",
-		"sSortJUIAscAllowed": "",
-		"sSortJUIDescAllowed": "",
-		"sSortJUIWrapper": "",
-		"sSortIcon": "",
-		"sJUIHeader": "",
-		"sJUIFooter": ""
-	} );
-	
-	
-	var extPagination = DataTable.ext.pager;
-	
-	function _numbers ( page, pages ) {
-		var
-			numbers = [],
-			buttons = extPagination.numbers_length,
-			half = Math.floor( buttons / 2 ),
-			i = 1;
-	
-		if ( pages <= buttons ) {
-			numbers = _range( 0, pages );
-		}
-		else if ( page <= half ) {
-			numbers = _range( 0, buttons-2 );
-			numbers.push( 'ellipsis' );
-			numbers.push( pages-1 );
-		}
-		else if ( page >= pages - 1 - half ) {
-			numbers = _range( pages-(buttons-2), pages );
-			numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
-			numbers.splice( 0, 0, 0 );
-		}
-		else {
-			numbers = _range( page-half+2, page+half-1 );
-			numbers.push( 'ellipsis' );
-			numbers.push( pages-1 );
-			numbers.splice( 0, 0, 'ellipsis' );
-			numbers.splice( 0, 0, 0 );
-		}
-	
-		numbers.DT_el = 'span';
-		return numbers;
-	}
-	
-	
-	$.extend( extPagination, {
-		simple: function ( page, pages ) {
-			return [ 'previous', 'next' ];
-		},
-	
-		full: function ( page, pages ) {
-			return [  'first', 'previous', 'next', 'last' ];
-		},
-	
-		numbers: function ( page, pages ) {
-			return [ _numbers(page, pages) ];
-		},
-	
-		simple_numbers: function ( page, pages ) {
-			return [ 'previous', _numbers(page, pages), 'next' ];
-		},
-	
-		full_numbers: function ( page, pages ) {
-			return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
-		},
-		
-		first_last_numbers: function (page, pages) {
-	 		return ['first', _numbers(page, pages), 'last'];
-	 	},
-	
-		// For testing and plug-ins to use
-		_numbers: _numbers,
-	
-		// Number of number buttons (including ellipsis) to show. _Must be odd!_
-		numbers_length: 7
-	} );
-	
-	
-	$.extend( true, DataTable.ext.renderer, {
-		pageButton: {
-			_: function ( settings, host, idx, buttons, page, pages ) {
-				var classes = settings.oClasses;
-				var lang = settings.oLanguage.oPaginate;
-				var aria = settings.oLanguage.oAria.paginate || {};
-				var btnDisplay, btnClass, counter=0;
-	
-				var attach = function( container, buttons ) {
-					var i, ien, node, button, tabIndex;
-					var disabledClass = classes.sPageButtonDisabled;
-					var clickHandler = function ( e ) {
-						_fnPageChange( settings, e.data.action, true );
-					};
-	
-					for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
-						button = buttons[i];
-	
-						if ( Array.isArray( button ) ) {
-							var inner = $( '<'+(button.DT_el || 'div')+'/>' )
-								.appendTo( container );
-							attach( inner, button );
-						}
-						else {
-							btnDisplay = null;
-							btnClass = button;
-							tabIndex = settings.iTabIndex;
-	
-							switch ( button ) {
-								case 'ellipsis':
-									container.append('<span class="ellipsis">&#x2026;</span>');
-									break;
-	
-								case 'first':
-									btnDisplay = lang.sFirst;
-	
-									if ( page === 0 ) {
-										tabIndex = -1;
-										btnClass += ' ' + disabledClass;
-									}
-									break;
-	
-								case 'previous':
-									btnDisplay = lang.sPrevious;
-	
-									if ( page === 0 ) {
-										tabIndex = -1;
-										btnClass += ' ' + disabledClass;
-									}
-									break;
-	
-								case 'next':
-									btnDisplay = lang.sNext;
-	
-									if ( pages === 0 || page === pages-1 ) {
-										tabIndex = -1;
-										btnClass += ' ' + disabledClass;
-									}
-									break;
-	
-								case 'last':
-									btnDisplay = lang.sLast;
-	
-									if ( pages === 0 || page === pages-1 ) {
-										tabIndex = -1;
-										btnClass += ' ' + disabledClass;
-									}
-									break;
-	
-								default:
-									btnDisplay = settings.fnFormatNumber( button + 1 );
-									btnClass = page === button ?
-										classes.sPageButtonActive : '';
-									break;
-							}
-	
-							if ( btnDisplay !== null ) {
-								node = $('<a>', {
-										'class': classes.sPageButton+' '+btnClass,
-										'aria-controls': settings.sTableId,
-										'aria-label': aria[ button ],
-										'data-dt-idx': counter,
-										'tabindex': tabIndex,
-										'id': idx === 0 && typeof button === 'string' ?
-											settings.sTableId +'_'+ button :
-											null
-									} )
-									.html( btnDisplay )
-									.appendTo( container );
-	
-								_fnBindAction(
-									node, {action: button}, clickHandler
-								);
-	
-								counter++;
-							}
-						}
-					}
-				};
-	
-				// IE9 throws an 'unknown error' if document.activeElement is used
-				// inside an iframe or frame. Try / catch the error. Not good for
-				// accessibility, but neither are frames.
-				var activeEl;
-	
-				try {
-					// Because this approach is destroying and recreating the paging
-					// elements, focus is lost on the select button which is bad for
-					// accessibility. So we want to restore focus once the draw has
-					// completed
-					activeEl = $(host).find(document.activeElement).data('dt-idx');
-				}
-				catch (e) {}
-	
-				attach( $(host).empty(), buttons );
-	
-				if ( activeEl !== undefined ) {
-					$(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');
-				}
-			}
-		}
-	} );
-	
-	
-	
-	// Built in type detection. See model.ext.aTypes for information about
-	// what is required from this methods.
-	$.extend( DataTable.ext.type.detect, [
-		// Plain numbers - first since V8 detects some plain numbers as dates
-		// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
-		function ( d, settings )
-		{
-			var decimal = settings.oLanguage.sDecimal;
-			return _isNumber( d, decimal ) ? 'num'+decimal : null;
-		},
-	
-		// Dates (only those recognised by the browser's Date.parse)
-		function ( d, settings )
-		{
-			// V8 tries _very_ hard to make a string passed into `Date.parse()`
-			// valid, so we need to use a regex to restrict date formats. Use a
-			// plug-in for anything other than ISO8601 style strings
-			if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
-				return null;
-			}
-			var parsed = Date.parse(d);
-			return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
-		},
-	
-		// Formatted numbers
-		function ( d, settings )
-		{
-			var decimal = settings.oLanguage.sDecimal;
-			return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
-		},
-	
-		// HTML numeric
-		function ( d, settings )
-		{
-			var decimal = settings.oLanguage.sDecimal;
-			return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
-		},
-	
-		// HTML numeric, formatted
-		function ( d, settings )
-		{
-			var decimal = settings.oLanguage.sDecimal;
-			return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
-		},
-	
-		// HTML (this is strict checking - there must be html)
-		function ( d, settings )
-		{
-			return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
-				'html' : null;
-		}
-	] );
-	
-	
-	
-	// Filter formatting functions. See model.ext.ofnSearch for information about
-	// what is required from these methods.
-	// 
-	// Note that additional search methods are added for the html numbers and
-	// html formatted numbers by `_addNumericSort()` when we know what the decimal
-	// place is
-	
-	
-	$.extend( DataTable.ext.type.search, {
-		html: function ( data ) {
-			return _empty(data) ?
-				data :
-				typeof data === 'string' ?
-					data
-						.replace( _re_new_lines, " " )
-						.replace( _re_html, "" ) :
-					'';
-		},
-	
-		string: function ( data ) {
-			return _empty(data) ?
-				data :
-				typeof data === 'string' ?
-					data.replace( _re_new_lines, " " ) :
-					data;
-		}
-	} );
-	
-	
-	
-	var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
-		if ( d !== 0 && (!d || d === '-') ) {
-			return -Infinity;
-		}
-	
-		// If a decimal place other than `.` is used, it needs to be given to the
-		// function so we can detect it and replace with a `.` which is the only
-		// decimal place Javascript recognises - it is not locale aware.
-		if ( decimalPlace ) {
-			d = _numToDecimal( d, decimalPlace );
-		}
-	
-		if ( d.replace ) {
-			if ( re1 ) {
-				d = d.replace( re1, '' );
-			}
-	
-			if ( re2 ) {
-				d = d.replace( re2, '' );
-			}
-		}
-	
-		return d * 1;
-	};
-	
-	
-	// Add the numeric 'deformatting' functions for sorting and search. This is done
-	// in a function to provide an easy ability for the language options to add
-	// additional methods if a non-period decimal place is used.
-	function _addNumericSort ( decimalPlace ) {
-		$.each(
-			{
-				// Plain numbers
-				"num": function ( d ) {
-					return __numericReplace( d, decimalPlace );
-				},
-	
-				// Formatted numbers
-				"num-fmt": function ( d ) {
-					return __numericReplace( d, decimalPlace, _re_formatted_numeric );
-				},
-	
-				// HTML numeric
-				"html-num": function ( d ) {
-					return __numericReplace( d, decimalPlace, _re_html );
-				},
-	
-				// HTML numeric, formatted
-				"html-num-fmt": function ( d ) {
-					return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
-				}
-			},
-			function ( key, fn ) {
-				// Add the ordering method
-				_ext.type.order[ key+decimalPlace+'-pre' ] = fn;
-	
-				// For HTML types add a search formatter that will strip the HTML
-				if ( key.match(/^html\-/) ) {
-					_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
-				}
-			}
-		);
-	}
-	
-	
-	// Default sort methods
-	$.extend( _ext.type.order, {
-		// Dates
-		"date-pre": function ( d ) {
-			var ts = Date.parse( d );
-			return isNaN(ts) ? -Infinity : ts;
-		},
-	
-		// html
-		"html-pre": function ( a ) {
-			return _empty(a) ?
-				'' :
-				a.replace ?
-					a.replace( /<.*?>/g, "" ).toLowerCase() :
-					a+'';
-		},
-	
-		// string
-		"string-pre": function ( a ) {
-			// This is a little complex, but faster than always calling toString,
-			// http://jsperf.com/tostring-v-check
-			return _empty(a) ?
-				'' :
-				typeof a === 'string' ?
-					a.toLowerCase() :
-					! a.toString ?
-						'' :
-						a.toString();
-		},
-	
-		// string-asc and -desc are retained only for compatibility with the old
-		// sort methods
-		"string-asc": function ( x, y ) {
-			return ((x < y) ? -1 : ((x > y) ? 1 : 0));
-		},
-	
-		"string-desc": function ( x, y ) {
-			return ((x < y) ? 1 : ((x > y) ? -1 : 0));
-		}
-	} );
-	
-	
-	// Numeric sorting types - order doesn't matter here
-	_addNumericSort( '' );
-	
-	
-	$.extend( true, DataTable.ext.renderer, {
-		header: {
-			_: function ( settings, cell, column, classes ) {
-				// No additional mark-up required
-				// Attach a sort listener to update on sort - note that using the
-				// `DT` namespace will allow the event to be removed automatically
-				// on destroy, while the `dt` namespaced event is the one we are
-				// listening for
-				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
-					if ( settings !== ctx ) { // need to check this this is the host
-						return;               // table, not a nested one
-					}
-	
-					var colIdx = column.idx;
-	
-					cell
-						.removeClass(
-							column.sSortingClass +' '+
-							classes.sSortAsc +' '+
-							classes.sSortDesc
-						)
-						.addClass( columns[ colIdx ] == 'asc' ?
-							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
-								classes.sSortDesc :
-								column.sSortingClass
-						);
-				} );
-			},
-	
-			jqueryui: function ( settings, cell, column, classes ) {
-				$('<div/>')
-					.addClass( classes.sSortJUIWrapper )
-					.append( cell.contents() )
-					.append( $('<span/>')
-						.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
-					)
-					.appendTo( cell );
-	
-				// Attach a sort listener to update on sort
-				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
-					if ( settings !== ctx ) {
-						return;
-					}
-	
-					var colIdx = column.idx;
-	
-					cell
-						.removeClass( classes.sSortAsc +" "+classes.sSortDesc )
-						.addClass( columns[ colIdx ] == 'asc' ?
-							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
-								classes.sSortDesc :
-								column.sSortingClass
-						);
-	
-					cell
-						.find( 'span.'+classes.sSortIcon )
-						.removeClass(
-							classes.sSortJUIAsc +" "+
-							classes.sSortJUIDesc +" "+
-							classes.sSortJUI +" "+
-							classes.sSortJUIAscAllowed +" "+
-							classes.sSortJUIDescAllowed
-						)
-						.addClass( columns[ colIdx ] == 'asc' ?
-							classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
-								classes.sSortJUIDesc :
-								column.sSortingClassJUI
-						);
-				} );
-			}
-		}
-	} );
-	
-	/*
-	 * Public helper functions. These aren't used internally by DataTables, or
-	 * called by any of the options passed into DataTables, but they can be used
-	 * externally by developers working with DataTables. They are helper functions
-	 * to make working with DataTables a little bit easier.
-	 */
-	
-	var __htmlEscapeEntities = function ( d ) {
-		return typeof d === 'string' ?
-			d
-				.replace(/&/g, '&amp;')
-				.replace(/</g, '&lt;')
-				.replace(/>/g, '&gt;')
-				.replace(/"/g, '&quot;') :
-			d;
-	};
-	
-	/**
-	 * Helpers for `columns.render`.
-	 *
-	 * The options defined here can be used with the `columns.render` initialisation
-	 * option to provide a display renderer. The following functions are defined:
-	 *
-	 * * `number` - Will format numeric data (defined by `columns.data`) for
-	 *   display, retaining the original unformatted data for sorting and filtering.
-	 *   It takes 5 parameters:
-	 *   * `string` - Thousands grouping separator
-	 *   * `string` - Decimal point indicator
-	 *   * `integer` - Number of decimal points to show
-	 *   * `string` (optional) - Prefix.
-	 *   * `string` (optional) - Postfix (/suffix).
-	 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
-	 *   parameters.
-	 *
-	 * @example
-	 *   // Column definition using the number renderer
-	 *   {
-	 *     data: "salary",
-	 *     render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
-	 *   }
-	 *
-	 * @namespace
-	 */
-	DataTable.render = {
-		number: function ( thousands, decimal, precision, prefix, postfix ) {
-			return {
-				display: function ( d ) {
-					if ( typeof d !== 'number' && typeof d !== 'string' ) {
-						return d;
-					}
-	
-					var negative = d < 0 ? '-' : '';
-					var flo = parseFloat( d );
-	
-					// If NaN then there isn't much formatting that we can do - just
-					// return immediately, escaping any HTML (this was supposed to
-					// be a number after all)
-					if ( isNaN( flo ) ) {
-						return __htmlEscapeEntities( d );
-					}
-	
-					flo = flo.toFixed( precision );
-					d = Math.abs( flo );
-	
-					var intPart = parseInt( d, 10 );
-					var floatPart = precision ?
-						decimal+(d - intPart).toFixed( precision ).substring( 2 ):
-						'';
-	
-					return negative + (prefix||'') +
-						intPart.toString().replace(
-							/\B(?=(\d{3})+(?!\d))/g, thousands
-						) +
-						floatPart +
-						(postfix||'');
-				}
-			};
-		},
-	
-		text: function () {
-			return {
-				display: __htmlEscapeEntities,
-				filter: __htmlEscapeEntities
-			};
-		}
-	};
-	
-	
-	/*
-	 * This is really a good bit rubbish this method of exposing the internal methods
-	 * publicly... - To be fixed in 2.0 using methods on the prototype
-	 */
-	
-	
-	/**
-	 * Create a wrapper function for exporting an internal functions to an external API.
-	 *  @param {string} fn API function name
-	 *  @returns {function} wrapped function
-	 *  @memberof DataTable#internal
-	 */
-	function _fnExternApiFunc (fn)
-	{
-		return function() {
-			var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
-				Array.prototype.slice.call(arguments)
-			);
-			return DataTable.ext.internal[fn].apply( this, args );
-		};
-	}
-	
-	
-	/**
-	 * Reference to internal functions for use by plug-in developers. Note that
-	 * these methods are references to internal functions and are considered to be
-	 * private. If you use these methods, be aware that they are liable to change
-	 * between versions.
-	 *  @namespace
-	 */
-	$.extend( DataTable.ext.internal, {
-		_fnExternApiFunc: _fnExternApiFunc,
-		_fnBuildAjax: _fnBuildAjax,
-		_fnAjaxUpdate: _fnAjaxUpdate,
-		_fnAjaxParameters: _fnAjaxParameters,
-		_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
-		_fnAjaxDataSrc: _fnAjaxDataSrc,
-		_fnAddColumn: _fnAddColumn,
-		_fnColumnOptions: _fnColumnOptions,
-		_fnAdjustColumnSizing: _fnAdjustColumnSizing,
-		_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
-		_fnColumnIndexToVisible: _fnColumnIndexToVisible,
-		_fnVisbleColumns: _fnVisbleColumns,
-		_fnGetColumns: _fnGetColumns,
-		_fnColumnTypes: _fnColumnTypes,
-		_fnApplyColumnDefs: _fnApplyColumnDefs,
-		_fnHungarianMap: _fnHungarianMap,
-		_fnCamelToHungarian: _fnCamelToHungarian,
-		_fnLanguageCompat: _fnLanguageCompat,
-		_fnBrowserDetect: _fnBrowserDetect,
-		_fnAddData: _fnAddData,
-		_fnAddTr: _fnAddTr,
-		_fnNodeToDataIndex: _fnNodeToDataIndex,
-		_fnNodeToColumnIndex: _fnNodeToColumnIndex,
-		_fnGetCellData: _fnGetCellData,
-		_fnSetCellData: _fnSetCellData,
-		_fnSplitObjNotation: _fnSplitObjNotation,
-		_fnGetObjectDataFn: _fnGetObjectDataFn,
-		_fnSetObjectDataFn: _fnSetObjectDataFn,
-		_fnGetDataMaster: _fnGetDataMaster,
-		_fnClearTable: _fnClearTable,
-		_fnDeleteIndex: _fnDeleteIndex,
-		_fnInvalidate: _fnInvalidate,
-		_fnGetRowElements: _fnGetRowElements,
-		_fnCreateTr: _fnCreateTr,
-		_fnBuildHead: _fnBuildHead,
-		_fnDrawHead: _fnDrawHead,
-		_fnDraw: _fnDraw,
-		_fnReDraw: _fnReDraw,
-		_fnAddOptionsHtml: _fnAddOptionsHtml,
-		_fnDetectHeader: _fnDetectHeader,
-		_fnGetUniqueThs: _fnGetUniqueThs,
-		_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
-		_fnFilterComplete: _fnFilterComplete,
-		_fnFilterCustom: _fnFilterCustom,
-		_fnFilterColumn: _fnFilterColumn,
-		_fnFilter: _fnFilter,
-		_fnFilterCreateSearch: _fnFilterCreateSearch,
-		_fnEscapeRegex: _fnEscapeRegex,
-		_fnFilterData: _fnFilterData,
-		_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
-		_fnUpdateInfo: _fnUpdateInfo,
-		_fnInfoMacros: _fnInfoMacros,
-		_fnInitialise: _fnInitialise,
-		_fnInitComplete: _fnInitComplete,
-		_fnLengthChange: _fnLengthChange,
-		_fnFeatureHtmlLength: _fnFeatureHtmlLength,
-		_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
-		_fnPageChange: _fnPageChange,
-		_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
-		_fnProcessingDisplay: _fnProcessingDisplay,
-		_fnFeatureHtmlTable: _fnFeatureHtmlTable,
-		_fnScrollDraw: _fnScrollDraw,
-		_fnApplyToChildren: _fnApplyToChildren,
-		_fnCalculateColumnWidths: _fnCalculateColumnWidths,
-		_fnThrottle: _fnThrottle,
-		_fnConvertToWidth: _fnConvertToWidth,
-		_fnGetWidestNode: _fnGetWidestNode,
-		_fnGetMaxLenString: _fnGetMaxLenString,
-		_fnStringToCss: _fnStringToCss,
-		_fnSortFlatten: _fnSortFlatten,
-		_fnSort: _fnSort,
-		_fnSortAria: _fnSortAria,
-		_fnSortListener: _fnSortListener,
-		_fnSortAttachListener: _fnSortAttachListener,
-		_fnSortingClasses: _fnSortingClasses,
-		_fnSortData: _fnSortData,
-		_fnSaveState: _fnSaveState,
-		_fnLoadState: _fnLoadState,
-		_fnSettingsFromNode: _fnSettingsFromNode,
-		_fnLog: _fnLog,
-		_fnMap: _fnMap,
-		_fnBindAction: _fnBindAction,
-		_fnCallbackReg: _fnCallbackReg,
-		_fnCallbackFire: _fnCallbackFire,
-		_fnLengthOverflow: _fnLengthOverflow,
-		_fnRenderer: _fnRenderer,
-		_fnDataSource: _fnDataSource,
-		_fnRowAttributes: _fnRowAttributes,
-		_fnExtend: _fnExtend,
-		_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
-		                                // in 1.10, so this dead-end function is
-		                                // added to prevent errors
-	} );
-	
-
-	// jQuery access
-	$.fn.dataTable = DataTable;
-
-	// Provide access to the host jQuery object (circular reference)
-	DataTable.$ = $;
-
-	// Legacy aliases
-	$.fn.dataTableSettings = DataTable.settings;
-	$.fn.dataTableExt = DataTable.ext;
-
-	// With a capital `D` we return a DataTables API instance rather than a
-	// jQuery object
-	$.fn.DataTable = function ( opts ) {
-		return $(this).dataTable( opts ).api();
-	};
-
-	// All properties that are available to $.fn.dataTable should also be
-	// available on $.fn.DataTable
-	$.each( DataTable, function ( prop, val ) {
-		$.fn.DataTable[ prop ] = val;
-	} );
-
-
-	// Information about events fired by DataTables - for documentation.
-	/**
-	 * Draw event, fired whenever the table is redrawn on the page, at the same
-	 * point as fnDrawCallback. This may be useful for binding events or
-	 * performing calculations when the table is altered at all.
-	 *  @name DataTable#draw.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 */
-
-	/**
-	 * Search event, fired when the searching applied to the table (using the
-	 * built-in global search, or column filters) is altered.
-	 *  @name DataTable#search.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 */
-
-	/**
-	 * Page change event, fired when the paging of the table is altered.
-	 *  @name DataTable#page.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 */
-
-	/**
-	 * Order event, fired when the ordering applied to the table is altered.
-	 *  @name DataTable#order.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 */
-
-	/**
-	 * DataTables initialisation complete event, fired when the table is fully
-	 * drawn, including Ajax data loaded, if Ajax data is required.
-	 *  @name DataTable#init.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} oSettings DataTables settings object
-	 *  @param {object} json The JSON object request from the server - only
-	 *    present if client-side Ajax sourced data is used</li></ol>
-	 */
-
-	/**
-	 * State save event, fired when the table has changed state a new state save
-	 * is required. This event allows modification of the state saving object
-	 * prior to actually doing the save, including addition or other state
-	 * properties (for plug-ins) or modification of a DataTables core property.
-	 *  @name DataTable#stateSaveParams.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} oSettings DataTables settings object
-	 *  @param {object} json The state information to be saved
-	 */
-
-	/**
-	 * State load event, fired when the table is loading state from the stored
-	 * data, but prior to the settings object being modified by the saved state
-	 * - allowing modification of the saved state is required or loading of
-	 * state for a plug-in.
-	 *  @name DataTable#stateLoadParams.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} oSettings DataTables settings object
-	 *  @param {object} json The saved state information
-	 */
-
-	/**
-	 * State loaded event, fired when state has been loaded from stored data and
-	 * the settings object has been modified by the loaded data.
-	 *  @name DataTable#stateLoaded.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} oSettings DataTables settings object
-	 *  @param {object} json The saved state information
-	 */
-
-	/**
-	 * Processing event, fired when DataTables is doing some kind of processing
-	 * (be it, order, search or anything else). It can be used to indicate to
-	 * the end user that there is something happening, or that something has
-	 * finished.
-	 *  @name DataTable#processing.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} oSettings DataTables settings object
-	 *  @param {boolean} bShow Flag for if DataTables is doing processing or not
-	 */
-
-	/**
-	 * Ajax (XHR) event, fired whenever an Ajax request is completed from a
-	 * request to made to the server for new data. This event is called before
-	 * DataTables processed the returned data, so it can also be used to pre-
-	 * process the data returned from the server, if needed.
-	 *
-	 * Note that this trigger is called in `fnServerData`, if you override
-	 * `fnServerData` and which to use this event, you need to trigger it in you
-	 * success function.
-	 *  @name DataTable#xhr.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 *  @param {object} json JSON returned from the server
-	 *
-	 *  @example
-	 *     // Use a custom property returned from the server in another DOM element
-	 *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
-	 *       $('#status').html( json.status );
-	 *     } );
-	 *
-	 *  @example
-	 *     // Pre-process the data returned from the server
-	 *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
-	 *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
-	 *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
-	 *       }
-	 *       // Note no return - manipulate the data directly in the JSON object.
-	 *     } );
-	 */
-
-	/**
-	 * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
-	 * or passing the bDestroy:true parameter in the initialisation object. This
-	 * can be used to remove bound events, added DOM nodes, etc.
-	 *  @name DataTable#destroy.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 */
-
-	/**
-	 * Page length change event, fired when number of records to show on each
-	 * page (the length) is changed.
-	 *  @name DataTable#length.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 *  @param {integer} len New length
-	 */
-
-	/**
-	 * Column sizing has changed.
-	 *  @name DataTable#column-sizing.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 */
-
-	/**
-	 * Column visibility has changed.
-	 *  @name DataTable#column-visibility.dt
-	 *  @event
-	 *  @param {event} e jQuery event object
-	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
-	 *  @param {int} column Column index
-	 *  @param {bool} vis `false` if column now hidden, or `true` if visible
-	 */
-
-	return $.fn.dataTable;
-}));
diff --git a/public/plugins/datatables/jquery.dataTables.min.css b/public/plugins/datatables/jquery.dataTables.min.css
new file mode 100644
index 000000000..aff1ca672
--- /dev/null
+++ b/public/plugins/datatables/jquery.dataTables.min.css
@@ -0,0 +1 @@
+:root{--dt-row-selected: 13, 110, 253;--dt-row-selected-text: 255, 255, 255;--dt-row-selected-link: 9, 10, 11}table.dataTable td.dt-control{text-align:center;cursor:pointer}table.dataTable td.dt-control:before{height:1em;width:1em;margin-top:-9px;display:inline-block;color:white;border:.15em solid white;border-radius:1em;box-shadow:0 0 .2em #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable tr.dt-hasChild td.dt-control:before{content:"-";background-color:#d33333}table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting_asc_disabled,table.dataTable thead>tr>th.sorting_desc_disabled,table.dataTable thead>tr>td.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting_asc_disabled,table.dataTable thead>tr>td.sorting_desc_disabled{cursor:pointer;position:relative;padding-right:26px}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after{position:absolute;display:block;opacity:.125;right:10px;line-height:9px;font-size:.8em}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:before{bottom:50%;content:"▲";content:"▲"/""}table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:after{top:50%;content:"▼";content:"▼"/""}table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:after{opacity:.6}table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting_asc_disabled:before{display:none}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}div.dataTables_scrollBody>table.dataTable>thead>tr>th:before,div.dataTables_scrollBody>table.dataTable>thead>tr>th:after,div.dataTables_scrollBody>table.dataTable>thead>tr>td:before,div.dataTables_scrollBody>table.dataTable>thead>tr>td:after{display:none}div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:2px}div.dataTables_processing>div:last-child{position:relative;width:80px;height:15px;margin:1em auto}div.dataTables_processing>div:last-child>div{position:absolute;top:0;width:13px;height:13px;border-radius:50%;background:rgb(13, 110, 253);background:rgb(var(--dt-row-selected));animation-timing-function:cubic-bezier(0, 1, 1, 0)}div.dataTables_processing>div:last-child>div:nth-child(1){left:8px;animation:datatables-loader-1 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(2){left:8px;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(3){left:32px;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(4){left:56px;animation:datatables-loader-3 .6s infinite}@keyframes datatables-loader-1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes datatables-loader-3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes datatables-loader-2{0%{transform:translate(0, 0)}100%{transform:translate(24px, 0)}}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th,table.dataTable thead td,table.dataTable tfoot th,table.dataTable tfoot td{text-align:left}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px;border-bottom:1px solid rgba(0, 0, 0, 0.3)}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 10px 6px 10px;border-top:1px solid rgba(0, 0, 0, 0.3)}table.dataTable tbody tr{background-color:transparent}table.dataTable tbody tr.selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.9);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.9);color:rgb(255, 255, 255);color:rgb(var(--dt-row-selected-text))}table.dataTable tbody tr.selected a{color:rgb(9, 10, 11);color:rgb(var(--dt-row-selected-link))}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid rgba(0, 0, 0, 0.15);border-right:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe>tbody>tr.odd>*,table.dataTable.display>tbody>tr.odd>*{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.023)}table.dataTable.stripe>tbody>tr.odd.selected>*,table.dataTable.display>tbody>tr.odd.selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.923);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.923))}table.dataTable.hover>tbody>tr:hover>*,table.dataTable.display>tbody>tr:hover>*{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.035)}table.dataTable.hover>tbody>tr.selected:hover>*,table.dataTable.display>tbody>tr.selected:hover>*{box-shadow:inset 0 0 0 9999px #0d6efd !important;box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 1)) !important}table.dataTable.order-column>tbody tr>.sorting_1,table.dataTable.order-column>tbody tr>.sorting_2,table.dataTable.order-column>tbody tr>.sorting_3,table.dataTable.display>tbody tr>.sorting_1,table.dataTable.display>tbody tr>.sorting_2,table.dataTable.display>tbody tr>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.019)}table.dataTable.order-column>tbody tr.selected>.sorting_1,table.dataTable.order-column>tbody tr.selected>.sorting_2,table.dataTable.order-column>tbody tr.selected>.sorting_3,table.dataTable.display>tbody tr.selected>.sorting_1,table.dataTable.display>tbody tr.selected>.sorting_2,table.dataTable.display>tbody tr.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.919);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.919))}table.dataTable.display>tbody>tr.odd>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.odd>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.054)}table.dataTable.display>tbody>tr.odd>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.odd>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.047)}table.dataTable.display>tbody>tr.odd>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.odd>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.039)}table.dataTable.display>tbody>tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.odd.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.954);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.954))}table.dataTable.display>tbody>tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.odd.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.947);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.947))}table.dataTable.display>tbody>tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.odd.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.939);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.939))}table.dataTable.display>tbody>tr.even>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.019)}table.dataTable.display>tbody>tr.even>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.011)}table.dataTable.display>tbody>tr.even>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.003)}table.dataTable.display>tbody>tr.even.selected>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.919);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.919))}table.dataTable.display>tbody>tr.even.selected>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.911);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.911))}table.dataTable.display>tbody>tr.even.selected>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.903);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.903))}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.082)}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.074)}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.062)}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.982);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.982))}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.974);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.974))}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.962);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.962))}table.dataTable.no-footer{border-bottom:1px solid rgba(0, 0, 0, 0.3)}table.dataTable.compact thead th,table.dataTable.compact thead td,table.dataTable.compact tfoot th,table.dataTable.compact tfoot td,table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_length select{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;padding:4px}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;margin-left:3px}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;color:inherit !important;border:1px solid transparent;border-radius:2px;background:transparent}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:inherit !important;border:1px solid rgba(0, 0, 0, 0.3);background-color:rgba(230, 230, 230, 0.1);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(230, 230, 230, 0.1)), color-stop(100%, rgba(0, 0, 0, 0.1)));background:-webkit-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-moz-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-ms-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-o-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:linear-gradient(to bottom, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:inherit}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid rgba(0, 0, 0, 0.3)}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:.5em}}
diff --git a/public/plugins/datatables/jquery.dataTables.min.js b/public/plugins/datatables/jquery.dataTables.min.js
index 142c04f2e..c89263c6d 100644
--- a/public/plugins/datatables/jquery.dataTables.min.js
+++ b/public/plugins/datatables/jquery.dataTables.min.js
@@ -1,168 +1,4 @@
-/*!
- DataTables 1.10.23
- ©2008-2020 SpryMedia Ltd - datatables.net/license
-*/
-(function(h){"function"===typeof define&&define.amd?define(["jquery"],function(E){return h(E,window,document)}):"object"===typeof exports?module.exports=function(E,H){E||(E=window);H||(H="undefined"!==typeof window?require("jquery"):require("jquery")(E));return h(H,E,E.document)}:h(jQuery,window,document)})(function(h,E,H,k){function $(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()),
-d[c]=e,"o"===b[1]&&$(a[e])});a._hungarianMap=d}function J(a,b,c){a._hungarianMap||$(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),J(a[d],b[d],c)):b[d]=b[e]})}function Ea(a){var b=l.defaults.oLanguage,c=b.sDecimal;c&&Fa(c);if(a){var d=a.sZeroRecords;!a.sEmptyTable&&(d&&"No data available in table"===b.sEmptyTable)&&F(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(d&&"Loading..."===b.sLoadingRecords)&&F(a,
-a,"sZeroRecords","sLoadingRecords");a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&c!==a&&Fa(a)}}function gb(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":
-"");"boolean"===typeof a.scrollX&&(a.scrollX=a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&J(l.models.oSearch,a[b])}function hb(a){A(a,"orderable","bSortable");A(a,"orderData","aDataSort");A(a,"orderSequence","asSorting");A(a,"orderDataType","sortDataType");var b=a.aDataSort;"number"===typeof b&&!Array.isArray(b)&&(a.aDataSort=[b])}function ib(a){if(!l.__browser){var b={};l.__browser=b;var c=h("<div/>").css({position:"fixed",top:0,left:-1*h(E).scrollLeft(),height:1,
-width:1,overflow:"hidden"}).append(h("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(h("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,l.__browser);a.oScroll.iBarWidth=l.__browser.barWidth}
-function jb(a,b,c,d,e,f){var g,j=!1;c!==k&&(g=c,j=!0);for(;d!==e;)a.hasOwnProperty(d)&&(g=j?b(g,a[d],d,a):a[d],j=!0,d+=f);return g}function Ga(a,b){var c=l.defaults.column,d=a.aoColumns.length,c=h.extend({},l.models.oColumn,c,{nTh:b?b:H.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},l.models.oSearch,c[d]);la(a,d,h(b).data())}function la(a,b,c){var b=a.aoColumns[b],
-d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(hb(c),J(l.defaults.column,c,!0),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),c.sClass&&e.addClass(c.sClass),h.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));var g=b.mData,j=S(g),i=
-b.mRender?S(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=h.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=j(a,b,k,c);return i&&b?i(d,b,a,c):d};b.fnSetData=function(a,b,c){return N(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=
-d.sSortableNone,b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function aa(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ha(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;(""!==b.sY||""!==b.sX)&&ma(a);u(a,null,"column-sizing",[a])}function ba(a,b){var c=na(a,"bVisible");
-return"number"===typeof c[b]?c[b]:null}function ca(a,b){var c=na(a,"bVisible"),c=h.inArray(b,c);return-1!==c?c:null}function W(a){var b=0;h.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==h(d.nTh).css("display")&&b++});return b}function na(a,b){var c=[];h.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ia(a){var b=a.aoColumns,c=a.aoData,d=l.ext.type.detect,e,f,g,j,i,h,m,q,r;e=0;for(f=b.length;e<f;e++)if(m=b[e],r=[],!m.sType&&m._sManualType)m.sType=m._sManualType;else if(!m.sType){g=
-0;for(j=d.length;g<j;g++){i=0;for(h=c.length;i<h;i++){r[i]===k&&(r[i]=B(a,i,e,"type"));q=d[g](r[i],a);if(!q&&g!==d.length-1)break;if("html"===q)break}if(q){m.sType=q;break}}m.sType||(m.sType="string")}}function kb(a,b,c,d){var e,f,g,j,i,n,m=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){n=b[e];var q=n.targets!==k?n.targets:n.aTargets;Array.isArray(q)||(q=[q]);f=0;for(g=q.length;f<g;f++)if("number"===typeof q[f]&&0<=q[f]){for(;m.length<=q[f];)Ga(a);d(q[f],n)}else if("number"===typeof q[f]&&0>q[f])d(m.length+
-q[f],n);else if("string"===typeof q[f]){j=0;for(i=m.length;j<i;j++)("_all"==q[f]||h(m[j].nTh).hasClass(q[f]))&&d(j,n)}}if(c){e=0;for(a=c.length;e<a;e++)d(e,c[e])}}function O(a,b,c,d){var e=a.aoData.length,f=h.extend(!0,{},l.models.oRow,{src:c?"dom":"data",idx:e});f._aData=b;a.aoData.push(f);for(var g=a.aoColumns,j=0,i=g.length;j<i;j++)g[j].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==k&&(a.aIds[b]=f);(c||!a.oFeatures.bDeferRender)&&Ja(a,e,c,d);return e}function oa(a,b){var c;b instanceof
-h||(b=h(b));return b.map(function(b,e){c=Ka(a,e);return O(a,c.data,e,c.cells)})}function B(a,b,c,d){var e=a.iDraw,f=a.aoColumns[c],g=a.aoData[b]._aData,j=f.sDefaultContent,i=f.fnGetData(g,d,{settings:a,row:b,col:c});if(i===k)return a.iDrawError!=e&&null===j&&(K(a,0,"Requested unknown parameter "+("function"==typeof f.mData?"{function}":"'"+f.mData+"'")+" for row "+b+", column "+c,4),a.iDrawError=e),j;if((i===g||null===i)&&null!==j&&d!==k)i=j;else if("function"===typeof i)return i.call(g);return null===
-i&&"display"==d?"":i}function lb(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}function La(a){return h.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\\./g,".")})}function S(a){if(h.isPlainObject(a)){var b={};h.each(a,function(a,c){c&&(b[a]=S(c))});return function(a,c,f,g){var j=b[c]||b._;return j!==k?j(a,c,f,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,f,g){return a(b,c,f,g)};if("string"===typeof a&&
-(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var c=function(a,b,f){var g,j;if(""!==f){j=La(f);for(var i=0,h=j.length;i<h;i++){f=j[i].match(da);g=j[i].match(X);if(f){j[i]=j[i].replace(da,"");""!==j[i]&&(a=a[j[i]]);g=[];j.splice(0,i+1);j=j.join(".");if(Array.isArray(a)){i=0;for(h=a.length;i<h;i++)g.push(c(a[i],b,j))}a=f[0].substring(1,f[0].length-1);a=""===a?g:g.join(a);break}else if(g){j[i]=j[i].replace(X,"");a=a[j[i]]();continue}if(null===a||a[j[i]]===k)return k;a=a[j[i]]}}return a};
-return function(b,e){return c(b,e,a)}}return function(b){return b[a]}}function N(a){if(h.isPlainObject(a))return N(a._);if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var b=function(a,d,e){var e=La(e),f;f=e[e.length-1];for(var g,j,i=0,h=e.length-1;i<h;i++){if("__proto__"===e[i]||"constructor"===e[i])throw Error("Cannot set prototype values");g=e[i].match(da);j=
-e[i].match(X);if(g){e[i]=e[i].replace(da,"");a[e[i]]=[];f=e.slice();f.splice(0,i+1);g=f.join(".");if(Array.isArray(d)){j=0;for(h=d.length;j<h;j++)f={},b(f,d[j],g),a[e[i]].push(f)}else a[e[i]]=d;return}j&&(e[i]=e[i].replace(X,""),a=a[e[i]](d));if(null===a[e[i]]||a[e[i]]===k)a[e[i]]={};a=a[e[i]]}if(f.match(X))a[f.replace(X,"")](d);else a[f.replace(da,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Ma(a){return C(a.aoData,"_aData")}function pa(a){a.aoData.length=0;
-a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function qa(a,b,c){for(var d=-1,e=0,f=a.length;e<f;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===k&&a.splice(d,1)}function ea(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ka(a,e,d,d===k?k:e._aData).data;else{var j=e.anCells;if(j)if(d!==k)g(j[d],d);else{c=0;for(f=j.length;c<f;c++)g(j[c],c)}}e._aSortData=null;
-e._aFilterData=null;g=a.aoColumns;if(d!==k)g[d].sType=null;else{c=0;for(f=g.length;c<f;c++)g[c].sType=null;Na(a,e)}}function Ka(a,b,c,d){var e=[],f=b.firstChild,g,j,i=0,h,m=a.aoColumns,q=a._rowReadObject,d=d!==k?d:q?{}:[],r=function(a,b){if("string"===typeof a){var c=a.indexOf("@");-1!==c&&(c=a.substring(c+1),N(a)(d,b.getAttribute(c)))}},G=function(a){if(c===k||c===i)j=m[i],h=a.innerHTML.trim(),j&&j._bAttrSrc?(N(j.mData._)(d,h),r(j.mData.sort,a),r(j.mData.type,a),r(j.mData.filter,a)):q?(j._setter||
-(j._setter=N(j.mData)),j._setter(d,h)):d[i]=h;i++};if(f)for(;f;){g=f.nodeName.toUpperCase();if("TD"==g||"TH"==g)G(f),e.push(f);f=f.nextSibling}else{e=b.anCells;f=0;for(g=e.length;f<g;f++)G(e[f])}if(b=b.firstChild?b:b.nTr)(b=b.getAttribute("id"))&&N(a.rowId)(d,b);return{data:d,cells:e}}function Ja(a,b,c,d){var e=a.aoData[b],f=e._aData,g=[],j,i,n,m,q;if(null===e.nTr){j=c||H.createElement("tr");e.nTr=j;e.anCells=g;j._DT_RowIndex=b;Na(a,e);n=0;for(m=a.aoColumns.length;n<m;n++){i=a.aoColumns[n];e=(q=c?
-!1:!0)?H.createElement(i.sCellType):d[n];e._DT_CellIndex={row:b,column:n};g.push(e);if(q||(i.mRender||i.mData!==n)&&(!h.isPlainObject(i.mData)||i.mData._!==n+".display"))e.innerHTML=B(a,b,n,"display");i.sClass&&(e.className+=" "+i.sClass);i.bVisible&&!c?j.appendChild(e):!i.bVisible&&c&&e.parentNode.removeChild(e);i.fnCreatedCell&&i.fnCreatedCell.call(a.oInstance,e,B(a,b,n),f,b,n)}u(a,"aoRowCreatedCallback",null,[j,f,b,g])}}function Na(a,b){var c=b.nTr,d=b._aData;if(c){var e=a.rowIdFn(d);e&&(c.id=
-e);d.DT_RowClass&&(e=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?ra(b.__rowc.concat(e)):e,h(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&h(c).attr(d.DT_RowAttr);d.DT_RowData&&h(c).data(d.DT_RowData)}}function mb(a){var b,c,d,e,f,g=a.nTHead,j=a.nTFoot,i=0===h("th, td",g).length,n=a.oClasses,m=a.aoColumns;i&&(e=h("<tr/>").appendTo(g));b=0;for(c=m.length;b<c;b++)f=m[b],d=h(f.nTh).addClass(f.sClass),i&&d.appendTo(e),a.oFeatures.bSort&&(d.addClass(f.sSortingClass),!1!==f.bSortable&&
-(d.attr("tabindex",a.iTabIndex).attr("aria-controls",a.sTableId),Oa(a,f.nTh,b))),f.sTitle!=d[0].innerHTML&&d.html(f.sTitle),Pa(a,"header")(a,d,f,n);i&&fa(a.aoHeader,g);h(g).children("tr").attr("role","row");h(g).children("tr").children("th, td").addClass(n.sHeaderTH);h(j).children("tr").children("th, td").addClass(n.sFooterTH);if(null!==j){a=a.aoFooter[0];b=0;for(c=a.length;b<c;b++)f=m[b],f.nTf=a[b].cell,f.sClass&&h(f.nTf).addClass(f.sClass)}}function ga(a,b,c){var d,e,f,g=[],j=[],i=a.aoColumns.length,
-n;if(b){c===k&&(c=!1);d=0;for(e=b.length;d<e;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=i-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);j.push([])}d=0;for(e=g.length;d<e;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(n=i=1,j[d][f]===k){a.appendChild(g[d][f].cell);for(j[d][f]=1;g[d+i]!==k&&g[d][f].cell==g[d+i][f].cell;)j[d+i][f]=1,i++;for(;g[d][f+n]!==k&&g[d][f].cell==g[d][f+n].cell;){for(c=0;c<i;c++)j[d+c][f+n]=1;n++}h(g[d][f].cell).attr("rowspan",
-i).attr("colspan",n)}}}}function P(a){var b=u(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,b))D(a,!1);else{var b=[],c=0,d=a.asStripeClasses,e=d.length,f=a.oLanguage,g=a.iInitDisplayStart,j="ssp"==y(a),i=a.aiDisplay;a.bDrawing=!0;g!==k&&-1!==g&&(a._iDisplayStart=j?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);var g=a._iDisplayStart,n=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,D(a,!1);else if(j){if(!a.bDestroying&&!nb(a))return}else a.iDraw++;if(0!==i.length){f=
-j?a.aoData.length:n;for(j=j?0:g;j<f;j++){var m=i[j],q=a.aoData[m];null===q.nTr&&Ja(a,m);var r=q.nTr;if(0!==e){var G=d[c%e];q._sRowStripe!=G&&(h(r).removeClass(q._sRowStripe).addClass(G),q._sRowStripe=G)}u(a,"aoRowCallback",null,[r,q._aData,c,j,m]);b.push(r);c++}}else c=f.sZeroRecords,1==a.iDraw&&"ajax"==y(a)?c=f.sLoadingRecords:f.sEmptyTable&&0===a.fnRecordsTotal()&&(c=f.sEmptyTable),b[0]=h("<tr/>",{"class":e?d[0]:""}).append(h("<td />",{valign:"top",colSpan:W(a),"class":a.oClasses.sRowEmpty}).html(c))[0];
-u(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ma(a),g,n,i]);u(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ma(a),g,n,i]);d=h(a.nTBody);d.children().detach();d.append(h(b));u(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function T(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&ob(a);d?ha(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;P(a);a._drawHold=!1}function pb(a){var b=a.oClasses,
-c=h(a.nTable),c=h("<div/>").insertBefore(c),d=a.oFeatures,e=h("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var f=a.sDom.split(""),g,j,i,n,m,q,k=0;k<f.length;k++){g=null;j=f[k];if("<"==j){i=h("<div/>")[0];n=f[k+1];if("'"==n||'"'==n){m="";for(q=2;f[k+q]!=n;)m+=f[k+q],q++;"H"==m?m=b.sJUIHeader:"F"==m&&(m=b.sJUIFooter);-1!=m.indexOf(".")?(n=m.split("."),i.id=n[0].substr(1,n[0].length-
-1),i.className=n[1]):"#"==m.charAt(0)?i.id=m.substr(1,m.length-1):i.className=m;k+=q}e.append(i);e=h(i)}else if(">"==j)e=e.parent();else if("l"==j&&d.bPaginate&&d.bLengthChange)g=qb(a);else if("f"==j&&d.bFilter)g=rb(a);else if("r"==j&&d.bProcessing)g=sb(a);else if("t"==j)g=tb(a);else if("i"==j&&d.bInfo)g=ub(a);else if("p"==j&&d.bPaginate)g=vb(a);else if(0!==l.ext.feature.length){i=l.ext.feature;q=0;for(n=i.length;q<n;q++)if(j==i[q].cFeature){g=i[q].fnInit(a);break}}g&&(i=a.aanFeatures,i[j]||(i[j]=
-[]),i[j].push(g),e.append(g))}c.replaceWith(e);a.nHolding=null}function fa(a,b){var c=h(b).children("tr"),d,e,f,g,j,i,n,m,q,k;a.splice(0,a.length);f=0;for(i=c.length;f<i;f++)a.push([]);f=0;for(i=c.length;f<i;f++){d=c[f];for(e=d.firstChild;e;){if("TD"==e.nodeName.toUpperCase()||"TH"==e.nodeName.toUpperCase()){m=1*e.getAttribute("colspan");q=1*e.getAttribute("rowspan");m=!m||0===m||1===m?1:m;q=!q||0===q||1===q?1:q;g=0;for(j=a[f];j[g];)g++;n=g;k=1===m?!0:!1;for(j=0;j<m;j++)for(g=0;g<q;g++)a[f+g][n+j]=
-{cell:e,unique:k},a[f+g].nTr=d}e=e.nextSibling}}}function sa(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],fa(c,b)));for(var b=0,e=c.length;b<e;b++)for(var f=0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function ta(a,b,c){u(a,"aoServerParams","serverParams",[b]);if(b&&Array.isArray(b)){var d={},e=/(.*?)\[\]$/;h.each(b,function(a,b){var c=b.name.match(e);c?(c=c[0],d[c]||(d[c]=[]),d[c].push(b.value)):d[b.name]=b.value});b=d}var f,g=a.ajax,j=a.oInstance,
-i=function(b){u(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(h.isPlainObject(g)&&g.data){f=g.data;var n="function"===typeof f?f(b,a):f,b="function"===typeof f&&n?n:h.extend(!0,b,n);delete g.data}n={data:b,success:function(b){var c=b.error||b.sError;c&&K(a,0,c);a.json=b;i(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c){var d=u(a,null,"xhr",[a,null,a.jqXHR]);-1===h.inArray(!0,d)&&("parsererror"==c?K(a,0,"Invalid JSON response",1):4===b.readyState&&K(a,0,"Ajax error",7));D(a,!1)}};a.oAjaxData=
-b;u(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(j,a.sAjaxSource,h.map(b,function(a,b){return{name:b,value:a}}),i,a):a.sAjaxSource||"string"===typeof g?a.jqXHR=h.ajax(h.extend(n,{url:g||a.sAjaxSource})):"function"===typeof g?a.jqXHR=g.call(j,b,i,a):(a.jqXHR=h.ajax(h.extend(n,g)),g.data=f)}function nb(a){return a.bAjaxDataGet?(a.iDraw++,D(a,!0),ta(a,wb(a),function(b){xb(a,b)}),!1):!0}function wb(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,f=a.aoPreSearchCols,g,j=
-[],i,n,m,k=Y(a);g=a._iDisplayStart;i=!1!==d.bPaginate?a._iDisplayLength:-1;var r=function(a,b){j.push({name:a,value:b})};r("sEcho",a.iDraw);r("iColumns",c);r("sColumns",C(b,"sName").join(","));r("iDisplayStart",g);r("iDisplayLength",i);var G={draw:a.iDraw,columns:[],order:[],start:g,length:i,search:{value:e.sSearch,regex:e.bRegex}};for(g=0;g<c;g++)n=b[g],m=f[g],i="function"==typeof n.mData?"function":n.mData,G.columns.push({data:i,name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:m.sSearch,
-regex:m.bRegex}}),r("mDataProp_"+g,i),d.bFilter&&(r("sSearch_"+g,m.sSearch),r("bRegex_"+g,m.bRegex),r("bSearchable_"+g,n.bSearchable)),d.bSort&&r("bSortable_"+g,n.bSortable);d.bFilter&&(r("sSearch",e.sSearch),r("bRegex",e.bRegex));d.bSort&&(h.each(k,function(a,b){G.order.push({column:b.col,dir:b.dir});r("iSortCol_"+a,b.col);r("sSortDir_"+a,b.dir)}),r("iSortingCols",k.length));b=l.ext.legacy.ajax;return null===b?a.sAjaxSource?j:G:b?j:G}function xb(a,b){var c=ua(a,b),d=b.sEcho!==k?b.sEcho:b.draw,e=
-b.iTotalRecords!==k?b.iTotalRecords:b.recordsTotal,f=b.iTotalDisplayRecords!==k?b.iTotalDisplayRecords:b.recordsFiltered;if(d!==k){if(1*d<a.iDraw)return;a.iDraw=1*d}pa(a);a._iRecordsTotal=parseInt(e,10);a._iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)O(a,c[d]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;P(a);a._bInitComplete||va(a,b);a.bAjaxDataGet=!0;D(a,!1)}function ua(a,b){var c=h.isPlainObject(a.ajax)&&a.ajax.dataSrc!==k?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===c?
-b.aaData||b[c]:""!==c?S(c)(b):b}function rb(a){var b=a.oClasses,c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,f=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',j=d.sSearch,j=j.match(/_INPUT_/)?j.replace("_INPUT_",g):j+g,b=h("<div/>",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("<label/>").append(j)),i=function(){var b=!this.value?"":this.value;b!=e.sSearch&&(ha(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,P(a))},
-f=null!==a.searchDelay?a.searchDelay:"ssp"===y(a)?400:0,n=h("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",f?Qa(i,f):i).on("mouseup",function(){setTimeout(function(){i.call(n[0])},10)}).on("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);h(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{n[0]!==H.activeElement&&n.val(e.sSearch)}catch(d){}});return b[0]}function ha(a,b,c){var d=a.oPreviousSearch,
-e=a.aoPreSearchCols,f=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};Ia(a);if("ssp"!=y(a)){yb(a,b.sSearch,c,b.bEscapeRegex!==k?!b.bEscapeRegex:b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<e.length;b++)zb(a,e[b].sSearch,b,e[b].bEscapeRegex!==k?!e[b].bEscapeRegex:e[b].bRegex,e[b].bSmart,e[b].bCaseInsensitive);Ab(a)}else f(b);a.bFiltered=!0;u(a,null,"search",[a])}function Ab(a){for(var b=l.ext.search,c=a.aiDisplay,d,e,f=0,g=b.length;f<
-g;f++){for(var j=[],i=0,n=c.length;i<n;i++)e=c[i],d=a.aoData[e],b[f](a,d._aFilterData,e,d._aData,i)&&j.push(e);c.length=0;h.merge(c,j)}}function zb(a,b,c,d,e,f){if(""!==b){for(var g=[],j=a.aiDisplay,d=Ra(b,d,e,f),e=0;e<j.length;e++)b=a.aoData[j[e]]._aFilterData[c],d.test(b)&&g.push(j[e]);a.aiDisplay=g}}function yb(a,b,c,d,e,f){var e=Ra(b,d,e,f),g=a.oPreviousSearch.sSearch,j=a.aiDisplayMaster,i,f=[];0!==l.ext.search.length&&(c=!0);i=Bb(a);if(0>=b.length)a.aiDisplay=j.slice();else{if(i||c||d||g.length>
-b.length||0!==b.indexOf(g)||a.bSorted)a.aiDisplay=j.slice();b=a.aiDisplay;for(c=0;c<b.length;c++)e.test(a.aoData[b[c]]._sFilterRow)&&f.push(b[c]);a.aiDisplay=f}}function Ra(a,b,c,d){a=b?a:Sa(a);c&&(a="^(?=.*?"+h.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0))var b=a.match(/^"(.*)"$/),a=b?b[1]:a;return a.replace('"',"")}).join(")(?=.*?")+").*$");return RegExp(a,d?"i":"")}function Bb(a){var b=a.aoColumns,c,d,e,f,g,j,i,h,m=l.ext.type.search;c=!1;d=0;for(f=a.aoData.length;d<f;d++)if(h=
-a.aoData[d],!h._aFilterData){j=[];e=0;for(g=b.length;e<g;e++)c=b[e],c.bSearchable?(i=B(a,d,e,"filter"),m[c.sType]&&(i=m[c.sType](i)),null===i&&(i=""),"string"!==typeof i&&i.toString&&(i=i.toString())):i="",i.indexOf&&-1!==i.indexOf("&")&&(wa.innerHTML=i,i=Zb?wa.textContent:wa.innerText),i.replace&&(i=i.replace(/[\r\n\u2028]/g,"")),j.push(i);h._aFilterData=j;h._sFilterRow=j.join("  ");c=!0}return c}function Cb(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}
-function Db(a){return{sSearch:a.search,bSmart:a.smart,bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function ub(a){var b=a.sTableId,c=a.aanFeatures.i,d=h("<div/>",{"class":a.oClasses.sInfo,id:!c?b+"_info":null});c||(a.aoDrawCallback.push({fn:Eb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),h(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Eb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),
-g=a.fnRecordsDisplay(),j=g?c.sInfo:c.sInfoEmpty;g!==f&&(j+=" "+c.sInfoFiltered);j+=c.sInfoPostFix;j=Fb(a,j);c=c.fnInfoCallback;null!==c&&(j=c.call(a.oInstance,a,d,e,f,g,j));h(b).html(j)}}function Fb(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,f=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,f)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/
-e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(f/e)))}function ia(a){var b,c,d=a.iInitDisplayStart,e=a.aoColumns,f;c=a.oFeatures;var g=a.bDeferLoading;if(a.bInitialised){pb(a);mb(a);ga(a,a.aoHeader);ga(a,a.aoFooter);D(a,!0);c.bAutoWidth&&Ha(a);b=0;for(c=e.length;b<c;b++)f=e[b],f.sWidth&&(f.nTh.style.width=w(f.sWidth));u(a,null,"preInit",[a]);T(a);e=y(a);if("ssp"!=e||g)"ajax"==e?ta(a,[],function(c){var f=ua(a,c);for(b=0;b<f.length;b++)O(a,f[b]);a.iInitDisplayStart=d;T(a);D(a,!1);va(a,c)},a):(D(a,!1),
-va(a))}else setTimeout(function(){ia(a)},200)}function va(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&aa(a);u(a,null,"plugin-init",[a,b]);u(a,"aoInitComplete","init",[a,b])}function Ta(a,b){var c=parseInt(b,10);a._iDisplayLength=c;Ua(a);u(a,null,"length",[a,c])}function qb(a){for(var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=Array.isArray(d[0]),f=e?d[0]:d,d=e?d[1]:d,e=h("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect}),g=0,j=f.length;g<j;g++)e[0][g]=new Option("number"===
-typeof d[g]?a.fnFormatNumber(d[g]):d[g],f[g]);var i=h("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(i[0].id=c+"_length");i.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",i).val(a._iDisplayLength).on("change.DT",function(){Ta(a,h(this).val());P(a)});h(a.nTable).on("length.dt.DT",function(b,c,d){a===c&&h("select",i).val(d)});return i[0]}function vb(a){var b=a.sPaginationType,c=l.ext.pager[b],d="function"===typeof c,e=function(a){P(a)},b=h("<div/>").addClass(a.oClasses.sPaging+
-b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,i=a._iDisplayLength,h=a.fnRecordsDisplay(),m=-1===i,b=m?0:Math.ceil(b/i),i=m?1:Math.ceil(h/i),h=c(b,i),k,m=0;for(k=f.p.length;m<k;m++)Pa(a,"pageButton")(a,f.p[m],m,h,b,i)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Va(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,f=a.fnRecordsDisplay();0===f||-1===e?d=0:"number"===typeof b?(d=b*e,d>f&&
-(d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e<f&&(d+=e):"last"==b?d=Math.floor((f-1)/e)*e:K(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(u(a,null,"page",[a]),c&&P(a));return b}function sb(a){return h("<div/>",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function D(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");
-u(a,null,"processing",[a,b])}function tb(a){var b=h(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),j=g.length?g[0]._captionSide:null,i=h(b[0].cloneNode(!1)),n=h(b[0].cloneNode(!1)),m=b.children("tfoot");m.length||(m=null);i=h("<div/>",{"class":f.sScrollWrapper}).append(h("<div/>",{"class":f.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?!d?null:w(d):"100%"}).append(h("<div/>",
-{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",width:c.sXInner||"100%"}).append(i.removeAttr("id").css("margin-left",0).append("top"===j?g:null).append(b.children("thead"))))).append(h("<div/>",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:w(d)}).append(b));m&&i.append(h("<div/>",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:w(d):"100%"}).append(h("<div/>",{"class":f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left",
-0).append("bottom"===j?g:null).append(b.children("tfoot")))));var b=i.children(),k=b[0],f=b[1],r=m?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;m&&(r.scrollLeft=a)});h(f).css("max-height",e);c.bCollapse||h(f).css("height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=r;a.aoDrawCallback.push({fn:ma,sName:"scrolling"});return i[0]}function ma(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth,f=h(a.nScrollHead),g=f[0].style,j=f.children("div"),i=j[0].style,
-n=j.children("table"),j=a.nScrollBody,m=h(j),q=j.style,r=h(a.nScrollFoot).children("div"),l=r.children("table"),o=h(a.nTHead),p=h(a.nTable),s=p[0],u=s.style,t=a.nTFoot?h(a.nTFoot):null,U=a.oBrowser,V=U.bScrollOversize,$b=C(a.aoColumns,"nTh"),Q,L,R,xa,v=[],x=[],y=[],z=[],A,B=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};L=j.scrollHeight>j.clientHeight;if(a.scrollBarVis!==L&&a.scrollBarVis!==k)a.scrollBarVis=L,aa(a);else{a.scrollBarVis=
-L;p.children("thead, tfoot").remove();t&&(R=t.clone().prependTo(p),Q=t.find("tr"),R=R.find("tr"));xa=o.clone().prependTo(p);o=o.find("tr");L=xa.find("tr");xa.find("th, td").removeAttr("tabindex");c||(q.width="100%",f[0].style.width="100%");h.each(sa(a,xa),function(b,c){A=ba(a,b);c.style.width=a.aoColumns[A].sWidth});t&&I(function(a){a.style.width=""},R);f=p.outerWidth();if(""===c){u.width="100%";if(V&&(p.find("tbody").height()>j.offsetHeight||"scroll"==m.css("overflow-y")))u.width=w(p.outerWidth()-
-b);f=p.outerWidth()}else""!==d&&(u.width=w(d),f=p.outerWidth());I(B,L);I(function(a){y.push(a.innerHTML);v.push(w(h(a).css("width")))},L);I(function(a,b){if(h.inArray(a,$b)!==-1)a.style.width=v[b]},o);h(L).height(0);t&&(I(B,R),I(function(a){z.push(a.innerHTML);x.push(w(h(a).css("width")))},R),I(function(a,b){a.style.width=x[b]},Q),h(R).height(0));I(function(a,b){a.innerHTML='<div class="dataTables_sizing">'+y[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=
-v[b]},L);t&&I(function(a,b){a.innerHTML='<div class="dataTables_sizing">'+z[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=x[b]},R);if(p.outerWidth()<f){Q=j.scrollHeight>j.offsetHeight||"scroll"==m.css("overflow-y")?f+b:f;if(V&&(j.scrollHeight>j.offsetHeight||"scroll"==m.css("overflow-y")))u.width=w(Q-b);(""===c||""!==d)&&K(a,1,"Possible column misalignment",6)}else Q="100%";q.width=w(Q);g.width=w(Q);t&&(a.nScrollFoot.style.width=w(Q));!e&&V&&(q.height=
-w(s.offsetHeight+b));c=p.outerWidth();n[0].style.width=w(c);i.width=w(c);d=p.height()>j.clientHeight||"scroll"==m.css("overflow-y");e="padding"+(U.bScrollbarLeft?"Left":"Right");i[e]=d?b+"px":"0px";t&&(l[0].style.width=w(c),r[0].style.width=w(c),r[0].style[e]=d?b+"px":"0px");p.children("colgroup").insertBefore(p.children("thead"));m.trigger("scroll");if((a.bSorted||a.bFiltered)&&!a._drawHold)j.scrollTop=0}}function I(a,b,c){for(var d=0,e=0,f=b.length,g,j;e<f;){g=b[e].firstChild;for(j=c?c[e].firstChild:
-null;g;)1===g.nodeType&&(c?a(g,j,d):a(g,d),d++),g=g.nextSibling,j=c?j.nextSibling:null;e++}}function Ha(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,e=d.sY,f=d.sX,g=d.sXInner,j=c.length,i=na(a,"bVisible"),n=h("th",a.nTHead),m=b.getAttribute("width"),k=b.parentNode,r=!1,l,o,p=a.oBrowser,d=p.bScrollOversize;(l=b.style.width)&&-1!==l.indexOf("%")&&(m=l);for(l=0;l<i.length;l++)o=c[i[l]],null!==o.sWidth&&(o.sWidth=Gb(o.sWidthOrig,k),r=!0);if(d||!r&&!f&&!e&&j==W(a)&&j==n.length)for(l=0;l<j;l++)i=ba(a,l),
-null!==i&&(c[i].sWidth=w(n.eq(l).width()));else{j=h(b).clone().css("visibility","hidden").removeAttr("id");j.find("tbody tr").remove();var s=h("<tr/>").appendTo(j.find("tbody"));j.find("thead, tfoot").remove();j.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());j.find("tfoot th, tfoot td").css("width","");n=sa(a,j.find("thead")[0]);for(l=0;l<i.length;l++)o=c[i[l]],n[l].style.width=null!==o.sWidthOrig&&""!==o.sWidthOrig?w(o.sWidthOrig):"",o.sWidthOrig&&f&&h(n[l]).append(h("<div/>").css({width:o.sWidthOrig,
-margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(l=0;l<i.length;l++)r=i[l],o=c[r],h(Hb(a,r)).clone(!1).append(o.sContentPadding).appendTo(s);h("[name]",j).removeAttr("name");o=h("<div/>").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(j).appendTo(k);f&&g?j.width(g):f?(j.css("width","auto"),j.removeAttr("width"),j.width()<k.clientWidth&&m&&j.width(k.clientWidth)):e?j.width(k.clientWidth):m&&j.width(m);for(l=e=0;l<i.length;l++)k=h(n[l]),g=k.outerWidth()-
-k.width(),k=p.bBounding?Math.ceil(n[l].getBoundingClientRect().width):k.outerWidth(),e+=k,c[i[l]].sWidth=w(k-g);b.style.width=w(e);o.remove()}m&&(b.style.width=w(m));if((m||f)&&!a._reszEvt)b=function(){h(E).on("resize.DT-"+a.sInstance,Qa(function(){aa(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0}function Gb(a,b){if(!a)return 0;var c=h("<div/>").css("width",w(a)).appendTo(b||H.body),d=c[0].offsetWidth;c.remove();return d}function Hb(a,b){var c=Ib(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?
-h("<td/>").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Ib(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;f<g;f++)c=B(a,f,b,"display")+"",c=c.replace(ac,""),c=c.replace(/&nbsp;/g," "),c.length>d&&(d=c.length,e=f);return e}function w(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function Y(a){var b,c,d=[],e=a.aoColumns,f,g,j,i;b=a.aaSortingFixed;c=h.isPlainObject(b);var n=[];f=function(a){a.length&&!Array.isArray(a[0])?n.push(a):h.merge(n,a)};Array.isArray(b)&&
-f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;a<n.length;a++){i=n[a][0];f=e[i].aDataSort;b=0;for(c=f.length;b<c;b++)g=f[b],j=e[g].sType||"string",n[a]._idx===k&&(n[a]._idx=h.inArray(n[a][1],e[g].asSorting)),d.push({src:i,col:g,dir:n[a][1],index:n[a]._idx,type:j,formatter:l.ext.type.order[j+"-pre"]})}return d}function ob(a){var b,c,d=[],e=l.ext.type.order,f=a.aoData,g=0,j,i=a.aiDisplayMaster,h;Ia(a);h=Y(a);b=0;for(c=h.length;b<c;b++)j=h[b],j.formatter&&g++,Jb(a,j.col);if("ssp"!=
-y(a)&&0!==h.length){b=0;for(c=i.length;b<c;b++)d[i[b]]=b;g===h.length?i.sort(function(a,b){var c,e,g,j,i=h.length,k=f[a]._aSortData,l=f[b]._aSortData;for(g=0;g<i;g++)if(j=h[g],c=k[j.col],e=l[j.col],c=c<e?-1:c>e?1:0,0!==c)return"asc"===j.dir?c:-c;c=d[a];e=d[b];return c<e?-1:c>e?1:0}):i.sort(function(a,b){var c,g,j,i,k=h.length,l=f[a]._aSortData,o=f[b]._aSortData;for(j=0;j<k;j++)if(i=h[j],c=l[i.col],g=o[i.col],i=e[i.type+"-"+i.dir]||e["string-"+i.dir],c=i(c,g),0!==c)return c;c=d[a];g=d[b];return c<
-g?-1:c>g?1:0})}a.bSorted=!0}function Kb(a){for(var b,c,d=a.aoColumns,e=Y(a),a=a.oLanguage.oAria,f=0,g=d.length;f<g;f++){c=d[f];var j=c.asSorting;b=c.sTitle.replace(/<.*?>/g,"");var i=c.nTh;i.removeAttribute("aria-sort");c.bSortable&&(0<e.length&&e[0].col==f?(i.setAttribute("aria-sort","asc"==e[0].dir?"ascending":"descending"),c=j[e[0].index+1]||j[0]):c=j[0],b+="asc"===c?a.sSortAscending:a.sSortDescending);i.setAttribute("aria-label",b)}}function Wa(a,b,c,d){var e=a.aaSorting,f=a.aoColumns[b].asSorting,
-g=function(a,b){var c=a._idx;c===k&&(c=h.inArray(a[1],f));return c+1<f.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=h.inArray(b,C(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=f[b],e[c]._idx=b)):(e.push([b,f[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=f[b],e[0]._idx=b):(e.length=0,e.push([b,f[0]]),e[0]._idx=0);T(a);"function"==typeof d&&d(a)}function Oa(a,b,c,d){var e=
-a.aoColumns[c];Xa(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(D(a,!0),setTimeout(function(){Wa(a,c,b.shiftKey,d);"ssp"!==y(a)&&D(a,!1)},0)):Wa(a,c,b.shiftKey,d))})}function ya(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=Y(a),e=a.oFeatures,f,g;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)g=b[e].src,h(C(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3));e=0;for(f=d.length;e<f;e++)g=d[e].src,h(C(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Jb(a,
-b){var c=a.aoColumns[b],d=l.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,ca(a,b)));for(var f,g=l.ext.type.order[c.sType+"-pre"],j=0,i=a.aoData.length;j<i;j++)if(c=a.aoData[j],c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)f=d?e[j]:B(a,j,b,"sort"),c._aSortData[b]=g?g(f):f}function za(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:h.extend(!0,[],a.aaSorting),search:Cb(a.oPreviousSearch),columns:h.map(a.aoColumns,
-function(b,d){return{visible:b.bVisible,search:Cb(a.aoPreSearchCols[d])}})};u(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,b)}}function Lb(a,b,c){var d,e,f=a.aoColumns,b=function(b){if(b&&b.time){var g=u(a,"aoStateLoadParams","stateLoadParams",[a,b]);if(-1===h.inArray(!1,g)&&(g=a.iStateDuration,!(0<g&&b.time<+new Date-1E3*g)&&!(b.columns&&f.length!==b.columns.length))){a.oLoadedState=h.extend(!0,{},b);b.start!==k&&(a._iDisplayStart=b.start,
-a.iInitDisplayStart=b.start);b.length!==k&&(a._iDisplayLength=b.length);b.order!==k&&(a.aaSorting=[],h.each(b.order,function(b,c){a.aaSorting.push(c[0]>=f.length?[0,c[1]]:c)}));b.search!==k&&h.extend(a.oPreviousSearch,Db(b.search));if(b.columns){d=0;for(e=b.columns.length;d<e;d++)g=b.columns[d],g.visible!==k&&(f[d].bVisible=g.visible),g.search!==k&&h.extend(a.aoPreSearchCols[d],Db(g.search))}u(a,"aoStateLoaded","stateLoaded",[a,b])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,
-a,b);g!==k&&b(g)}else c()}function Aa(a){var b=l.settings,a=h.inArray(a,C(b,"nTable"));return-1!==a?b[a]:null}function K(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+d);if(b)E.console&&console.log&&console.log(c);else if(b=l.ext,b=b.sErrMode||b.errMode,a&&u(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function F(a,b,c,d){Array.isArray(c)?
-h.each(c,function(c,d){Array.isArray(d)?F(a,b,d[0],d[1]):F(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Ya(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==e&&Array.isArray(d)?d.slice():d);return a}function Xa(a,b,c){h(a).on("click.DT",b,function(b){h(a).trigger("blur");c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}
-function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function u(a,b,c,d){var e=[];b&&(e=h.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=h.Event(c+".dt"),h(a.nTable).trigger(b,d),e.push(b.result));return e}function Ua(a){var b=a._iDisplayStart,c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Pa(a,b){var c=a.renderer,d=l.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===typeof c?d[c]||
-d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ja(a,b){var c=[],c=Mb.numbers_length,d=Math.floor(c/2);b<=c?c=Z(0,b):a<=d?(c=Z(0,c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=Z(b-(c-2),b):(c=Z(a-d+2,a+d-1),c.push("ellipsis"),c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function Fa(a){h.each({num:function(b){return Ba(b,a)},"num-fmt":function(b){return Ba(b,a,Za)},"html-num":function(b){return Ba(b,a,Ca)},"html-num-fmt":function(b){return Ba(b,
-a,Ca,Za)}},function(b,c){v.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(v.type.search[b+a]=v.type.search.html)})}function Nb(a){return function(){var b=[Aa(this[l.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return l.ext.internal[a].apply(this,b)}}var l=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new s(Aa(this[v.iApiIndex])):new s(this)};this.fnAddData=function(a,b){var c=this.api(!0),
-d=Array.isArray(a)&&(Array.isArray(a[0])||h.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&ma(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0),a=d.rows(a),e=
-a.settings()[0],h=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,h);(c===k||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,h){e=this.api(!0);null===b||b===k?e.search(a,c,d,h):e.column(b).search(a,c,d,h);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};
-this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){var c=this.api(!0).page(a);
-(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return Aa(this[v.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===k||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===k||e)&&h.columns.adjust();(d===k||d)&&h.draw();return 0};this.fnVersionCheck=
-v.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=v.internal;for(var e in l.ext.internal)e&&(this[e]=Nb(e));this.each(function(){var e={},g=1<d?Ya(e,a,!0):a,j=0,i,e=this.getAttribute("id"),n=!1,m=l.defaults,q=h(this);if("table"!=this.nodeName.toLowerCase())K(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{gb(m);hb(m.column);J(m,m,!0);J(m.column,m.column,!0);J(m,h.extend(g,q.data()),!0);var r=l.settings,j=0;for(i=r.length;j<i;j++){var o=r[j];if(o.nTable==
-this||o.nTHead&&o.nTHead.parentNode==this||o.nTFoot&&o.nTFoot.parentNode==this){var s=g.bRetrieve!==k?g.bRetrieve:m.bRetrieve;if(c||s)return o.oInstance;if(g.bDestroy!==k?g.bDestroy:m.bDestroy){o.oInstance.fnDestroy();break}else{K(o,0,"Cannot reinitialise DataTable",3);return}}if(o.sTableId==this.id){r.splice(j,1);break}}if(null===e||""===e)this.id=e="DataTables_Table_"+l.ext._unique++;var p=h.extend(!0,{},l.models.oSettings,{sDestroyWidth:q[0].style.width,sInstance:e,sTableId:e});p.nTable=this;p.oApi=
-b.internal;p.oInit=g;r.push(p);p.oInstance=1===b.length?b:q.dataTable();gb(g);Ea(g.oLanguage);g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=Array.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]);g=Ya(h.extend(!0,{},m),g);F(p.oFeatures,g,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));F(p,g,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu",
-"sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"]]);F(p.oScroll,g,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);F(p.oLanguage,g,"fnInfoCallback");z(p,"aoDrawCallback",g.fnDrawCallback,
-"user");z(p,"aoServerParams",g.fnServerParams,"user");z(p,"aoStateSaveParams",g.fnStateSaveParams,"user");z(p,"aoStateLoadParams",g.fnStateLoadParams,"user");z(p,"aoStateLoaded",g.fnStateLoaded,"user");z(p,"aoRowCallback",g.fnRowCallback,"user");z(p,"aoRowCreatedCallback",g.fnCreatedRow,"user");z(p,"aoHeaderCallback",g.fnHeaderCallback,"user");z(p,"aoFooterCallback",g.fnFooterCallback,"user");z(p,"aoInitComplete",g.fnInitComplete,"user");z(p,"aoPreDrawCallback",g.fnPreDrawCallback,"user");p.rowIdFn=
-S(g.rowId);ib(p);var t=p.oClasses;h.extend(t,l.ext.classes,g.oClasses);q.addClass(t.sTable);p.iInitDisplayStart===k&&(p.iInitDisplayStart=g.iDisplayStart,p._iDisplayStart=g.iDisplayStart);null!==g.iDeferLoading&&(p.bDeferLoading=!0,e=Array.isArray(g.iDeferLoading),p._iRecordsDisplay=e?g.iDeferLoading[0]:g.iDeferLoading,p._iRecordsTotal=e?g.iDeferLoading[1]:g.iDeferLoading);var w=p.oLanguage;h.extend(!0,w,g.oLanguage);w.sUrl&&(h.ajax({dataType:"json",url:w.sUrl,success:function(a){Ea(a);J(m.oLanguage,
-a);h.extend(true,w,a);ia(p)},error:function(){ia(p)}}),n=!0);null===g.asStripeClasses&&(p.asStripeClasses=[t.sStripeOdd,t.sStripeEven]);var e=p.asStripeClasses,v=q.children("tbody").find("tr").eq(0);-1!==h.inArray(!0,h.map(e,function(a){return v.hasClass(a)}))&&(h("tbody tr",this).removeClass(e.join(" ")),p.asDestroyStripes=e.slice());e=[];r=this.getElementsByTagName("thead");0!==r.length&&(fa(p.aoHeader,r[0]),e=sa(p));if(null===g.aoColumns){r=[];j=0;for(i=e.length;j<i;j++)r.push(null)}else r=g.aoColumns;
-j=0;for(i=r.length;j<i;j++)Ga(p,e?e[j]:null);kb(p,g.aoColumnDefs,r,function(a,b){la(p,a,b)});if(v.length){var U=function(a,b){return a.getAttribute("data-"+b)!==null?b:null};h(v[0]).children("th, td").each(function(a,b){var c=p.aoColumns[a];if(c.mData===a){var d=U(b,"sort")||U(b,"order"),e=U(b,"filter")||U(b,"search");if(d!==null||e!==null){c.mData={_:a+".display",sort:d!==null?a+".@data-"+d:k,type:d!==null?a+".@data-"+d:k,filter:e!==null?a+".@data-"+e:k};la(p,a)}}})}var V=p.oFeatures,e=function(){if(g.aaSorting===
-k){var a=p.aaSorting;j=0;for(i=a.length;j<i;j++)a[j][1]=p.aoColumns[j].asSorting[0]}ya(p);V.bSort&&z(p,"aoDrawCallback",function(){if(p.bSorted){var a=Y(p),b={};h.each(a,function(a,c){b[c.src]=c.dir});u(p,null,"order",[p,a,b]);Kb(p)}});z(p,"aoDrawCallback",function(){(p.bSorted||y(p)==="ssp"||V.bDeferRender)&&ya(p)},"sc");var a=q.children("caption").each(function(){this._captionSide=h(this).css("caption-side")}),b=q.children("thead");b.length===0&&(b=h("<thead/>").appendTo(q));p.nTHead=b[0];b=q.children("tbody");
-b.length===0&&(b=h("<tbody/>").appendTo(q));p.nTBody=b[0];b=q.children("tfoot");if(b.length===0&&a.length>0&&(p.oScroll.sX!==""||p.oScroll.sY!==""))b=h("<tfoot/>").appendTo(q);if(b.length===0||b.children().length===0)q.addClass(t.sNoFooter);else if(b.length>0){p.nTFoot=b[0];fa(p.aoFooter,p.nTFoot)}if(g.aaData)for(j=0;j<g.aaData.length;j++)O(p,g.aaData[j]);else(p.bDeferLoading||y(p)=="dom")&&oa(p,h(p.nTBody).children("tr"));p.aiDisplay=p.aiDisplayMaster.slice();p.bInitialised=true;n===false&&ia(p)};
-g.bStateSave?(V.bStateSave=!0,z(p,"aoDrawCallback",za,"state_save"),Lb(p,g,e)):e()}});b=null;return this},v,s,o,t,$a={},Ob=/[\r\n\u2028]/g,Ca=/<.*?>/g,bc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,cc=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Za=/['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,M=function(a){return!a||!0===a||"-"===a?!0:!1},Pb=function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},Qb=
-function(a,b){$a[b]||($a[b]=RegExp(Sa(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace($a[b],"."):a},ab=function(a,b,c){var d="string"===typeof a;if(M(a))return!0;b&&d&&(a=Qb(a,b));c&&d&&(a=a.replace(Za,""));return!isNaN(parseFloat(a))&&isFinite(a)},Rb=function(a,b,c){return M(a)?!0:!(M(a)||"string"===typeof a)?null:ab(a.replace(Ca,""),b,c)?!0:null},C=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;e<f;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<f;e++)a[e]&&d.push(a[e][b]);
-return d},ka=function(a,b,c,d){var e=[],f=0,g=b.length;if(d!==k)for(;f<g;f++)a[b[f]][c]&&e.push(a[b[f]][c][d]);else for(;f<g;f++)e.push(a[b[f]][c]);return e},Z=function(a,b){var c=[],d;b===k?(b=0,d=a):(d=b,b=a);for(var e=b;e<d;e++)c.push(e);return c},Sb=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},ra=function(a){var b;a:{if(!(2>a.length)){b=a.slice().sort();for(var c=b[0],d=1,e=b.length;d<e;d++){if(b[d]===c){b=!1;break a}c=b[d]}}b=!0}if(b)return a.slice();b=[];var e=
-a.length,f,g=0,d=0;a:for(;d<e;d++){c=a[d];for(f=0;f<g;f++)if(b[f]===c)continue a;b.push(c);g++}return b},Tb=function(a,b){if(Array.isArray(b))for(var c=0;c<b.length;c++)Tb(a,b[c]);else a.push(b);return a};Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});l.util={throttle:function(a,b){var c=b!==k?b:200,d,e;return function(){var b=
-this,g=+new Date,j=arguments;if(d&&g<d+c){clearTimeout(e);e=setTimeout(function(){d=k;a.apply(b,j)},c)}else{d=g;a.apply(b,j)}}},escapeRegex:function(a){return a.replace(cc,"\\$1")}};var A=function(a,b,c){a[b]!==k&&(a[c]=a[b])},da=/\[.*?\]$/,X=/\(\)$/,Sa=l.util.escapeRegex,wa=h("<div>")[0],Zb=wa.textContent!==k,ac=/<.*?>/g,Qa=l.util.throttle,Ub=[],x=Array.prototype,dc=function(a){var b,c,d=l.settings,e=h.map(d,function(a){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&a.nodeName.toLowerCase()===
-"table"){b=h.inArray(a,e);return b!==-1?[d[b]]:null}if(a&&typeof a.settings==="function")return a.settings().toArray();typeof a==="string"?c=h(a):a instanceof h&&(c=a)}else return[];if(c)return c.map(function(){b=h.inArray(this,e);return b!==-1?d[b]:null}).toArray()};s=function(a,b){if(!(this instanceof s))return new s(a,b);var c=[],d=function(a){(a=dc(a))&&c.push.apply(c,a)};if(Array.isArray(a))for(var e=0,f=a.length;e<f;e++)d(a[e]);else d(a);this.context=ra(c);b&&h.merge(this,b);this.selector={rows:null,
-cols:null,opts:null};s.extend(this,this,Ub)};l.Api=s;h.extend(s.prototype,{any:function(){return this.count()!==0},concat:x.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=this.context;return b.length>a?new s(b[a],this[a]):null},filter:function(a){var b=[];if(x.filter)b=x.filter.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);
-return new s(this.context,b)},flatten:function(){var a=[];return new s(this.context,a.concat.apply(a,this.toArray()))},join:x.join,indexOf:x.indexOf||function(a,b){for(var c=b||0,d=this.length;c<d;c++)if(this[c]===a)return c;return-1},iterator:function(a,b,c,d){var e=[],f,g,j,i,h,m=this.context,l,o,t=this.selector;if(typeof a==="string"){d=c;c=b;b=a;a=false}g=0;for(j=m.length;g<j;g++){var u=new s(m[g]);if(b==="table"){f=c.call(u,m[g],g);f!==k&&e.push(f)}else if(b==="columns"||b==="rows"){f=c.call(u,
-m[g],this[g],g);f!==k&&e.push(f)}else if(b==="column"||b==="column-rows"||b==="row"||b==="cell"){o=this[g];b==="column-rows"&&(l=Da(m[g],t.opts));i=0;for(h=o.length;i<h;i++){f=o[i];f=b==="cell"?c.call(u,m[g],f.row,f.column,g,i):c.call(u,m[g],f,g,i,l);f!==k&&e.push(f)}}}if(e.length||d){a=new s(m,a?e.concat.apply([],e):e);b=a.selector;b.rows=t.rows;b.cols=t.cols;b.opts=t.opts;return a}return this},lastIndexOf:x.lastIndexOf||function(a,b){return this.indexOf.apply(this.toArray.reverse(),arguments)},
-length:0,map:function(a){var b=[];if(x.map)b=x.map.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new s(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:x.pop,push:x.push,reduce:x.reduce||function(a,b){return jb(this,a,b,0,this.length,1)},reduceRight:x.reduceRight||function(a,b){return jb(this,a,b,this.length-1,-1,-1)},reverse:x.reverse,selector:null,shift:x.shift,slice:function(){return new s(this.context,this)},sort:x.sort,
-splice:x.splice,toArray:function(){return x.slice.call(this)},to$:function(){return h(this)},toJQuery:function(){return h(this)},unique:function(){return new s(this.context,ra(this))},unshift:x.unshift});s.extend=function(a,b,c){if(c.length&&b&&(b instanceof s||b.__dt_wrapper)){var d,e,f,g=function(a,b,c){return function(){var d=b.apply(a,arguments);s.extend(d,d,c.methodExt);return d}};d=0;for(e=c.length;d<e;d++){f=c[d];b[f.name]=f.type==="function"?g(a,f.val,f):f.type==="object"?{}:f.val;b[f.name].__dt_wrapper=
-true;s.extend(a,b[f.name],f.propExt)}}};s.register=o=function(a,b){if(Array.isArray(a))for(var c=0,d=a.length;c<d;c++)s.register(a[c],b);else for(var e=a.split("."),f=Ub,g,j,c=0,d=e.length;c<d;c++){g=(j=e[c].indexOf("()")!==-1)?e[c].replace("()",""):e[c];var i;a:{i=0;for(var k=f.length;i<k;i++)if(f[i].name===g){i=f[i];break a}i=null}if(!i){i={name:g,val:{},methodExt:[],propExt:[],type:"object"};f.push(i)}if(c===d-1){i.val=b;i.type=typeof b==="function"?"function":h.isPlainObject(b)?"object":"other"}else f=
-j?i.methodExt:i.propExt}};s.registerPlural=t=function(a,b,c){s.register(a,c);s.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof s?a.length?Array.isArray(a[0])?new s(a.context,a[0]):a[0]:k:a})};var Vb=function(a,b){if(Array.isArray(a))return h.map(a,function(a){return Vb(a,b)});if(typeof a==="number")return[b[a]];var c=h.map(b,function(a){return a.nTable});return h(c).filter(a).map(function(){var a=h.inArray(this,c);return b[a]}).toArray()};o("tables()",function(a){return a!==
-k&&a!==null?new s(Vb(a,this.context)):this});o("table()",function(a){var a=this.tables(a),b=a.context;return b.length?new s(b[0]):a});t("tables().nodes()","table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});t("tables().body()","table().body()",function(){return this.iterator("table",function(a){return a.nTBody},1)});t("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});t("tables().footer()","table().footer()",
-function(){return this.iterator("table",function(a){return a.nTFoot},1)});t("tables().containers()","table().container()",function(){return this.iterator("table",function(a){return a.nTableWrapper},1)});o("draw()",function(a){return this.iterator("table",function(b){if(a==="page")P(b);else{typeof a==="string"&&(a=a==="full-hold"?false:true);T(b,a===false)}})});o("page()",function(a){return a===k?this.page.info().page:this.iterator("table",function(b){Va(b,a)})});o("page.info()",function(){if(this.context.length===
-0)return k;var a=this.context[0],b=a._iDisplayStart,c=a.oFeatures.bPaginate?a._iDisplayLength:-1,d=a.fnRecordsDisplay(),e=c===-1;return{page:e?0:Math.floor(b/c),pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,serverSide:y(a)==="ssp"}});o("page.len()",function(a){return a===k?this.context.length!==0?this.context[0]._iDisplayLength:k:this.iterator("table",function(b){Ta(b,a)})});var Wb=function(a,b,c){if(c){var d=new s(a);d.one("draw",
-function(){c(d.ajax.json())})}if(y(a)=="ssp")T(a,b);else{D(a,true);var e=a.jqXHR;e&&e.readyState!==4&&e.abort();ta(a,[],function(c){pa(a);for(var c=ua(a,c),d=0,e=c.length;d<e;d++)O(a,c[d]);T(a,b);D(a,false)})}};o("ajax.json()",function(){var a=this.context;if(a.length>0)return a[0].json});o("ajax.params()",function(){var a=this.context;if(a.length>0)return a[0].oAjaxData});o("ajax.reload()",function(a,b){return this.iterator("table",function(c){Wb(c,b===false,a)})});o("ajax.url()",function(a){var b=
-this.context;if(a===k){if(b.length===0)return k;b=b[0];return b.ajax?h.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){h.isPlainObject(b.ajax)?b.ajax.url=a:b.ajax=a})});o("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Wb(c,b===false,a)})});var bb=function(a,b,c,d,e){var f=[],g,j,i,h,m,l;i=typeof b;if(!b||i==="string"||i==="function"||b.length===k)b=[b];i=0;for(h=b.length;i<h;i++){j=b[i]&&b[i].split&&!b[i].match(/[\[\(:]/)?
-b[i].split(","):[b[i]];m=0;for(l=j.length;m<l;m++)(g=c(typeof j[m]==="string"?j[m].trim():j[m]))&&g.length&&(f=f.concat(g))}a=v.selector[a];if(a.length){i=0;for(h=a.length;i<h;i++)f=a[i](d,e,f)}return ra(f)},cb=function(a){a||(a={});if(a.filter&&a.search===k)a.search=a.filter;return h.extend({search:"none",order:"current",page:"all"},a)},db=function(a){for(var b=0,c=a.length;b<c;b++)if(a[b].length>0){a[0]=a[b];a[0].length=1;a.length=1;a.context=[a.context[b]];return a}a.length=0;return a},Da=function(a,
-b){var c,d,e,f=[],g=a.aiDisplay;e=a.aiDisplayMaster;var j=b.search;c=b.order;d=b.page;if(y(a)=="ssp")return j==="removed"?[]:Z(0,e.length);if(d=="current"){c=a._iDisplayStart;for(d=a.fnDisplayEnd();c<d;c++)f.push(g[c])}else if(c=="current"||c=="applied")if(j=="none")f=e.slice();else if(j=="applied")f=g.slice();else{if(j=="removed"){var i={};c=0;for(d=g.length;c<d;c++)i[g[c]]=null;f=h.map(e,function(a){return!i.hasOwnProperty(a)?a:null})}}else if(c=="index"||c=="original"){c=0;for(d=a.aoData.length;c<
-d;c++)if(j=="none")f.push(c);else{e=h.inArray(c,g);(e===-1&&j=="removed"||e>=0&&j=="applied")&&f.push(c)}}return f};o("rows()",function(a,b){if(a===k)a="";else if(h.isPlainObject(a)){b=a;a=""}var b=cb(b),c=this.iterator("table",function(c){var e=b,f;return bb("row",a,function(a){var b=Pb(a),i=c.aoData;if(b!==null&&!e)return[b];f||(f=Da(c,e));if(b!==null&&h.inArray(b,f)!==-1)return[b];if(a===null||a===k||a==="")return f;if(typeof a==="function")return h.map(f,function(b){var c=i[b];return a(b,c._aData,
-c.nTr)?b:null});if(a.nodeName){var b=a._DT_RowIndex,n=a._DT_CellIndex;if(b!==k)return i[b]&&i[b].nTr===a?[b]:[];if(n)return i[n.row]&&i[n.row].nTr===a.parentNode?[n.row]:[];b=h(a).closest("*[data-dt-row]");return b.length?[b.data("dt-row")]:[]}if(typeof a==="string"&&a.charAt(0)==="#"){b=c.aIds[a.replace(/^#/,"")];if(b!==k)return[b.idx]}b=Sb(ka(c.aoData,f,"nTr"));return h(b).filter(a).map(function(){return this._DT_RowIndex}).toArray()},c,e)},1);c.selector.rows=a;c.selector.opts=b;return c});o("rows().nodes()",
-function(){return this.iterator("row",function(a,b){return a.aoData[b].nTr||k},1)});o("rows().data()",function(){return this.iterator(true,"rows",function(a,b){return ka(a.aoData,b,"_aData")},1)});t("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){var d=b.aoData[c];return a==="search"?d._aFilterData:d._aSortData},1)});t("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",function(b,c){ea(b,c,a)})});t("rows().indexes()","row().index()",
-function(){return this.iterator("row",function(a,b){return b},1)});t("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var h=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((a===true?"#":"")+h)}return new s(c,b)});t("rows().remove()","row().remove()",function(){var a=this;this.iterator("row",function(b,c,d){var e=b.aoData,f=e[c],g,h,i,n,m;e.splice(c,1);g=0;for(h=e.length;g<h;g++){i=e[g];m=i.anCells;if(i.nTr!==null)i.nTr._DT_RowIndex=
-g;if(m!==null){i=0;for(n=m.length;i<n;i++)m[i]._DT_CellIndex.row=g}}qa(b.aiDisplayMaster,c);qa(b.aiDisplay,c);qa(a[d],c,false);b._iRecordsDisplay>0&&b._iRecordsDisplay--;Ua(b);c=b.rowIdFn(f._aData);c!==k&&delete b.aIds[c]});this.iterator("table",function(a){for(var c=0,d=a.aoData.length;c<d;c++)a.aoData[c].idx=c});return this});o("rows.add()",function(a){var b=this.iterator("table",function(b){var c,f,g,h=[];f=0;for(g=a.length;f<g;f++){c=a[f];c.nodeName&&c.nodeName.toUpperCase()==="TR"?h.push(oa(b,
-c)[0]):h.push(O(b,c))}return h},1),c=this.rows(-1);c.pop();h.merge(c,b);return c});o("row()",function(a,b){return db(this.rows(a,b))});o("row().data()",function(a){var b=this.context;if(a===k)return b.length&&this.length?b[0].aoData[this[0]]._aData:k;var c=b[0].aoData[this[0]];c._aData=a;Array.isArray(a)&&(c.nTr&&c.nTr.id)&&N(b[0].rowId)(a,c.nTr.id);ea(b[0],this[0],"data");return this});o("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});
-o("row.add()",function(a){a instanceof h&&a.length&&(a=a[0]);var b=this.iterator("table",function(b){return a.nodeName&&a.nodeName.toUpperCase()==="TR"?oa(b,a)[0]:O(b,a)});return this.row(b[0])});var eb=function(a,b){var c=a.context;if(c.length)if((c=c[0].aoData[b!==k?b:a[0]])&&c._details){c._details.remove();c._detailsShow=k;c._details=k}},Xb=function(a,b){var c=a.context;if(c.length&&a.length){var d=c[0].aoData[a[0]];if(d._details){(d._detailsShow=b)?d._details.insertAfter(d.nTr):d._details.detach();
-var e=c[0],f=new s(e),g=e.aoData;f.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");if(C(g,"_details").length>0){f.on("draw.dt.DT_details",function(a,b){e===b&&f.rows({page:"current"}).eq(0).each(function(a){a=g[a];a._detailsShow&&a._details.insertAfter(a.nTr)})});f.on("column-visibility.dt.DT_details",function(a,b){if(e===b)for(var c,d=W(b),f=0,h=g.length;f<h;f++){c=g[f];c._details&&c._details.children("td[colspan]").attr("colspan",d)}});f.on("destroy.dt.DT_details",
-function(a,b){if(e===b)for(var c=0,d=g.length;c<d;c++)g[c]._details&&eb(f,c)})}}}};o("row().child()",function(a,b){var c=this.context;if(a===k)return c.length&&this.length?c[0].aoData[this[0]]._details:k;if(a===true)this.child.show();else if(a===false)eb(this);else if(c.length&&this.length){var d=c[0],c=c[0].aoData[this[0]],e=[],f=function(a,b){if(Array.isArray(a)||a instanceof h)for(var c=0,k=a.length;c<k;c++)f(a[c],b);else if(a.nodeName&&a.nodeName.toLowerCase()==="tr")e.push(a);else{c=h("<tr><td></td></tr>").addClass(b);
-h("td",c).addClass(b).html(a)[0].colSpan=W(d);e.push(c[0])}};f(a,b);c._details&&c._details.detach();c._details=h(e);c._detailsShow&&c._details.insertAfter(c.nTr)}return this});o(["row().child.show()","row().child().show()"],function(){Xb(this,true);return this});o(["row().child.hide()","row().child().hide()"],function(){Xb(this,false);return this});o(["row().child.remove()","row().child().remove()"],function(){eb(this);return this});o("row().child.isShown()",function(){var a=this.context;return a.length&&
-this.length?a[0].aoData[this[0]]._detailsShow||false:false});var ec=/^([^:]+):(name|visIdx|visible)$/,Yb=function(a,b,c,d,e){for(var c=[],d=0,f=e.length;d<f;d++)c.push(B(a,e[d],b));return c};o("columns()",function(a,b){if(a===k)a="";else if(h.isPlainObject(a)){b=a;a=""}var b=cb(b),c=this.iterator("table",function(c){var e=a,f=b,g=c.aoColumns,j=C(g,"sName"),i=C(g,"nTh");return bb("column",e,function(a){var b=Pb(a);if(a==="")return Z(g.length);if(b!==null)return[b>=0?b:g.length+b];if(typeof a==="function"){var e=
-Da(c,f);return h.map(g,function(b,f){return a(f,Yb(c,f,0,0,e),i[f])?f:null})}var k=typeof a==="string"?a.match(ec):"";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],10);if(b<0){var l=h.map(g,function(a,b){return a.bVisible?b:null});return[l[l.length+b]]}return[ba(c,b)];case "name":return h.map(j,function(a,b){return a===k[1]?b:null});default:return[]}if(a.nodeName&&a._DT_CellIndex)return[a._DT_CellIndex.column];b=h(i).filter(a).map(function(){return h.inArray(this,i)}).toArray();if(b.length||
-!a.nodeName)return b;b=h(a).closest("*[data-dt-column]");return b.length?[b.data("dt-column")]:[]},c,f)},1);c.selector.cols=a;c.selector.opts=b;return c});t("columns().header()","column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});t("columns().footer()","column().footer()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});t("columns().data()","column().data()",function(){return this.iterator("column-rows",Yb,
-1)});t("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});t("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ka(b.aoData,f,a==="search"?"_aFilterData":"_aSortData",c)},1)});t("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ka(a.aoData,e,"anCells",b)},1)});t("columns().visible()","column().visible()",
-function(a,b){var c=this,d=this.iterator("column",function(b,c){if(a===k)return b.aoColumns[c].bVisible;var d=b.aoColumns,j=d[c],i=b.aoData,n,m,l;if(a!==k&&j.bVisible!==a){if(a){var o=h.inArray(true,C(d,"bVisible"),c+1);n=0;for(m=i.length;n<m;n++){l=i[n].nTr;d=i[n].anCells;l&&l.insertBefore(d[c],d[o]||null)}}else h(C(b.aoData,"anCells",c)).detach();j.bVisible=a}});a!==k&&this.iterator("table",function(d){ga(d,d.aoHeader);ga(d,d.aoFooter);d.aiDisplay.length||h(d.nTBody).find("td[colspan]").attr("colspan",
-W(d));za(d);c.iterator("column",function(c,d){u(c,null,"column-visibility",[c,d,a,b])});(b===k||b)&&c.columns.adjust()});return d});t("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return a==="visible"?ca(b,c):c},1)});o("columns.adjust()",function(){return this.iterator("table",function(a){aa(a)},1)});o("column.index()",function(a,b){if(this.context.length!==0){var c=this.context[0];if(a==="fromVisible"||a==="toData")return ba(c,b);if(a==="fromData"||
-a==="toVisible")return ca(c,b)}});o("column()",function(a,b){return db(this.columns(a,b))});o("cells()",function(a,b,c){if(h.isPlainObject(a))if(a.row===k){c=a;a=null}else{c=b;b=null}if(h.isPlainObject(b)){c=b;b=null}if(b===null||b===k)return this.iterator("table",function(b){var d=a,e=cb(c),f=b.aoData,g=Da(b,e),i=Sb(ka(f,g,"anCells")),j=h(Tb([],i)),l,n=b.aoColumns.length,o,t,s,u,w,v;return bb("cell",d,function(a){var c=typeof a==="function";if(a===null||a===k||c){o=[];t=0;for(s=g.length;t<s;t++){l=
-g[t];for(u=0;u<n;u++){w={row:l,column:u};if(c){v=f[l];a(w,B(b,l,u),v.anCells?v.anCells[u]:null)&&o.push(w)}else o.push(w)}}return o}if(h.isPlainObject(a))return a.column!==k&&a.row!==k&&h.inArray(a.row,g)!==-1?[a]:[];c=j.filter(a).map(function(a,b){return{row:b._DT_CellIndex.row,column:b._DT_CellIndex.column}}).toArray();if(c.length||!a.nodeName)return c;v=h(a).closest("*[data-dt-row]");return v.length?[{row:v.data("dt-row"),column:v.data("dt-column")}]:[]},b,e)});var d=c?{page:c.page,order:c.order,
-search:c.search}:{},e=this.columns(b,d),f=this.rows(a,d),g,j,i,l,d=this.iterator("table",function(a,b){var c=[];g=0;for(j=f[b].length;g<j;g++){i=0;for(l=e[b].length;i<l;i++)c.push({row:f[b][g],column:e[b][i]})}return c},1),d=c&&c.selected?this.cells(d,c):d;h.extend(d.selector,{cols:b,rows:a,opts:c});return d});t("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=a.aoData[b])&&a.anCells?a.anCells[c]:k},1)});o("cells().data()",function(){return this.iterator("cell",
-function(a,b,c){return B(a,b,c)},1)});t("cells().cache()","cell().cache()",function(a){a=a==="search"?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});t("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return B(b,c,d,a)},1)});t("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(a,b,c){return{row:b,column:c,columnVisible:ca(a,c)}},1)});t("cells().invalidate()","cell().invalidate()",
-function(a){return this.iterator("cell",function(b,c,d){ea(b,c,a,d)})});o("cell()",function(a,b,c){return db(this.cells(a,b,c))});o("cell().data()",function(a){var b=this.context,c=this[0];if(a===k)return b.length&&c.length?B(b[0],c[0].row,c[0].column):k;lb(b[0],c[0].row,c[0].column,a);ea(b[0],c[0].row,"data",c[0].column);return this});o("order()",function(a,b){var c=this.context;if(a===k)return c.length!==0?c[0].aaSorting:k;typeof a==="number"?a=[[a,b]]:a.length&&!Array.isArray(a[0])&&(a=Array.prototype.slice.call(arguments));
-return this.iterator("table",function(b){b.aaSorting=a.slice()})});o("order.listener()",function(a,b,c){return this.iterator("table",function(d){Oa(d,a,b,c)})});o("order.fixed()",function(a){if(!a){var b=this.context,b=b.length?b[0].aaSortingFixed:k;return Array.isArray(b)?{pre:b}:b}return this.iterator("table",function(b){b.aaSortingFixed=h.extend(true,{},a)})});o(["columns().order()","column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];h.each(b[d],function(b,
-c){e.push([c,a])});c.aaSorting=e})});o("search()",function(a,b,c,d){var e=this.context;return a===k?e.length!==0?e[0].oPreviousSearch.sSearch:k:this.iterator("table",function(e){e.oFeatures.bFilter&&ha(e,h.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:b===null?false:b,bSmart:c===null?true:c,bCaseInsensitive:d===null?true:d}),1)})});t("columns().search()","column().search()",function(a,b,c,d){return this.iterator("column",function(e,f){var g=e.aoPreSearchCols;if(a===k)return g[f].sSearch;if(e.oFeatures.bFilter){h.extend(g[f],
-{sSearch:a+"",bRegex:b===null?false:b,bSmart:c===null?true:c,bCaseInsensitive:d===null?true:d});ha(e,e.oPreviousSearch,1)}})});o("state()",function(){return this.context.length?this.context[0].oSavedState:null});o("state.clear()",function(){return this.iterator("table",function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});o("state.loaded()",function(){return this.context.length?this.context[0].oLoadedState:null});o("state.save()",function(){return this.iterator("table",function(a){za(a)})});
-l.versionCheck=l.fnVersionCheck=function(a){for(var b=l.version.split("."),a=a.split("."),c,d,e=0,f=a.length;e<f;e++){c=parseInt(b[e],10)||0;d=parseInt(a[e],10)||0;if(c!==d)return c>d}return true};l.isDataTable=l.fnIsDataTable=function(a){var b=h(a).get(0),c=false;if(a instanceof l.Api)return true;h.each(l.settings,function(a,e){var f=e.nScrollHead?h("table",e.nScrollHead)[0]:null,g=e.nScrollFoot?h("table",e.nScrollFoot)[0]:null;if(e.nTable===b||f===b||g===b)c=true});return c};l.tables=l.fnTables=
-function(a){var b=false;if(h.isPlainObject(a)){b=a.api;a=a.visible}var c=h.map(l.settings,function(b){if(!a||a&&h(b.nTable).is(":visible"))return b.nTable});return b?new s(c):c};l.camelToHungarian=J;o("$()",function(a,b){var c=this.rows(b).nodes(),c=h(c);return h([].concat(c.filter(a).toArray(),c.find(a).toArray()))});h.each(["on","one","off"],function(a,b){o(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0]=h.map(a[0].split(/\s/),function(a){return!a.match(/\.dt\b/)?a+".dt":a}).join(" ");
-var d=h(this.tables().nodes());d[b].apply(d,a);return this})});o("clear()",function(){return this.iterator("table",function(a){pa(a)})});o("settings()",function(){return new s(this.context,this.context)});o("init()",function(){var a=this.context;return a.length?a[0].oInit:null});o("data()",function(){return this.iterator("table",function(a){return C(a.aoData,"_aData")}).flatten()});o("destroy()",function(a){a=a||false;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,
-e=b.nTable,f=b.nTBody,g=b.nTHead,j=b.nTFoot,i=h(e),f=h(f),k=h(b.nTableWrapper),m=h.map(b.aoData,function(a){return a.nTr}),o;b.bDestroying=true;u(b,"aoDestroyCallback","destroy",[b]);a||(new s(b)).columns().visible(true);k.off(".DT").find(":not(tbody *)").off(".DT");h(E).off(".DT-"+b.sInstance);if(e!=g.parentNode){i.children("thead").detach();i.append(g)}if(j&&e!=j.parentNode){i.children("tfoot").detach();i.append(j)}b.aaSorting=[];b.aaSortingFixed=[];ya(b);h(m).removeClass(b.asStripeClasses.join(" "));
-h("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);f.children().detach();f.append(m);g=a?"remove":"detach";i[g]();k[g]();if(!a&&c){c.insertBefore(e,b.nTableReinsertBefore);i.css("width",b.sDestroyWidth).removeClass(d.sTable);(o=b.asDestroyStripes.length)&&f.children().each(function(a){h(this).addClass(b.asDestroyStripes[a%o])})}c=h.inArray(b,l.settings);c!==-1&&l.settings.splice(c,1)})});h.each(["column","row","cell"],function(a,b){o(b+"s().every()",
-function(a){var d=this.selector.opts,e=this;return this.iterator(b,function(f,g,h,i,l){a.call(e[b](g,b==="cell"?h:d,b==="cell"?d:k),g,h,i,l)})})});o("i18n()",function(a,b,c){var d=this.context[0],a=S(a)(d.oLanguage);a===k&&(a=b);c!==k&&h.isPlainObject(a)&&(a=a[c]!==k?a[c]:a._);return a.replace("%d",c)});l.version="1.10.23";l.settings=[];l.models={};l.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};l.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,
-_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};l.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};l.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],
-ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,
-fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((a.iStateDuration===-1?sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){return{}}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(a.iStateDuration===-1?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},
-fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",
-sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:h.extend({},l.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};$(l.defaults);l.defaults.column={aDataSort:null,
-iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};$(l.defaults.column);l.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,
-iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],
-aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,
-iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return y(this)=="ssp"?this._iRecordsTotal*1:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return y(this)=="ssp"?this._iRecordsDisplay*1:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,
-f=e.bPaginate;return e.bServerSide?f===false||a===-1?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||a===-1?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};l.ext=v={buttons:{},classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:l.fnVersionCheck,
-iApiIndex:0,oJUIClasses:{},sVersion:l.version};h.extend(v,{afnFiltering:v.search,aTypes:v.type.detect,ofnSearch:v.type.search,oSort:v.type.order,afnSortData:v.order,aoFeatures:v.feature,oApi:v.internal,oStdClasses:v.classes,oPagination:v.pager});h.extend(l.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",
-sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",
-sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var Mb=l.ext.pager;h.extend(Mb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ja(a,b)]},simple_numbers:function(a,b){return["previous",ja(a,b),"next"]},full_numbers:function(a,
-b){return["first","previous",ja(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ja(a,b),"last"]},_numbers:ja,numbers_length:7});h.extend(!0,l.ext.renderer,{pageButton:{_:function(a,b,c,d,e,f){var g=a.oClasses,j=a.oLanguage.oPaginate,i=a.oLanguage.oAria.paginate||{},l,m,o=0,r=function(b,d){var k,t,s,u,v=g.sPageButtonDisabled,w=function(b){Va(a,b.data.action,true)};k=0;for(t=d.length;k<t;k++){u=d[k];if(Array.isArray(u)){s=h("<"+(u.DT_el||"div")+"/>").appendTo(b);r(s,u)}else{l=null;
-m=u;s=a.iTabIndex;switch(u){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;case "first":l=j.sFirst;if(e===0){s=-1;m=m+(" "+v)}break;case "previous":l=j.sPrevious;if(e===0){s=-1;m=m+(" "+v)}break;case "next":l=j.sNext;if(f===0||e===f-1){s=-1;m=m+(" "+v)}break;case "last":l=j.sLast;if(f===0||e===f-1){s=-1;m=m+(" "+v)}break;default:l=a.fnFormatNumber(u+1);m=e===u?g.sPageButtonActive:""}if(l!==null){s=h("<a>",{"class":g.sPageButton+" "+m,"aria-controls":a.sTableId,"aria-label":i[u],
-"data-dt-idx":o,tabindex:s,id:c===0&&typeof u==="string"?a.sTableId+"_"+u:null}).html(l).appendTo(b);Xa(s,{action:u},w);o++}}}},t;try{t=h(b).find(H.activeElement).data("dt-idx")}catch(s){}r(h(b).empty(),d);t!==k&&h(b).find("[data-dt-idx="+t+"]").trigger("focus")}}});h.extend(l.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return ab(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&!bc.test(a))return null;var b=Date.parse(a);return b!==null&&!isNaN(b)||M(a)?"date":null},function(a,
-b){var c=b.oLanguage.sDecimal;return ab(a,c,true)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Rb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Rb(a,c,true)?"html-num-fmt"+c:null},function(a){return M(a)||typeof a==="string"&&a.indexOf("<")!==-1?"html":null}]);h.extend(l.ext.type.search,{html:function(a){return M(a)?a:typeof a==="string"?a.replace(Ob," ").replace(Ca,""):""},string:function(a){return M(a)?a:typeof a==="string"?a.replace(Ob," "):a}});var Ba=
-function(a,b,c,d){if(a!==0&&(!a||a==="-"))return-Infinity;b&&(a=Qb(a,b));if(a.replace){c&&(a=a.replace(c,""));d&&(a=a.replace(d,""))}return a*1};h.extend(v.type.order,{"date-pre":function(a){a=Date.parse(a);return isNaN(a)?-Infinity:a},"html-pre":function(a){return M(a)?"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return M(a)?"":typeof a==="string"?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,
-b){return a<b?1:a>b?-1:0}});Fa("");h.extend(!0,l.ext.renderer,{header:{_:function(a,b,c,d){h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass)}})},jqueryui:function(a,b,c,d){h("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(h("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);h(a.nTable).on("order.dt.DT",function(e,
-f,g,h){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass);b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(h[e]=="asc"?d.sSortJUIAsc:h[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});var fb=function(a){return typeof a==="string"?a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):
-a};l.render={number:function(a,b,c,d,e){return{display:function(f){if(typeof f!=="number"&&typeof f!=="string")return f;var g=f<0?"-":"",h=parseFloat(f);if(isNaN(h))return fb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g,a)+f+(e||"")}}},text:function(){return{display:fb,filter:fb}}};h.extend(l.ext.internal,{_fnExternApiFunc:Nb,_fnBuildAjax:ta,_fnAjaxUpdate:nb,_fnAjaxParameters:wb,_fnAjaxUpdateDraw:xb,
-_fnAjaxDataSrc:ua,_fnAddColumn:Ga,_fnColumnOptions:la,_fnAdjustColumnSizing:aa,_fnVisibleToColumnIndex:ba,_fnColumnIndexToVisible:ca,_fnVisbleColumns:W,_fnGetColumns:na,_fnColumnTypes:Ia,_fnApplyColumnDefs:kb,_fnHungarianMap:$,_fnCamelToHungarian:J,_fnLanguageCompat:Ea,_fnBrowserDetect:ib,_fnAddData:O,_fnAddTr:oa,_fnNodeToDataIndex:function(a,b){return b._DT_RowIndex!==k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return h.inArray(c,a.aoData[b].anCells)},_fnGetCellData:B,_fnSetCellData:lb,
-_fnSplitObjNotation:La,_fnGetObjectDataFn:S,_fnSetObjectDataFn:N,_fnGetDataMaster:Ma,_fnClearTable:pa,_fnDeleteIndex:qa,_fnInvalidate:ea,_fnGetRowElements:Ka,_fnCreateTr:Ja,_fnBuildHead:mb,_fnDrawHead:ga,_fnDraw:P,_fnReDraw:T,_fnAddOptionsHtml:pb,_fnDetectHeader:fa,_fnGetUniqueThs:sa,_fnFeatureHtmlFilter:rb,_fnFilterComplete:ha,_fnFilterCustom:Ab,_fnFilterColumn:zb,_fnFilter:yb,_fnFilterCreateSearch:Ra,_fnEscapeRegex:Sa,_fnFilterData:Bb,_fnFeatureHtmlInfo:ub,_fnUpdateInfo:Eb,_fnInfoMacros:Fb,_fnInitialise:ia,
-_fnInitComplete:va,_fnLengthChange:Ta,_fnFeatureHtmlLength:qb,_fnFeatureHtmlPaginate:vb,_fnPageChange:Va,_fnFeatureHtmlProcessing:sb,_fnProcessingDisplay:D,_fnFeatureHtmlTable:tb,_fnScrollDraw:ma,_fnApplyToChildren:I,_fnCalculateColumnWidths:Ha,_fnThrottle:Qa,_fnConvertToWidth:Gb,_fnGetWidestNode:Hb,_fnGetMaxLenString:Ib,_fnStringToCss:w,_fnSortFlatten:Y,_fnSort:ob,_fnSortAria:Kb,_fnSortListener:Wa,_fnSortAttachListener:Oa,_fnSortingClasses:ya,_fnSortData:Jb,_fnSaveState:za,_fnLoadState:Lb,_fnSettingsFromNode:Aa,
-_fnLog:K,_fnMap:F,_fnBindAction:Xa,_fnCallbackReg:z,_fnCallbackFire:u,_fnLengthOverflow:Ua,_fnRenderer:Pa,_fnDataSource:y,_fnRowAttributes:Na,_fnExtend:Ya,_fnCalculateEnd:function(){}});h.fn.dataTable=l;l.$=h;h.fn.dataTableSettings=l.settings;h.fn.dataTableExt=l.ext;h.fn.DataTable=function(a){return h(this).dataTable(a).api()};h.each(l,function(a,b){h.fn.DataTable[a]=b});return h.fn.dataTable});
+/*! DataTables 1.13.4
+ * ©2008-2023 SpryMedia Ltd - datatables.net/license
+ */
+!function(n){"use strict";var a;"function"==typeof define&&define.amd?define(["jquery"],function(t){return n(t,window,document)}):"object"==typeof exports?(a=require("jquery"),"undefined"!=typeof window?module.exports=function(t,e){return t=t||window,e=e||a(t),n(e,t,t.document)}:n(a,window,window.document)):window.DataTable=n(jQuery,window,document)}(function(P,j,y,N){"use strict";function d(t){var e=parseInt(t,10);return!isNaN(e)&&isFinite(t)?e:null}function l(t,e,n){var a=typeof t,r="string"==a;return"number"==a||"bigint"==a||!!h(t)||(e&&r&&(t=G(t,e)),n&&r&&(t=t.replace(q,"")),!isNaN(parseFloat(t))&&isFinite(t))}function a(t,e,n){var a;return!!h(t)||(h(a=t)||"string"==typeof a)&&!!l(t.replace(V,""),e,n)||null}function m(t,e,n,a){var r=[],o=0,i=e.length;if(a!==N)for(;o<i;o++)t[e[o]][n]&&r.push(t[e[o]][n][a]);else for(;o<i;o++)r.push(t[e[o]][n]);return r}function f(t,e){var n,a=[];e===N?(e=0,n=t):(n=e,e=t);for(var r=e;r<n;r++)a.push(r);return a}function _(t){for(var e=[],n=0,a=t.length;n<a;n++)t[n]&&e.push(t[n]);return e}function s(t,e){return-1!==this.indexOf(t,e=e===N?0:e)}var p,e,t,w=function(t,v){if(w.factory(t,v))return w;if(this instanceof w)return P(t).DataTable(v);v=t,this.$=function(t,e){return this.api(!0).$(t,e)},this._=function(t,e){return this.api(!0).rows(t,e).data()},this.api=function(t){return new B(t?ge(this[p.iApiIndex]):this)},this.fnAddData=function(t,e){var n=this.api(!0),t=(Array.isArray(t)&&(Array.isArray(t[0])||P.isPlainObject(t[0]))?n.rows:n.row).add(t);return e!==N&&!e||n.draw(),t.flatten().toArray()},this.fnAdjustColumnSizing=function(t){var e=this.api(!0).columns.adjust(),n=e.settings()[0],a=n.oScroll;t===N||t?e.draw(!1):""===a.sX&&""===a.sY||Qt(n)},this.fnClearTable=function(t){var e=this.api(!0).clear();t!==N&&!t||e.draw()},this.fnClose=function(t){this.api(!0).row(t).child.hide()},this.fnDeleteRow=function(t,e,n){var a=this.api(!0),t=a.rows(t),r=t.settings()[0],o=r.aoData[t[0][0]];return t.remove(),e&&e.call(this,r,o),n!==N&&!n||a.draw(),o},this.fnDestroy=function(t){this.api(!0).destroy(t)},this.fnDraw=function(t){this.api(!0).draw(t)},this.fnFilter=function(t,e,n,a,r,o){var i=this.api(!0);(null===e||e===N?i:i.column(e)).search(t,n,a,o),i.draw()},this.fnGetData=function(t,e){var n,a=this.api(!0);return t!==N?(n=t.nodeName?t.nodeName.toLowerCase():"",e!==N||"td"==n||"th"==n?a.cell(t,e).data():a.row(t).data()||null):a.data().toArray()},this.fnGetNodes=function(t){var e=this.api(!0);return t!==N?e.row(t).node():e.rows().nodes().flatten().toArray()},this.fnGetPosition=function(t){var e=this.api(!0),n=t.nodeName.toUpperCase();return"TR"==n?e.row(t).index():"TD"==n||"TH"==n?[(n=e.cell(t).index()).row,n.columnVisible,n.column]:null},this.fnIsOpen=function(t){return this.api(!0).row(t).child.isShown()},this.fnOpen=function(t,e,n){return this.api(!0).row(t).child(e,n).show().child()[0]},this.fnPageChange=function(t,e){t=this.api(!0).page(t);e!==N&&!e||t.draw(!1)},this.fnSetColumnVis=function(t,e,n){t=this.api(!0).column(t).visible(e);n!==N&&!n||t.columns.adjust().draw()},this.fnSettings=function(){return ge(this[p.iApiIndex])},this.fnSort=function(t){this.api(!0).order(t).draw()},this.fnSortListener=function(t,e,n){this.api(!0).order.listener(t,e,n)},this.fnUpdate=function(t,e,n,a,r){var o=this.api(!0);return(n===N||null===n?o.row(e):o.cell(e,n)).data(t),r!==N&&!r||o.columns.adjust(),a!==N&&!a||o.draw(),0},this.fnVersionCheck=p.fnVersionCheck;var e,y=this,D=v===N,_=this.length;for(e in D&&(v={}),this.oApi=this.internal=p.internal,w.ext.internal)e&&(this[e]=Ge(e));return this.each(function(){var r=1<_?be({},v,!0):v,o=0,t=this.getAttribute("id"),i=!1,e=w.defaults,l=P(this);if("table"!=this.nodeName.toLowerCase())W(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{K(e),Q(e.column),C(e,e,!0),C(e.column,e.column,!0),C(e,P.extend(r,l.data()),!0);for(var n=w.settings,o=0,s=n.length;o<s;o++){var a=n[o];if(a.nTable==this||a.nTHead&&a.nTHead.parentNode==this||a.nTFoot&&a.nTFoot.parentNode==this){var u=(r.bRetrieve!==N?r:e).bRetrieve,c=(r.bDestroy!==N?r:e).bDestroy;if(D||u)return a.oInstance;if(c){a.oInstance.fnDestroy();break}return void W(a,0,"Cannot reinitialise DataTable",3)}if(a.sTableId==this.id){n.splice(o,1);break}}null!==t&&""!==t||(t="DataTables_Table_"+w.ext._unique++,this.id=t);var f,d,h=P.extend(!0,{},w.models.oSettings,{sDestroyWidth:l[0].style.width,sInstance:t,sTableId:t}),p=(h.nTable=this,h.oApi=y.internal,h.oInit=r,n.push(h),h.oInstance=1===y.length?y:l.dataTable(),K(r),Z(r.oLanguage),r.aLengthMenu&&!r.iDisplayLength&&(r.iDisplayLength=(Array.isArray(r.aLengthMenu[0])?r.aLengthMenu[0]:r.aLengthMenu)[0]),r=be(P.extend(!0,{},e),r),F(h.oFeatures,r,["bPaginate","bLengthChange","bFilter","bSort","bSortMulti","bInfo","bProcessing","bAutoWidth","bSortClasses","bServerSide","bDeferRender"]),F(h,r,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"]]),F(h.oScroll,r,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]),F(h.oLanguage,r,"fnInfoCallback"),L(h,"aoDrawCallback",r.fnDrawCallback,"user"),L(h,"aoServerParams",r.fnServerParams,"user"),L(h,"aoStateSaveParams",r.fnStateSaveParams,"user"),L(h,"aoStateLoadParams",r.fnStateLoadParams,"user"),L(h,"aoStateLoaded",r.fnStateLoaded,"user"),L(h,"aoRowCallback",r.fnRowCallback,"user"),L(h,"aoRowCreatedCallback",r.fnCreatedRow,"user"),L(h,"aoHeaderCallback",r.fnHeaderCallback,"user"),L(h,"aoFooterCallback",r.fnFooterCallback,"user"),L(h,"aoInitComplete",r.fnInitComplete,"user"),L(h,"aoPreDrawCallback",r.fnPreDrawCallback,"user"),h.rowIdFn=A(r.rowId),tt(h),h.oClasses),g=(P.extend(p,w.ext.classes,r.oClasses),l.addClass(p.sTable),h.iInitDisplayStart===N&&(h.iInitDisplayStart=r.iDisplayStart,h._iDisplayStart=r.iDisplayStart),null!==r.iDeferLoading&&(h.bDeferLoading=!0,t=Array.isArray(r.iDeferLoading),h._iRecordsDisplay=t?r.iDeferLoading[0]:r.iDeferLoading,h._iRecordsTotal=t?r.iDeferLoading[1]:r.iDeferLoading),h.oLanguage),t=(P.extend(!0,g,r.oLanguage),g.sUrl?(P.ajax({dataType:"json",url:g.sUrl,success:function(t){C(e.oLanguage,t),Z(t),P.extend(!0,g,t,h.oInit.oLanguage),R(h,null,"i18n",[h]),Jt(h)},error:function(){Jt(h)}}),i=!0):R(h,null,"i18n",[h]),null===r.asStripeClasses&&(h.asStripeClasses=[p.sStripeOdd,p.sStripeEven]),h.asStripeClasses),b=l.children("tbody").find("tr").eq(0),m=(-1!==P.inArray(!0,P.map(t,function(t,e){return b.hasClass(t)}))&&(P("tbody tr",this).removeClass(t.join(" ")),h.asDestroyStripes=t.slice()),[]),t=this.getElementsByTagName("thead");if(0!==t.length&&(wt(h.aoHeader,t[0]),m=Ct(h)),null===r.aoColumns)for(f=[],o=0,s=m.length;o<s;o++)f.push(null);else f=r.aoColumns;for(o=0,s=f.length;o<s;o++)nt(h,m?m[o]:null);st(h,r.aoColumnDefs,f,function(t,e){at(h,t,e)}),b.length&&(d=function(t,e){return null!==t.getAttribute("data-"+e)?e:null},P(b[0]).children("th, td").each(function(t,e){var n,a=h.aoColumns[t];a||W(h,0,"Incorrect column count",18),a.mData===t&&(n=d(e,"sort")||d(e,"order"),e=d(e,"filter")||d(e,"search"),null===n&&null===e||(a.mData={_:t+".display",sort:null!==n?t+".@data-"+n:N,type:null!==n?t+".@data-"+n:N,filter:null!==e?t+".@data-"+e:N},a._isArrayHost=!0,at(h,t)))}));var S=h.oFeatures,t=function(){if(r.aaSorting===N){var t=h.aaSorting;for(o=0,s=t.length;o<s;o++)t[o][1]=h.aoColumns[o].asSorting[0]}ce(h),S.bSort&&L(h,"aoDrawCallback",function(){var t,n;h.bSorted&&(t=I(h),n={},P.each(t,function(t,e){n[e.src]=e.dir}),R(h,null,"order",[h,t,n]),le(h))}),L(h,"aoDrawCallback",function(){(h.bSorted||"ssp"===E(h)||S.bDeferRender)&&ce(h)},"sc");var e=l.children("caption").each(function(){this._captionSide=P(this).css("caption-side")}),n=l.children("thead"),a=(0===n.length&&(n=P("<thead/>").appendTo(l)),h.nTHead=n[0],l.children("tbody")),n=(0===a.length&&(a=P("<tbody/>").insertAfter(n)),h.nTBody=a[0],l.children("tfoot"));if(0===(n=0===n.length&&0<e.length&&(""!==h.oScroll.sX||""!==h.oScroll.sY)?P("<tfoot/>").appendTo(l):n).length||0===n.children().length?l.addClass(p.sNoFooter):0<n.length&&(h.nTFoot=n[0],wt(h.aoFooter,h.nTFoot)),r.aaData)for(o=0;o<r.aaData.length;o++)x(h,r.aaData[o]);else!h.bDeferLoading&&"dom"!=E(h)||ut(h,P(h.nTBody).children("tr"));h.aiDisplay=h.aiDisplayMaster.slice(),!(h.bInitialised=!0)===i&&Jt(h)};L(h,"aoDrawCallback",de,"state_save"),r.bStateSave?(S.bStateSave=!0,he(h,0,t)):t()}}),y=null,this},c={},U=/[\r\n\u2028]/g,V=/<.*?>/g,X=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,J=new RegExp("(\\"+["/",".","*","+","?","|","(",")","[","]","{","}","\\","$","^","-"].join("|\\")+")","g"),q=/['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,h=function(t){return!t||!0===t||"-"===t},G=function(t,e){return c[e]||(c[e]=new RegExp(Ot(e),"g")),"string"==typeof t&&"."!==e?t.replace(/\./g,"").replace(c[e],"."):t},H=function(t,e,n){var a=[],r=0,o=t.length;if(n!==N)for(;r<o;r++)t[r]&&t[r][e]&&a.push(t[r][e][n]);else for(;r<o;r++)t[r]&&a.push(t[r][e]);return a},$=function(t){if(!(t.length<2))for(var e=t.slice().sort(),n=e[0],a=1,r=e.length;a<r;a++){if(e[a]===n)return!1;n=e[a]}return!0},z=function(t){if($(t))return t.slice();var e,n,a,r=[],o=t.length,i=0;t:for(n=0;n<o;n++){for(e=t[n],a=0;a<i;a++)if(r[a]===e)continue t;r.push(e),i++}return r},Y=function(t,e){if(Array.isArray(e))for(var n=0;n<e.length;n++)Y(t,e[n]);else t.push(e);return t};function i(n){var a,r,o={};P.each(n,function(t,e){(a=t.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(a[1]+" ")&&(r=t.replace(a[0],a[2].toLowerCase()),o[r]=t,"o"===a[1])&&i(n[t])}),n._hungarianMap=o}function C(n,a,r){var o;n._hungarianMap||i(n),P.each(a,function(t,e){(o=n._hungarianMap[t])===N||!r&&a[o]!==N||("o"===o.charAt(0)?(a[o]||(a[o]={}),P.extend(!0,a[o],a[t]),C(n[o],a[o],r)):a[o]=a[t])})}function Z(t){var e,n=w.defaults.oLanguage,a=n.sDecimal;a&&Me(a),t&&(e=t.sZeroRecords,!t.sEmptyTable&&e&&"No data available in table"===n.sEmptyTable&&F(t,t,"sZeroRecords","sEmptyTable"),!t.sLoadingRecords&&e&&"Loading..."===n.sLoadingRecords&&F(t,t,"sZeroRecords","sLoadingRecords"),t.sInfoThousands&&(t.sThousands=t.sInfoThousands),e=t.sDecimal)&&a!==e&&Me(e)}Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),Array.prototype.includes||(Array.prototype.includes=s),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}),String.prototype.includes||(String.prototype.includes=s),w.util={throttle:function(a,t){var r,o,i=t!==N?t:200;return function(){var t=this,e=+new Date,n=arguments;r&&e<r+i?(clearTimeout(o),o=setTimeout(function(){r=N,a.apply(t,n)},i)):(r=e,a.apply(t,n))}},escapeRegex:function(t){return t.replace(J,"\\$1")},set:function(a){var d;return P.isPlainObject(a)?w.util.set(a._):null===a?function(){}:"function"==typeof a?function(t,e,n){a(t,"set",e,n)}:"string"!=typeof a||-1===a.indexOf(".")&&-1===a.indexOf("[")&&-1===a.indexOf("(")?function(t,e){t[a]=e}:(d=function(t,e,n){for(var a,r,o,i,l=dt(n),n=l[l.length-1],s=0,u=l.length-1;s<u;s++){if("__proto__"===l[s]||"constructor"===l[s])throw new Error("Cannot set prototype values");if(a=l[s].match(ft),r=l[s].match(g),a){if(l[s]=l[s].replace(ft,""),t[l[s]]=[],(a=l.slice()).splice(0,s+1),i=a.join("."),Array.isArray(e))for(var c=0,f=e.length;c<f;c++)d(o={},e[c],i),t[l[s]].push(o);else t[l[s]]=e;return}r&&(l[s]=l[s].replace(g,""),t=t[l[s]](e)),null!==t[l[s]]&&t[l[s]]!==N||(t[l[s]]={}),t=t[l[s]]}n.match(g)?t[n.replace(g,"")](e):t[n.replace(ft,"")]=e},function(t,e){return d(t,e,a)})},get:function(r){var o,d;return P.isPlainObject(r)?(o={},P.each(r,function(t,e){e&&(o[t]=w.util.get(e))}),function(t,e,n,a){var r=o[e]||o._;return r!==N?r(t,e,n,a):t}):null===r?function(t){return t}:"function"==typeof r?function(t,e,n,a){return r(t,e,n,a)}:"string"!=typeof r||-1===r.indexOf(".")&&-1===r.indexOf("[")&&-1===r.indexOf("(")?function(t,e){return t[r]}:(d=function(t,e,n){var a,r,o;if(""!==n)for(var i=dt(n),l=0,s=i.length;l<s;l++){if(f=i[l].match(ft),a=i[l].match(g),f){if(i[l]=i[l].replace(ft,""),""!==i[l]&&(t=t[i[l]]),r=[],i.splice(0,l+1),o=i.join("."),Array.isArray(t))for(var u=0,c=t.length;u<c;u++)r.push(d(t[u],e,o));var f=f[0].substring(1,f[0].length-1);t=""===f?r:r.join(f);break}if(a)i[l]=i[l].replace(g,""),t=t[i[l]]();else{if(null===t||t[i[l]]===N)return N;t=t[i[l]]}}return t},function(t,e){return d(t,e,r)})}};var r=function(t,e,n){t[e]!==N&&(t[n]=t[e])};function K(t){r(t,"ordering","bSort"),r(t,"orderMulti","bSortMulti"),r(t,"orderClasses","bSortClasses"),r(t,"orderCellsTop","bSortCellsTop"),r(t,"order","aaSorting"),r(t,"orderFixed","aaSortingFixed"),r(t,"paging","bPaginate"),r(t,"pagingType","sPaginationType"),r(t,"pageLength","iDisplayLength"),r(t,"searching","bFilter"),"boolean"==typeof t.sScrollX&&(t.sScrollX=t.sScrollX?"100%":""),"boolean"==typeof t.scrollX&&(t.scrollX=t.scrollX?"100%":"");var e=t.aoSearchCols;if(e)for(var n=0,a=e.length;n<a;n++)e[n]&&C(w.models.oSearch,e[n])}function Q(t){r(t,"orderable","bSortable"),r(t,"orderData","aDataSort"),r(t,"orderSequence","asSorting"),r(t,"orderDataType","sortDataType");var e=t.aDataSort;"number"!=typeof e||Array.isArray(e)||(t.aDataSort=[e])}function tt(t){var e,n,a,r;w.__browser||(w.__browser=e={},r=(a=(n=P("<div/>").css({position:"fixed",top:0,left:-1*P(j).scrollLeft(),height:1,width:1,overflow:"hidden"}).append(P("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(P("<div/>").css({width:"100%",height:10}))).appendTo("body")).children()).children(),e.barWidth=a[0].offsetWidth-a[0].clientWidth,e.bScrollOversize=100===r[0].offsetWidth&&100!==a[0].clientWidth,e.bScrollbarLeft=1!==Math.round(r.offset().left),e.bBounding=!!n[0].getBoundingClientRect().width,n.remove()),P.extend(t.oBrowser,w.__browser),t.oScroll.iBarWidth=w.__browser.barWidth}function et(t,e,n,a,r,o){var i,l=a,s=!1;for(n!==N&&(i=n,s=!0);l!==r;)t.hasOwnProperty(l)&&(i=s?e(i,t[l],l,t):t[l],s=!0,l+=o);return i}function nt(t,e){var n=w.defaults.column,a=t.aoColumns.length,n=P.extend({},w.models.oColumn,n,{nTh:e||y.createElement("th"),sTitle:n.sTitle||(e?e.innerHTML:""),aDataSort:n.aDataSort||[a],mData:n.mData||a,idx:a}),n=(t.aoColumns.push(n),t.aoPreSearchCols);n[a]=P.extend({},w.models.oSearch,n[a]),at(t,a,P(e).data())}function at(t,e,n){function a(t){return"string"==typeof t&&-1!==t.indexOf("@")}var e=t.aoColumns[e],r=t.oClasses,o=P(e.nTh),i=(!e.sWidthOrig&&(e.sWidthOrig=o.attr("width")||null,u=(o.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/))&&(e.sWidthOrig=u[1]),n!==N&&null!==n&&(Q(n),C(w.defaults.column,n,!0),n.mDataProp===N||n.mData||(n.mData=n.mDataProp),n.sType&&(e._sManualType=n.sType),n.className&&!n.sClass&&(n.sClass=n.className),n.sClass&&o.addClass(n.sClass),u=e.sClass,P.extend(e,n),F(e,n,"sWidth","sWidthOrig"),u!==e.sClass&&(e.sClass=u+" "+e.sClass),n.iDataSort!==N&&(e.aDataSort=[n.iDataSort]),F(e,n,"aDataSort")),e.mData),l=A(i),s=e.mRender?A(e.mRender):null,u=(e._bAttrSrc=P.isPlainObject(i)&&(a(i.sort)||a(i.type)||a(i.filter)),e._setter=null,e.fnGetData=function(t,e,n){var a=l(t,e,N,n);return s&&e?s(a,e,t,n):a},e.fnSetData=function(t,e,n){return b(i)(t,e,n)},"number"==typeof i||e._isArrayHost||(t._rowReadObject=!0),t.oFeatures.bSort||(e.bSortable=!1,o.addClass(r.sSortableNone)),-1!==P.inArray("asc",e.asSorting)),n=-1!==P.inArray("desc",e.asSorting);e.bSortable&&(u||n)?u&&!n?(e.sSortingClass=r.sSortableAsc,e.sSortingClassJUI=r.sSortJUIAscAllowed):!u&&n?(e.sSortingClass=r.sSortableDesc,e.sSortingClassJUI=r.sSortJUIDescAllowed):(e.sSortingClass=r.sSortable,e.sSortingClassJUI=r.sSortJUI):(e.sSortingClass=r.sSortableNone,e.sSortingClassJUI="")}function O(t){if(!1!==t.oFeatures.bAutoWidth){var e=t.aoColumns;ee(t);for(var n=0,a=e.length;n<a;n++)e[n].nTh.style.width=e[n].sWidth}var r=t.oScroll;""===r.sY&&""===r.sX||Qt(t),R(t,null,"column-sizing",[t])}function rt(t,e){t=it(t,"bVisible");return"number"==typeof t[e]?t[e]:null}function ot(t,e){t=it(t,"bVisible"),e=P.inArray(e,t);return-1!==e?e:null}function T(t){var n=0;return P.each(t.aoColumns,function(t,e){e.bVisible&&"none"!==P(e.nTh).css("display")&&n++}),n}function it(t,n){var a=[];return P.map(t.aoColumns,function(t,e){t[n]&&a.push(e)}),a}function lt(t){for(var e,n,a,r,o,i,l,s=t.aoColumns,u=t.aoData,c=w.ext.type.detect,f=0,d=s.length;f<d;f++)if(l=[],!(o=s[f]).sType&&o._sManualType)o.sType=o._sManualType;else if(!o.sType){for(e=0,n=c.length;e<n;e++){for(a=0,r=u.length;a<r&&(l[a]===N&&(l[a]=S(t,a,f,"type")),(i=c[e](l[a],t))||e===c.length-1)&&("html"!==i||h(l[a]));a++);if(i){o.sType=i;break}}o.sType||(o.sType="string")}}function st(t,e,n,a){var r,o,i,l,s=t.aoColumns;if(e)for(r=e.length-1;0<=r;r--)for(var u,c=(u=e[r]).target!==N?u.target:u.targets!==N?u.targets:u.aTargets,f=0,d=(c=Array.isArray(c)?c:[c]).length;f<d;f++)if("number"==typeof c[f]&&0<=c[f]){for(;s.length<=c[f];)nt(t);a(c[f],u)}else if("number"==typeof c[f]&&c[f]<0)a(s.length+c[f],u);else if("string"==typeof c[f])for(i=0,l=s.length;i<l;i++)"_all"!=c[f]&&!P(s[i].nTh).hasClass(c[f])||a(i,u);if(n)for(r=0,o=n.length;r<o;r++)a(r,n[r])}function x(t,e,n,a){for(var r=t.aoData.length,o=P.extend(!0,{},w.models.oRow,{src:n?"dom":"data",idx:r}),i=(o._aData=e,t.aoData.push(o),t.aoColumns),l=0,s=i.length;l<s;l++)i[l].sType=null;t.aiDisplayMaster.push(r);e=t.rowIdFn(e);return e!==N&&(t.aIds[e]=o),!n&&t.oFeatures.bDeferRender||St(t,r,n,a),r}function ut(n,t){var a;return(t=t instanceof P?t:P(t)).map(function(t,e){return a=mt(n,e),x(n,a.data,e,a.cells)})}function S(t,e,n,a){"search"===a?a="filter":"order"===a&&(a="sort");var r=t.iDraw,o=t.aoColumns[n],i=t.aoData[e]._aData,l=o.sDefaultContent,s=o.fnGetData(i,a,{settings:t,row:e,col:n});if(s===N)return t.iDrawError!=r&&null===l&&(W(t,0,"Requested unknown parameter "+("function"==typeof o.mData?"{function}":"'"+o.mData+"'")+" for row "+e+", column "+n,4),t.iDrawError=r),l;if(s!==i&&null!==s||null===l||a===N){if("function"==typeof s)return s.call(i)}else s=l;return null===s&&"display"===a?"":"filter"===a&&(e=w.ext.type.search)[o.sType]?e[o.sType](s):s}function ct(t,e,n,a){var r=t.aoColumns[n],o=t.aoData[e]._aData;r.fnSetData(o,a,{settings:t,row:e,col:n})}var ft=/\[.*?\]$/,g=/\(\)$/;function dt(t){return P.map(t.match(/(\\.|[^\.])+/g)||[""],function(t){return t.replace(/\\\./g,".")})}var A=w.util.get,b=w.util.set;function ht(t){return H(t.aoData,"_aData")}function pt(t){t.aoData.length=0,t.aiDisplayMaster.length=0,t.aiDisplay.length=0,t.aIds={}}function gt(t,e,n){for(var a=-1,r=0,o=t.length;r<o;r++)t[r]==e?a=r:t[r]>e&&t[r]--;-1!=a&&n===N&&t.splice(a,1)}function bt(n,a,t,e){function r(t,e){for(;t.childNodes.length;)t.removeChild(t.firstChild);t.innerHTML=S(n,a,e,"display")}var o,i,l=n.aoData[a];if("dom"!==t&&(t&&"auto"!==t||"dom"!==l.src)){var s=l.anCells;if(s)if(e!==N)r(s[e],e);else for(o=0,i=s.length;o<i;o++)r(s[o],o)}else l._aData=mt(n,l,e,e===N?N:l._aData).data;l._aSortData=null,l._aFilterData=null;var u=n.aoColumns;if(e!==N)u[e].sType=null;else{for(o=0,i=u.length;o<i;o++)u[o].sType=null;vt(n,l)}}function mt(t,e,n,a){function r(t,e){var n;"string"==typeof t&&-1!==(n=t.indexOf("@"))&&(n=t.substring(n+1),b(t)(a,e.getAttribute(n)))}function o(t){n!==N&&n!==f||(l=d[f],s=t.innerHTML.trim(),l&&l._bAttrSrc?(b(l.mData._)(a,s),r(l.mData.sort,t),r(l.mData.type,t),r(l.mData.filter,t)):h?(l._setter||(l._setter=b(l.mData)),l._setter(a,s)):a[f]=s),f++}var i,l,s,u=[],c=e.firstChild,f=0,d=t.aoColumns,h=t._rowReadObject;a=a!==N?a:h?{}:[];if(c)for(;c;)"TD"!=(i=c.nodeName.toUpperCase())&&"TH"!=i||(o(c),u.push(c)),c=c.nextSibling;else for(var p=0,g=(u=e.anCells).length;p<g;p++)o(u[p]);var e=e.firstChild?e:e.nTr;return e&&(e=e.getAttribute("id"))&&b(t.rowId)(a,e),{data:a,cells:u}}function St(t,e,n,a){var r,o,i,l,s,u,c=t.aoData[e],f=c._aData,d=[];if(null===c.nTr){for(r=n||y.createElement("tr"),c.nTr=r,c.anCells=d,r._DT_RowIndex=e,vt(t,c),l=0,s=t.aoColumns.length;l<s;l++)i=t.aoColumns[l],(o=(u=!n)?y.createElement(i.sCellType):a[l])||W(t,0,"Incorrect column count",18),o._DT_CellIndex={row:e,column:l},d.push(o),!u&&(!i.mRender&&i.mData===l||P.isPlainObject(i.mData)&&i.mData._===l+".display")||(o.innerHTML=S(t,e,l,"display")),i.sClass&&(o.className+=" "+i.sClass),i.bVisible&&!n?r.appendChild(o):!i.bVisible&&n&&o.parentNode.removeChild(o),i.fnCreatedCell&&i.fnCreatedCell.call(t.oInstance,o,S(t,e,l),f,e,l);R(t,"aoRowCreatedCallback",null,[r,f,e,d])}}function vt(t,e){var n=e.nTr,a=e._aData;n&&((t=t.rowIdFn(a))&&(n.id=t),a.DT_RowClass&&(t=a.DT_RowClass.split(" "),e.__rowc=e.__rowc?z(e.__rowc.concat(t)):t,P(n).removeClass(e.__rowc.join(" ")).addClass(a.DT_RowClass)),a.DT_RowAttr&&P(n).attr(a.DT_RowAttr),a.DT_RowData)&&P(n).data(a.DT_RowData)}function yt(t){var e,n,a,r=t.nTHead,o=t.nTFoot,i=0===P("th, td",r).length,l=t.oClasses,s=t.aoColumns;for(i&&(n=P("<tr/>").appendTo(r)),c=0,f=s.length;c<f;c++)a=s[c],e=P(a.nTh).addClass(a.sClass),i&&e.appendTo(n),t.oFeatures.bSort&&(e.addClass(a.sSortingClass),!1!==a.bSortable)&&(e.attr("tabindex",t.iTabIndex).attr("aria-controls",t.sTableId),ue(t,a.nTh,c)),a.sTitle!=e[0].innerHTML&&e.html(a.sTitle),ve(t,"header")(t,e,a,l);if(i&&wt(t.aoHeader,r),P(r).children("tr").children("th, td").addClass(l.sHeaderTH),P(o).children("tr").children("th, td").addClass(l.sFooterTH),null!==o)for(var u=t.aoFooter[0],c=0,f=u.length;c<f;c++)(a=s[c])?(a.nTf=u[c].cell,a.sClass&&P(a.nTf).addClass(a.sClass)):W(t,0,"Incorrect column count",18)}function Dt(t,e,n){var a,r,o,i,l,s,u,c,f,d=[],h=[],p=t.aoColumns.length;if(e){for(n===N&&(n=!1),a=0,r=e.length;a<r;a++){for(d[a]=e[a].slice(),d[a].nTr=e[a].nTr,o=p-1;0<=o;o--)t.aoColumns[o].bVisible||n||d[a].splice(o,1);h.push([])}for(a=0,r=d.length;a<r;a++){if(u=d[a].nTr)for(;s=u.firstChild;)u.removeChild(s);for(o=0,i=d[a].length;o<i;o++)if(f=c=1,h[a][o]===N){for(u.appendChild(d[a][o].cell),h[a][o]=1;d[a+c]!==N&&d[a][o].cell==d[a+c][o].cell;)h[a+c][o]=1,c++;for(;d[a][o+f]!==N&&d[a][o].cell==d[a][o+f].cell;){for(l=0;l<c;l++)h[a+l][o+f]=1;f++}P(d[a][o].cell).attr("rowspan",c).attr("colspan",f)}}}}function v(t,e){n="ssp"==E(s=t),(l=s.iInitDisplayStart)!==N&&-1!==l&&(s._iDisplayStart=!n&&l>=s.fnRecordsDisplay()?0:l,s.iInitDisplayStart=-1);var n=R(t,"aoPreDrawCallback","preDraw",[t]);if(-1!==P.inArray(!1,n))D(t,!1);else{var a=[],r=0,o=t.asStripeClasses,i=o.length,l=t.oLanguage,s="ssp"==E(t),u=t.aiDisplay,n=t._iDisplayStart,c=t.fnDisplayEnd();if(t.bDrawing=!0,t.bDeferLoading)t.bDeferLoading=!1,t.iDraw++,D(t,!1);else if(s){if(!t.bDestroying&&!e)return void xt(t)}else t.iDraw++;if(0!==u.length)for(var f=s?t.aoData.length:c,d=s?0:n;d<f;d++){var h,p=u[d],g=t.aoData[p],b=(null===g.nTr&&St(t,p),g.nTr);0!==i&&(h=o[r%i],g._sRowStripe!=h)&&(P(b).removeClass(g._sRowStripe).addClass(h),g._sRowStripe=h),R(t,"aoRowCallback",null,[b,g._aData,r,d,p]),a.push(b),r++}else{e=l.sZeroRecords;1==t.iDraw&&"ajax"==E(t)?e=l.sLoadingRecords:l.sEmptyTable&&0===t.fnRecordsTotal()&&(e=l.sEmptyTable),a[0]=P("<tr/>",{class:i?o[0]:""}).append(P("<td />",{valign:"top",colSpan:T(t),class:t.oClasses.sRowEmpty}).html(e))[0]}R(t,"aoHeaderCallback","header",[P(t.nTHead).children("tr")[0],ht(t),n,c,u]),R(t,"aoFooterCallback","footer",[P(t.nTFoot).children("tr")[0],ht(t),n,c,u]);s=P(t.nTBody);s.children().detach(),s.append(P(a)),R(t,"aoDrawCallback","draw",[t]),t.bSorted=!1,t.bFiltered=!1,t.bDrawing=!1}}function u(t,e){var n=t.oFeatures,a=n.bSort,n=n.bFilter;a&&ie(t),n?Rt(t,t.oPreviousSearch):t.aiDisplay=t.aiDisplayMaster.slice(),!0!==e&&(t._iDisplayStart=0),t._drawHold=e,v(t),t._drawHold=!1}function _t(t){for(var e,n,a,r,o,i,l,s=t.oClasses,u=P(t.nTable),u=P("<div/>").insertBefore(u),c=t.oFeatures,f=P("<div/>",{id:t.sTableId+"_wrapper",class:s.sWrapper+(t.nTFoot?"":" "+s.sNoFooter)}),d=(t.nHolding=u[0],t.nTableWrapper=f[0],t.nTableReinsertBefore=t.nTable.nextSibling,t.sDom.split("")),h=0;h<d.length;h++){if(e=null,"<"==(n=d[h])){if(a=P("<div/>")[0],"'"==(r=d[h+1])||'"'==r){for(o="",i=2;d[h+i]!=r;)o+=d[h+i],i++;"H"==o?o=s.sJUIHeader:"F"==o&&(o=s.sJUIFooter),-1!=o.indexOf(".")?(l=o.split("."),a.id=l[0].substr(1,l[0].length-1),a.className=l[1]):"#"==o.charAt(0)?a.id=o.substr(1,o.length-1):a.className=o,h+=i}f.append(a),f=P(a)}else if(">"==n)f=f.parent();else if("l"==n&&c.bPaginate&&c.bLengthChange)e=$t(t);else if("f"==n&&c.bFilter)e=Lt(t);else if("r"==n&&c.bProcessing)e=Zt(t);else if("t"==n)e=Kt(t);else if("i"==n&&c.bInfo)e=Ut(t);else if("p"==n&&c.bPaginate)e=zt(t);else if(0!==w.ext.feature.length)for(var p=w.ext.feature,g=0,b=p.length;g<b;g++)if(n==p[g].cFeature){e=p[g].fnInit(t);break}e&&((l=t.aanFeatures)[n]||(l[n]=[]),l[n].push(e),f.append(e))}u.replaceWith(f),t.nHolding=null}function wt(t,e){var n,a,r,o,i,l,s,u,c,f,d=P(e).children("tr");for(t.splice(0,t.length),r=0,l=d.length;r<l;r++)t.push([]);for(r=0,l=d.length;r<l;r++)for(a=(n=d[r]).firstChild;a;){if("TD"==a.nodeName.toUpperCase()||"TH"==a.nodeName.toUpperCase())for(u=(u=+a.getAttribute("colspan"))&&0!=u&&1!=u?u:1,c=(c=+a.getAttribute("rowspan"))&&0!=c&&1!=c?c:1,s=function(t,e,n){for(var a=t[e];a[n];)n++;return n}(t,r,0),f=1==u,i=0;i<u;i++)for(o=0;o<c;o++)t[r+o][s+i]={cell:a,unique:f},t[r+o].nTr=n;a=a.nextSibling}}function Ct(t,e,n){var a=[];n||(n=t.aoHeader,e&&wt(n=[],e));for(var r=0,o=n.length;r<o;r++)for(var i=0,l=n[r].length;i<l;i++)!n[r][i].unique||a[i]&&t.bSortCellsTop||(a[i]=n[r][i].cell);return a}function Tt(r,t,n){function e(t){var e=r.jqXHR?r.jqXHR.status:null;(null===t||"number"==typeof e&&204==e)&&Ft(r,t={},[]),(e=t.error||t.sError)&&W(r,0,e),r.json=t,R(r,null,"xhr",[r,t,r.jqXHR]),n(t)}R(r,"aoServerParams","serverParams",[t]),t&&Array.isArray(t)&&(a={},o=/(.*?)\[\]$/,P.each(t,function(t,e){var n=e.name.match(o);n?(n=n[0],a[n]||(a[n]=[]),a[n].push(e.value)):a[e.name]=e.value}),t=a);var a,o,i,l=r.ajax,s=r.oInstance,u=(P.isPlainObject(l)&&l.data&&(u="function"==typeof(i=l.data)?i(t,r):i,t="function"==typeof i&&u?u:P.extend(!0,t,u),delete l.data),{data:t,success:e,dataType:"json",cache:!1,type:r.sServerMethod,error:function(t,e,n){var a=R(r,null,"xhr",[r,null,r.jqXHR]);-1===P.inArray(!0,a)&&("parsererror"==e?W(r,0,"Invalid JSON response",1):4===t.readyState&&W(r,0,"Ajax error",7)),D(r,!1)}});r.oAjaxData=t,R(r,null,"preXhr",[r,t]),r.fnServerData?r.fnServerData.call(s,r.sAjaxSource,P.map(t,function(t,e){return{name:e,value:t}}),e,r):r.sAjaxSource||"string"==typeof l?r.jqXHR=P.ajax(P.extend(u,{url:l||r.sAjaxSource})):"function"==typeof l?r.jqXHR=l.call(s,t,e,r):(r.jqXHR=P.ajax(P.extend(u,l)),l.data=i)}function xt(e){e.iDraw++,D(e,!0),Tt(e,At(e),function(t){It(e,t)})}function At(t){for(var e,n,a,r=t.aoColumns,o=r.length,i=t.oFeatures,l=t.oPreviousSearch,s=t.aoPreSearchCols,u=[],c=I(t),f=t._iDisplayStart,d=!1!==i.bPaginate?t._iDisplayLength:-1,h=function(t,e){u.push({name:t,value:e})},p=(h("sEcho",t.iDraw),h("iColumns",o),h("sColumns",H(r,"sName").join(",")),h("iDisplayStart",f),h("iDisplayLength",d),{draw:t.iDraw,columns:[],order:[],start:f,length:d,search:{value:l.sSearch,regex:l.bRegex}}),g=0;g<o;g++)n=r[g],a=s[g],e="function"==typeof n.mData?"function":n.mData,p.columns.push({data:e,name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:a.sSearch,regex:a.bRegex}}),h("mDataProp_"+g,e),i.bFilter&&(h("sSearch_"+g,a.sSearch),h("bRegex_"+g,a.bRegex),h("bSearchable_"+g,n.bSearchable)),i.bSort&&h("bSortable_"+g,n.bSortable);i.bFilter&&(h("sSearch",l.sSearch),h("bRegex",l.bRegex)),i.bSort&&(P.each(c,function(t,e){p.order.push({column:e.col,dir:e.dir}),h("iSortCol_"+t,e.col),h("sSortDir_"+t,e.dir)}),h("iSortingCols",c.length));f=w.ext.legacy.ajax;return null===f?t.sAjaxSource?u:p:f?u:p}function It(t,n){function e(t,e){return n[t]!==N?n[t]:n[e]}var a=Ft(t,n),r=e("sEcho","draw"),o=e("iTotalRecords","recordsTotal"),i=e("iTotalDisplayRecords","recordsFiltered");if(r!==N){if(+r<t.iDraw)return;t.iDraw=+r}a=a||[],pt(t),t._iRecordsTotal=parseInt(o,10),t._iRecordsDisplay=parseInt(i,10);for(var l=0,s=a.length;l<s;l++)x(t,a[l]);t.aiDisplay=t.aiDisplayMaster.slice(),v(t,!0),t._bInitComplete||qt(t,n),D(t,!1)}function Ft(t,e,n){t=P.isPlainObject(t.ajax)&&t.ajax.dataSrc!==N?t.ajax.dataSrc:t.sAjaxDataProp;if(!n)return"data"===t?e.aaData||e[t]:""!==t?A(t)(e):e;b(t)(e,n)}function Lt(n){function e(t){i.f;var e=this.value||"";o.return&&"Enter"!==t.key||e!=o.sSearch&&(Rt(n,{sSearch:e,bRegex:o.bRegex,bSmart:o.bSmart,bCaseInsensitive:o.bCaseInsensitive,return:o.return}),n._iDisplayStart=0,v(n))}var t=n.oClasses,a=n.sTableId,r=n.oLanguage,o=n.oPreviousSearch,i=n.aanFeatures,l='<input type="search" class="'+t.sFilterInput+'"/>',s=(s=r.sSearch).match(/_INPUT_/)?s.replace("_INPUT_",l):s+l,l=P("<div/>",{id:i.f?null:a+"_filter",class:t.sFilter}).append(P("<label/>").append(s)),t=null!==n.searchDelay?n.searchDelay:"ssp"===E(n)?400:0,u=P("input",l).val(o.sSearch).attr("placeholder",r.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",t?ne(e,t):e).on("mouseup",function(t){setTimeout(function(){e.call(u[0],t)},10)}).on("keypress.DT",function(t){if(13==t.keyCode)return!1}).attr("aria-controls",a);return P(n.nTable).on("search.dt.DT",function(t,e){if(n===e)try{u[0]!==y.activeElement&&u.val(o.sSearch)}catch(t){}}),l[0]}function Rt(t,e,n){function a(t){o.sSearch=t.sSearch,o.bRegex=t.bRegex,o.bSmart=t.bSmart,o.bCaseInsensitive=t.bCaseInsensitive,o.return=t.return}function r(t){return t.bEscapeRegex!==N?!t.bEscapeRegex:t.bRegex}var o=t.oPreviousSearch,i=t.aoPreSearchCols;if(lt(t),"ssp"!=E(t)){Nt(t,e.sSearch,n,r(e),e.bSmart,e.bCaseInsensitive,e.return),a(e);for(var l=0;l<i.length;l++)jt(t,i[l].sSearch,l,r(i[l]),i[l].bSmart,i[l].bCaseInsensitive);Pt(t)}else a(e);t.bFiltered=!0,R(t,null,"search",[t])}function Pt(t){for(var e,n,a=w.ext.search,r=t.aiDisplay,o=0,i=a.length;o<i;o++){for(var l=[],s=0,u=r.length;s<u;s++)n=r[s],e=t.aoData[n],a[o](t,e._aFilterData,n,e._aData,s)&&l.push(n);r.length=0,P.merge(r,l)}}function jt(t,e,n,a,r,o){if(""!==e){for(var i,l=[],s=t.aiDisplay,u=Ht(e,a,r,o),c=0;c<s.length;c++)i=t.aoData[s[c]]._aFilterData[n],u.test(i)&&l.push(s[c]);t.aiDisplay=l}}function Nt(t,e,n,a,r,o){var i,l,s,u=Ht(e,a,r,o),r=t.oPreviousSearch.sSearch,o=t.aiDisplayMaster,c=[];if(0!==w.ext.search.length&&(n=!0),l=Wt(t),e.length<=0)t.aiDisplay=o.slice();else{for((l||n||a||r.length>e.length||0!==e.indexOf(r)||t.bSorted)&&(t.aiDisplay=o.slice()),i=t.aiDisplay,s=0;s<i.length;s++)u.test(t.aoData[i[s]]._sFilterRow)&&c.push(i[s]);t.aiDisplay=c}}function Ht(t,e,n,a){return t=e?t:Ot(t),n&&(t="^(?=.*?"+P.map(t.match(/"[^"]+"|[^ ]+/g)||[""],function(t){var e;return(t='"'===t.charAt(0)?(e=t.match(/^"(.*)"$/))?e[1]:t:t).replace('"',"")}).join(")(?=.*?")+").*$"),new RegExp(t,a?"i":"")}var Ot=w.util.escapeRegex,kt=P("<div>")[0],Mt=kt.textContent!==N;function Wt(t){for(var e,n,a,r,o,i=t.aoColumns,l=!1,s=0,u=t.aoData.length;s<u;s++)if(!(o=t.aoData[s])._aFilterData){for(a=[],e=0,n=i.length;e<n;e++)i[e].bSearchable?"string"!=typeof(r=null===(r=S(t,s,e,"filter"))?"":r)&&r.toString&&(r=r.toString()):r="",r.indexOf&&-1!==r.indexOf("&")&&(kt.innerHTML=r,r=Mt?kt.textContent:kt.innerText),r.replace&&(r=r.replace(/[\r\n\u2028]/g,"")),a.push(r);o._aFilterData=a,o._sFilterRow=a.join("  "),l=!0}return l}function Et(t){return{search:t.sSearch,smart:t.bSmart,regex:t.bRegex,caseInsensitive:t.bCaseInsensitive}}function Bt(t){return{sSearch:t.search,bSmart:t.smart,bRegex:t.regex,bCaseInsensitive:t.caseInsensitive}}function Ut(t){var e=t.sTableId,n=t.aanFeatures.i,a=P("<div/>",{class:t.oClasses.sInfo,id:n?null:e+"_info"});return n||(t.aoDrawCallback.push({fn:Vt,sName:"information"}),a.attr("role","status").attr("aria-live","polite"),P(t.nTable).attr("aria-describedby",e+"_info")),a[0]}function Vt(t){var e,n,a,r,o,i,l=t.aanFeatures.i;0!==l.length&&(i=t.oLanguage,e=t._iDisplayStart+1,n=t.fnDisplayEnd(),a=t.fnRecordsTotal(),o=(r=t.fnRecordsDisplay())?i.sInfo:i.sInfoEmpty,r!==a&&(o+=" "+i.sInfoFiltered),o=Xt(t,o+=i.sInfoPostFix),null!==(i=i.fnInfoCallback)&&(o=i.call(t.oInstance,t,e,n,a,r,o)),P(l).html(o))}function Xt(t,e){var n=t.fnFormatNumber,a=t._iDisplayStart+1,r=t._iDisplayLength,o=t.fnRecordsDisplay(),i=-1===r;return e.replace(/_START_/g,n.call(t,a)).replace(/_END_/g,n.call(t,t.fnDisplayEnd())).replace(/_MAX_/g,n.call(t,t.fnRecordsTotal())).replace(/_TOTAL_/g,n.call(t,o)).replace(/_PAGE_/g,n.call(t,i?1:Math.ceil(a/r))).replace(/_PAGES_/g,n.call(t,i?1:Math.ceil(o/r)))}function Jt(n){var a,t,e,r=n.iInitDisplayStart,o=n.aoColumns,i=n.oFeatures,l=n.bDeferLoading;if(n.bInitialised){for(_t(n),yt(n),Dt(n,n.aoHeader),Dt(n,n.aoFooter),D(n,!0),i.bAutoWidth&&ee(n),a=0,t=o.length;a<t;a++)(e=o[a]).sWidth&&(e.nTh.style.width=M(e.sWidth));R(n,null,"preInit",[n]),u(n);i=E(n);"ssp"==i&&!l||("ajax"==i?Tt(n,[],function(t){var e=Ft(n,t);for(a=0;a<e.length;a++)x(n,e[a]);n.iInitDisplayStart=r,u(n),D(n,!1),qt(n,t)}):(D(n,!1),qt(n)))}else setTimeout(function(){Jt(n)},200)}function qt(t,e){t._bInitComplete=!0,(e||t.oInit.aaData)&&O(t),R(t,null,"plugin-init",[t,e]),R(t,"aoInitComplete","init",[t,e])}function Gt(t,e){e=parseInt(e,10);t._iDisplayLength=e,Se(t),R(t,null,"length",[t,e])}function $t(a){for(var t=a.oClasses,e=a.sTableId,n=a.aLengthMenu,r=Array.isArray(n[0]),o=r?n[0]:n,i=r?n[1]:n,l=P("<select/>",{name:e+"_length","aria-controls":e,class:t.sLengthSelect}),s=0,u=o.length;s<u;s++)l[0][s]=new Option("number"==typeof i[s]?a.fnFormatNumber(i[s]):i[s],o[s]);var c=P("<div><label/></div>").addClass(t.sLength);return a.aanFeatures.l||(c[0].id=e+"_length"),c.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",l[0].outerHTML)),P("select",c).val(a._iDisplayLength).on("change.DT",function(t){Gt(a,P(this).val()),v(a)}),P(a.nTable).on("length.dt.DT",function(t,e,n){a===e&&P("select",c).val(n)}),c[0]}function zt(t){function c(t){v(t)}var e=t.sPaginationType,f=w.ext.pager[e],d="function"==typeof f,e=P("<div/>").addClass(t.oClasses.sPaging+e)[0],h=t.aanFeatures;return d||f.fnInit(t,e,c),h.p||(e.id=t.sTableId+"_paginate",t.aoDrawCallback.push({fn:function(t){if(d)for(var e=t._iDisplayStart,n=t._iDisplayLength,a=t.fnRecordsDisplay(),r=-1===n,o=r?0:Math.ceil(e/n),i=r?1:Math.ceil(a/n),l=f(o,i),s=0,u=h.p.length;s<u;s++)ve(t,"pageButton")(t,h.p[s],s,l,o,i);else f.fnUpdate(t,c)},sName:"pagination"})),e}function Yt(t,e,n){var a=t._iDisplayStart,r=t._iDisplayLength,o=t.fnRecordsDisplay(),o=(0===o||-1===r?a=0:"number"==typeof e?o<(a=e*r)&&(a=0):"first"==e?a=0:"previous"==e?(a=0<=r?a-r:0)<0&&(a=0):"next"==e?a+r<o&&(a+=r):"last"==e?a=Math.floor((o-1)/r)*r:W(t,0,"Unknown paging action: "+e,5),t._iDisplayStart!==a);return t._iDisplayStart=a,o?(R(t,null,"page",[t]),n&&v(t)):R(t,null,"page-nc",[t]),o}function Zt(t){return P("<div/>",{id:t.aanFeatures.r?null:t.sTableId+"_processing",class:t.oClasses.sProcessing,role:"status"}).html(t.oLanguage.sProcessing).append("<div><div></div><div></div><div></div><div></div></div>").insertBefore(t.nTable)[0]}function D(t,e){t.oFeatures.bProcessing&&P(t.aanFeatures.r).css("display",e?"block":"none"),R(t,null,"processing",[t,e])}function Kt(t){var e,n,a,r,o,i,l,s,u,c,f,d,h=P(t.nTable),p=t.oScroll;return""===p.sX&&""===p.sY?t.nTable:(e=p.sX,n=p.sY,a=t.oClasses,o=(r=h.children("caption")).length?r[0]._captionSide:null,s=P(h[0].cloneNode(!1)),i=P(h[0].cloneNode(!1)),u=function(t){return t?M(t):null},(l=h.children("tfoot")).length||(l=null),s=P(f="<div/>",{class:a.sScrollWrapper}).append(P(f,{class:a.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:e?u(e):"100%"}).append(P(f,{class:a.sScrollHeadInner}).css({"box-sizing":"content-box",width:p.sXInner||"100%"}).append(s.removeAttr("id").css("margin-left",0).append("top"===o?r:null).append(h.children("thead"))))).append(P(f,{class:a.sScrollBody}).css({position:"relative",overflow:"auto",width:u(e)}).append(h)),l&&s.append(P(f,{class:a.sScrollFoot}).css({overflow:"hidden",border:0,width:e?u(e):"100%"}).append(P(f,{class:a.sScrollFootInner}).append(i.removeAttr("id").css("margin-left",0).append("bottom"===o?r:null).append(h.children("tfoot"))))),u=s.children(),c=u[0],f=u[1],d=l?u[2]:null,e&&P(f).on("scroll.DT",function(t){var e=this.scrollLeft;c.scrollLeft=e,l&&(d.scrollLeft=e)}),P(f).css("max-height",n),p.bCollapse||P(f).css("height",n),t.nScrollHead=c,t.nScrollBody=f,t.nScrollFoot=d,t.aoDrawCallback.push({fn:Qt,sName:"scrolling"}),s[0])}function Qt(n){function t(t){(t=t.style).paddingTop="0",t.paddingBottom="0",t.borderTopWidth="0",t.borderBottomWidth="0",t.height=0}var e,a,r,o,i,l=n.oScroll,s=l.sX,u=l.sXInner,c=l.sY,l=l.iBarWidth,f=P(n.nScrollHead),d=f[0].style,h=f.children("div"),p=h[0].style,h=h.children("table"),g=n.nScrollBody,b=P(g),m=g.style,S=P(n.nScrollFoot).children("div"),v=S.children("table"),y=P(n.nTHead),D=P(n.nTable),_=D[0],w=_.style,C=n.nTFoot?P(n.nTFoot):null,T=n.oBrowser,x=T.bScrollOversize,A=(H(n.aoColumns,"nTh"),[]),I=[],F=[],L=[],R=g.scrollHeight>g.clientHeight;n.scrollBarVis!==R&&n.scrollBarVis!==N?(n.scrollBarVis=R,O(n)):(n.scrollBarVis=R,D.children("thead, tfoot").remove(),C&&(R=C.clone().prependTo(D),i=C.find("tr"),a=R.find("tr"),R.find("[id]").removeAttr("id")),R=y.clone().prependTo(D),y=y.find("tr"),e=R.find("tr"),R.find("th, td").removeAttr("tabindex"),R.find("[id]").removeAttr("id"),s||(m.width="100%",f[0].style.width="100%"),P.each(Ct(n,R),function(t,e){r=rt(n,t),e.style.width=n.aoColumns[r].sWidth}),C&&k(function(t){t.style.width=""},a),f=D.outerWidth(),""===s?(w.width="100%",x&&(D.find("tbody").height()>g.offsetHeight||"scroll"==b.css("overflow-y"))&&(w.width=M(D.outerWidth()-l)),f=D.outerWidth()):""!==u&&(w.width=M(u),f=D.outerWidth()),k(t,e),k(function(t){var e=j.getComputedStyle?j.getComputedStyle(t).width:M(P(t).width());F.push(t.innerHTML),A.push(e)},e),k(function(t,e){t.style.width=A[e]},y),P(e).css("height",0),C&&(k(t,a),k(function(t){L.push(t.innerHTML),I.push(M(P(t).css("width")))},a),k(function(t,e){t.style.width=I[e]},i),P(a).height(0)),k(function(t,e){t.innerHTML='<div class="dataTables_sizing">'+F[e]+"</div>",t.childNodes[0].style.height="0",t.childNodes[0].style.overflow="hidden",t.style.width=A[e]},e),C&&k(function(t,e){t.innerHTML='<div class="dataTables_sizing">'+L[e]+"</div>",t.childNodes[0].style.height="0",t.childNodes[0].style.overflow="hidden",t.style.width=I[e]},a),Math.round(D.outerWidth())<Math.round(f)?(o=g.scrollHeight>g.offsetHeight||"scroll"==b.css("overflow-y")?f+l:f,x&&(g.scrollHeight>g.offsetHeight||"scroll"==b.css("overflow-y"))&&(w.width=M(o-l)),""!==s&&""===u||W(n,1,"Possible column misalignment",6)):o="100%",m.width=M(o),d.width=M(o),C&&(n.nScrollFoot.style.width=M(o)),c||x&&(m.height=M(_.offsetHeight+l)),R=D.outerWidth(),h[0].style.width=M(R),p.width=M(R),y=D.height()>g.clientHeight||"scroll"==b.css("overflow-y"),p[i="padding"+(T.bScrollbarLeft?"Left":"Right")]=y?l+"px":"0px",C&&(v[0].style.width=M(R),S[0].style.width=M(R),S[0].style[i]=y?l+"px":"0px"),D.children("colgroup").insertBefore(D.children("thead")),b.trigger("scroll"),!n.bSorted&&!n.bFiltered||n._drawHold||(g.scrollTop=0))}function k(t,e,n){for(var a,r,o=0,i=0,l=e.length;i<l;){for(a=e[i].firstChild,r=n?n[i].firstChild:null;a;)1===a.nodeType&&(n?t(a,r,o):t(a,o),o++),a=a.nextSibling,r=n?r.nextSibling:null;i++}}var te=/<.*?>/g;function ee(t){var e,n,a=t.nTable,r=t.aoColumns,o=t.oScroll,i=o.sY,l=o.sX,o=o.sXInner,s=r.length,u=it(t,"bVisible"),c=P("th",t.nTHead),f=a.getAttribute("width"),d=a.parentNode,h=!1,p=t.oBrowser,g=p.bScrollOversize,b=a.style.width;for(b&&-1!==b.indexOf("%")&&(f=b),D=0;D<u.length;D++)null!==(e=r[u[D]]).sWidth&&(e.sWidth=ae(e.sWidthOrig,d),h=!0);if(g||!h&&!l&&!i&&s==T(t)&&s==c.length)for(D=0;D<s;D++){var m=rt(t,D);null!==m&&(r[m].sWidth=M(c.eq(D).width()))}else{var b=P(a).clone().css("visibility","hidden").removeAttr("id"),S=(b.find("tbody tr").remove(),P("<tr/>").appendTo(b.find("tbody")));for(b.find("thead, tfoot").remove(),b.append(P(t.nTHead).clone()).append(P(t.nTFoot).clone()),b.find("tfoot th, tfoot td").css("width",""),c=Ct(t,b.find("thead")[0]),D=0;D<u.length;D++)e=r[u[D]],c[D].style.width=null!==e.sWidthOrig&&""!==e.sWidthOrig?M(e.sWidthOrig):"",e.sWidthOrig&&l&&P(c[D]).append(P("<div/>").css({width:e.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(t.aoData.length)for(D=0;D<u.length;D++)e=r[n=u[D]],P(re(t,n)).clone(!1).append(e.sContentPadding).appendTo(S);P("[name]",b).removeAttr("name");for(var v=P("<div/>").css(l||i?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(b).appendTo(d),y=(l&&o?b.width(o):l?(b.css("width","auto"),b.removeAttr("width"),b.width()<d.clientWidth&&f&&b.width(d.clientWidth)):i?b.width(d.clientWidth):f&&b.width(f),0),D=0;D<u.length;D++){var _=P(c[D]),w=_.outerWidth()-_.width(),_=p.bBounding?Math.ceil(c[D].getBoundingClientRect().width):_.outerWidth();y+=_,r[u[D]].sWidth=M(_-w)}a.style.width=M(y),v.remove()}f&&(a.style.width=M(f)),!f&&!l||t._reszEvt||(o=function(){P(j).on("resize.DT-"+t.sInstance,ne(function(){O(t)}))},g?setTimeout(o,1e3):o(),t._reszEvt=!0)}var ne=w.util.throttle;function ae(t,e){return t?(e=(t=P("<div/>").css("width",M(t)).appendTo(e||y.body))[0].offsetWidth,t.remove(),e):0}function re(t,e){var n,a=oe(t,e);return a<0?null:(n=t.aoData[a]).nTr?n.anCells[e]:P("<td/>").html(S(t,a,e,"display"))[0]}function oe(t,e){for(var n,a=-1,r=-1,o=0,i=t.aoData.length;o<i;o++)(n=(n=(n=S(t,o,e,"display")+"").replace(te,"")).replace(/&nbsp;/g," ")).length>a&&(a=n.length,r=o);return r}function M(t){return null===t?"0px":"number"==typeof t?t<0?"0px":t+"px":t.match(/\d$/)?t+"px":t}function I(t){function e(t){t.length&&!Array.isArray(t[0])?h.push(t):P.merge(h,t)}var n,a,r,o,i,l,s,u=[],c=t.aoColumns,f=t.aaSortingFixed,d=P.isPlainObject(f),h=[];for(Array.isArray(f)&&e(f),d&&f.pre&&e(f.pre),e(t.aaSorting),d&&f.post&&e(f.post),n=0;n<h.length;n++)for(r=(o=c[s=h[n][a=0]].aDataSort).length;a<r;a++)l=c[i=o[a]].sType||"string",h[n]._idx===N&&(h[n]._idx=P.inArray(h[n][1],c[i].asSorting)),u.push({src:s,col:i,dir:h[n][1],index:h[n]._idx,type:l,formatter:w.ext.type.order[l+"-pre"]});return u}function ie(t){var e,n,a,r,c,f=[],u=w.ext.type.order,d=t.aoData,o=(t.aoColumns,0),i=t.aiDisplayMaster;for(lt(t),e=0,n=(c=I(t)).length;e<n;e++)(r=c[e]).formatter&&o++,fe(t,r.col);if("ssp"!=E(t)&&0!==c.length){for(e=0,a=i.length;e<a;e++)f[i[e]]=e;o===c.length?i.sort(function(t,e){for(var n,a,r,o,i=c.length,l=d[t]._aSortData,s=d[e]._aSortData,u=0;u<i;u++)if(0!=(r=(n=l[(o=c[u]).col])<(a=s[o.col])?-1:a<n?1:0))return"asc"===o.dir?r:-r;return(n=f[t])<(a=f[e])?-1:a<n?1:0}):i.sort(function(t,e){for(var n,a,r,o=c.length,i=d[t]._aSortData,l=d[e]._aSortData,s=0;s<o;s++)if(n=i[(r=c[s]).col],a=l[r.col],0!==(r=(u[r.type+"-"+r.dir]||u["string-"+r.dir])(n,a)))return r;return(n=f[t])<(a=f[e])?-1:a<n?1:0})}t.bSorted=!0}function le(t){for(var e=t.aoColumns,n=I(t),a=t.oLanguage.oAria,r=0,o=e.length;r<o;r++){var i=e[r],l=i.asSorting,s=i.ariaTitle||i.sTitle.replace(/<.*?>/g,""),u=i.nTh;u.removeAttribute("aria-sort"),i=i.bSortable?s+("asc"===(0<n.length&&n[0].col==r&&(u.setAttribute("aria-sort","asc"==n[0].dir?"ascending":"descending"),l[n[0].index+1])||l[0])?a.sSortAscending:a.sSortDescending):s,u.setAttribute("aria-label",i)}}function se(t,e,n,a){function r(t,e){var n=t._idx;return(n=n===N?P.inArray(t[1],s):n)+1<s.length?n+1:e?null:0}var o,i=t.aoColumns[e],l=t.aaSorting,s=i.asSorting;"number"==typeof l[0]&&(l=t.aaSorting=[l]),n&&t.oFeatures.bSortMulti?-1!==(i=P.inArray(e,H(l,"0")))?null===(o=null===(o=r(l[i],!0))&&1===l.length?0:o)?l.splice(i,1):(l[i][1]=s[o],l[i]._idx=o):(l.push([e,s[0],0]),l[l.length-1]._idx=0):l.length&&l[0][0]==e?(o=r(l[0]),l.length=1,l[0][1]=s[o],l[0]._idx=o):(l.length=0,l.push([e,s[0]]),l[0]._idx=0),u(t),"function"==typeof a&&a(t)}function ue(e,t,n,a){var r=e.aoColumns[n];me(t,{},function(t){!1!==r.bSortable&&(e.oFeatures.bProcessing?(D(e,!0),setTimeout(function(){se(e,n,t.shiftKey,a),"ssp"!==E(e)&&D(e,!1)},0)):se(e,n,t.shiftKey,a))})}function ce(t){var e,n,a,r=t.aLastSort,o=t.oClasses.sSortColumn,i=I(t),l=t.oFeatures;if(l.bSort&&l.bSortClasses){for(e=0,n=r.length;e<n;e++)a=r[e].src,P(H(t.aoData,"anCells",a)).removeClass(o+(e<2?e+1:3));for(e=0,n=i.length;e<n;e++)a=i[e].src,P(H(t.aoData,"anCells",a)).addClass(o+(e<2?e+1:3))}t.aLastSort=i}function fe(t,e){for(var n,a,r,o=t.aoColumns[e],i=w.ext.order[o.sSortDataType],l=(i&&(n=i.call(t.oInstance,t,e,ot(t,e))),w.ext.type.order[o.sType+"-pre"]),s=0,u=t.aoData.length;s<u;s++)(a=t.aoData[s])._aSortData||(a._aSortData=[]),a._aSortData[e]&&!i||(r=i?n[s]:S(t,s,e,"sort"),a._aSortData[e]=l?l(r):r)}function de(n){var t;n._bLoadingState||(t={time:+new Date,start:n._iDisplayStart,length:n._iDisplayLength,order:P.extend(!0,[],n.aaSorting),search:Et(n.oPreviousSearch),columns:P.map(n.aoColumns,function(t,e){return{visible:t.bVisible,search:Et(n.aoPreSearchCols[e])}})},n.oSavedState=t,R(n,"aoStateSaveParams","stateSaveParams",[n,t]),n.oFeatures.bStateSave&&!n.bDestroying&&n.fnStateSaveCallback.call(n.oInstance,n,t))}function he(e,t,n){var a;if(e.oFeatures.bStateSave)return(a=e.fnStateLoadCallback.call(e.oInstance,e,function(t){pe(e,t,n)}))!==N&&pe(e,a,n),!0;n()}function pe(n,t,e){var a,r,o=n.aoColumns,i=(n._bLoadingState=!0,n._bInitComplete?new w.Api(n):null);if(t&&t.time){var l=R(n,"aoStateLoadParams","stateLoadParams",[n,t]);if(-1!==P.inArray(!1,l))n._bLoadingState=!1;else{l=n.iStateDuration;if(0<l&&t.time<+new Date-1e3*l)n._bLoadingState=!1;else if(t.columns&&o.length!==t.columns.length)n._bLoadingState=!1;else{if(n.oLoadedState=P.extend(!0,{},t),t.length!==N&&(i?i.page.len(t.length):n._iDisplayLength=t.length),t.start!==N&&(null===i?(n._iDisplayStart=t.start,n.iInitDisplayStart=t.start):Yt(n,t.start/n._iDisplayLength)),t.order!==N&&(n.aaSorting=[],P.each(t.order,function(t,e){n.aaSorting.push(e[0]>=o.length?[0,e[1]]:e)})),t.search!==N&&P.extend(n.oPreviousSearch,Bt(t.search)),t.columns){for(a=0,r=t.columns.length;a<r;a++){var s=t.columns[a];s.visible!==N&&(i?i.column(a).visible(s.visible,!1):o[a].bVisible=s.visible),s.search!==N&&P.extend(n.aoPreSearchCols[a],Bt(s.search))}i&&i.columns.adjust()}n._bLoadingState=!1,R(n,"aoStateLoaded","stateLoaded",[n,t])}}}else n._bLoadingState=!1;e()}function ge(t){var e=w.settings,t=P.inArray(t,H(e,"nTable"));return-1!==t?e[t]:null}function W(t,e,n,a){if(n="DataTables warning: "+(t?"table id="+t.sTableId+" - ":"")+n,a&&(n+=". For more information about this error, please see http://datatables.net/tn/"+a),e)j.console&&console.log&&console.log(n);else{e=w.ext,e=e.sErrMode||e.errMode;if(t&&R(t,null,"error",[t,a,n]),"alert"==e)alert(n);else{if("throw"==e)throw new Error(n);"function"==typeof e&&e(t,a,n)}}}function F(n,a,t,e){Array.isArray(t)?P.each(t,function(t,e){Array.isArray(e)?F(n,a,e[0],e[1]):F(n,a,e)}):(e===N&&(e=t),a[t]!==N&&(n[e]=a[t]))}function be(t,e,n){var a,r;for(r in e)e.hasOwnProperty(r)&&(a=e[r],P.isPlainObject(a)?(P.isPlainObject(t[r])||(t[r]={}),P.extend(!0,t[r],a)):n&&"data"!==r&&"aaData"!==r&&Array.isArray(a)?t[r]=a.slice():t[r]=a);return t}function me(e,t,n){P(e).on("click.DT",t,function(t){P(e).trigger("blur"),n(t)}).on("keypress.DT",t,function(t){13===t.which&&(t.preventDefault(),n(t))}).on("selectstart.DT",function(){return!1})}function L(t,e,n,a){n&&t[e].push({fn:n,sName:a})}function R(n,t,e,a){var r=[];return t&&(r=P.map(n[t].slice().reverse(),function(t,e){return t.fn.apply(n.oInstance,a)})),null!==e&&(t=P.Event(e+".dt"),(e=P(n.nTable)).trigger(t,a),0===e.parents("body").length&&P("body").trigger(t,a),r.push(t.result)),r}function Se(t){var e=t._iDisplayStart,n=t.fnDisplayEnd(),a=t._iDisplayLength;n<=e&&(e=n-a),e-=e%a,t._iDisplayStart=e=-1===a||e<0?0:e}function ve(t,e){var t=t.renderer,n=w.ext.renderer[e];return P.isPlainObject(t)&&t[e]?n[t[e]]||n._:"string"==typeof t&&n[t]||n._}function E(t){return t.oFeatures.bServerSide?"ssp":t.ajax||t.sAjaxSource?"ajax":"dom"}function ye(t,n){var a;return Array.isArray(t)?P.map(t,function(t){return ye(t,n)}):"number"==typeof t?[n[t]]:(a=P.map(n,function(t,e){return t.nTable}),P(a).filter(t).map(function(t){var e=P.inArray(this,a);return n[e]}).toArray())}function De(r,o,t){var e,n;t&&(e=new B(r)).one("draw",function(){t(e.ajax.json())}),"ssp"==E(r)?u(r,o):(D(r,!0),(n=r.jqXHR)&&4!==n.readyState&&n.abort(),Tt(r,[],function(t){pt(r);for(var e=Ft(r,t),n=0,a=e.length;n<a;n++)x(r,e[n]);u(r,o),D(r,!1)}))}function _e(t,e,n,a,r){for(var o,i,l,s,u=[],c=typeof e,f=0,d=(e=e&&"string"!=c&&"function"!=c&&e.length!==N?e:[e]).length;f<d;f++)for(l=0,s=(i=e[f]&&e[f].split&&!e[f].match(/[\[\(:]/)?e[f].split(","):[e[f]]).length;l<s;l++)(o=n("string"==typeof i[l]?i[l].trim():i[l]))&&o.length&&(u=u.concat(o));var h=p.selector[t];if(h.length)for(f=0,d=h.length;f<d;f++)u=h[f](a,r,u);return z(u)}function we(t){return(t=t||{}).filter&&t.search===N&&(t.search=t.filter),P.extend({search:"none",order:"current",page:"all"},t)}function Ce(t){for(var e=0,n=t.length;e<n;e++)if(0<t[e].length)return t[0]=t[e],t[0].length=1,t.length=1,t.context=[t.context[e]],t;return t.length=0,t}function Te(o,t,e,n){function i(t,e){var n;if(Array.isArray(t)||t instanceof P)for(var a=0,r=t.length;a<r;a++)i(t[a],e);else t.nodeName&&"tr"===t.nodeName.toLowerCase()?l.push(t):(n=P("<tr><td></td></tr>").addClass(e),P("td",n).addClass(e).html(t)[0].colSpan=T(o),l.push(n[0]))}var l=[];i(e,n),t._details&&t._details.detach(),t._details=P(l),t._detailsShow&&t._details.insertAfter(t.nTr)}function xe(t,e){var n=t.context;if(n.length&&t.length){var a=n[0].aoData[t[0]];if(a._details){(a._detailsShow=e)?(a._details.insertAfter(a.nTr),P(a.nTr).addClass("dt-hasChild")):(a._details.detach(),P(a.nTr).removeClass("dt-hasChild")),R(n[0],null,"childRow",[e,t.row(t[0])]);var s=n[0],r=new B(s),a=".dt.DT_details",e="draw"+a,t="column-sizing"+a,a="destroy"+a,u=s.aoData;if(r.off(e+" "+t+" "+a),H(u,"_details").length>0){r.on(e,function(t,e){if(s!==e)return;r.rows({page:"current"}).eq(0).each(function(t){var e=u[t];if(e._detailsShow)e._details.insertAfter(e.nTr)})});r.on(t,function(t,e,n,a){if(s!==e)return;var r,o=T(e);for(var i=0,l=u.length;i<l;i++){r=u[i];if(r._details)r._details.children("td[colspan]").attr("colspan",o)}});r.on(a,function(t,e){if(s!==e)return;for(var n=0,a=u.length;n<a;n++)if(u[n]._details)Re(r,n)})}Le(n)}}}function Ae(t,e,n,a,r){for(var o=[],i=0,l=r.length;i<l;i++)o.push(S(t,r[i],e));return o}var Ie=[],o=Array.prototype,B=function(t,e){if(!(this instanceof B))return new B(t,e);function n(t){var e,n,a,r;t=t,a=w.settings,r=P.map(a,function(t,e){return t.nTable}),(t=t?t.nTable&&t.oApi?[t]:t.nodeName&&"table"===t.nodeName.toLowerCase()?-1!==(e=P.inArray(t,r))?[a[e]]:null:t&&"function"==typeof t.settings?t.settings().toArray():("string"==typeof t?n=P(t):t instanceof P&&(n=t),n?n.map(function(t){return-1!==(e=P.inArray(this,r))?a[e]:null}).toArray():void 0):[])&&o.push.apply(o,t)}var o=[];if(Array.isArray(t))for(var a=0,r=t.length;a<r;a++)n(t[a]);else n(t);this.context=z(o),e&&P.merge(this,e),this.selector={rows:null,cols:null,opts:null},B.extend(this,this,Ie)},Fe=(w.Api=B,P.extend(B.prototype,{any:function(){return 0!==this.count()},concat:o.concat,context:[],count:function(){return this.flatten().length},each:function(t){for(var e=0,n=this.length;e<n;e++)t.call(this,this[e],e,this);return this},eq:function(t){var e=this.context;return e.length>t?new B(e[t],this[t]):null},filter:function(t){var e=[];if(o.filter)e=o.filter.call(this,t,this);else for(var n=0,a=this.length;n<a;n++)t.call(this,this[n],n,this)&&e.push(this[n]);return new B(this.context,e)},flatten:function(){var t=[];return new B(this.context,t.concat.apply(t,this.toArray()))},join:o.join,indexOf:o.indexOf||function(t,e){for(var n=e||0,a=this.length;n<a;n++)if(this[n]===t)return n;return-1},iterator:function(t,e,n,a){var r,o,i,l,s,u,c,f,d=[],h=this.context,p=this.selector;for("string"==typeof t&&(a=n,n=e,e=t,t=!1),o=0,i=h.length;o<i;o++){var g=new B(h[o]);if("table"===e)(r=n.call(g,h[o],o))!==N&&d.push(r);else if("columns"===e||"rows"===e)(r=n.call(g,h[o],this[o],o))!==N&&d.push(r);else if("column"===e||"column-rows"===e||"row"===e||"cell"===e)for(c=this[o],"column-rows"===e&&(u=Fe(h[o],p.opts)),l=0,s=c.length;l<s;l++)f=c[l],(r="cell"===e?n.call(g,h[o],f.row,f.column,o,l):n.call(g,h[o],f,o,l,u))!==N&&d.push(r)}return d.length||a?((t=(a=new B(h,t?d.concat.apply([],d):d)).selector).rows=p.rows,t.cols=p.cols,t.opts=p.opts,a):this},lastIndexOf:o.lastIndexOf||function(t,e){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(t){var e=[];if(o.map)e=o.map.call(this,t,this);else for(var n=0,a=this.length;n<a;n++)e.push(t.call(this,this[n],n));return new B(this.context,e)},pluck:function(t){var e=w.util.get(t);return this.map(function(t){return e(t)})},pop:o.pop,push:o.push,reduce:o.reduce||function(t,e){return et(this,t,e,0,this.length,1)},reduceRight:o.reduceRight||function(t,e){return et(this,t,e,this.length-1,-1,-1)},reverse:o.reverse,selector:null,shift:o.shift,slice:function(){return new B(this.context,this)},sort:o.sort,splice:o.splice,toArray:function(){return o.slice.call(this)},to$:function(){return P(this)},toJQuery:function(){return P(this)},unique:function(){return new B(this.context,z(this))},unshift:o.unshift}),B.extend=function(t,e,n){if(n.length&&e&&(e instanceof B||e.__dt_wrapper))for(var a,r=0,o=n.length;r<o;r++)e[(a=n[r]).name]="function"===a.type?function(e,n,a){return function(){var t=n.apply(e,arguments);return B.extend(t,t,a.methodExt),t}}(t,a.val,a):"object"===a.type?{}:a.val,e[a.name].__dt_wrapper=!0,B.extend(t,e[a.name],a.propExt)},B.register=e=function(t,e){if(Array.isArray(t))for(var n=0,a=t.length;n<a;n++)B.register(t[n],e);else for(var r=t.split("."),o=Ie,i=0,l=r.length;i<l;i++){var s,u,c=function(t,e){for(var n=0,a=t.length;n<a;n++)if(t[n].name===e)return t[n];return null}(o,u=(s=-1!==r[i].indexOf("()"))?r[i].replace("()",""):r[i]);c||o.push(c={name:u,val:{},methodExt:[],propExt:[],type:"object"}),i===l-1?(c.val=e,c.type="function"==typeof e?"function":P.isPlainObject(e)?"object":"other"):o=s?c.methodExt:c.propExt}},B.registerPlural=t=function(t,e,n){B.register(t,n),B.register(e,function(){var t=n.apply(this,arguments);return t===this?this:t instanceof B?t.length?Array.isArray(t[0])?new B(t.context,t[0]):t[0]:N:t})},e("tables()",function(t){return t!==N&&null!==t?new B(ye(t,this.context)):this}),e("table()",function(t){var t=this.tables(t),e=t.context;return e.length?new B(e[0]):t}),t("tables().nodes()","table().node()",function(){return this.iterator("table",function(t){return t.nTable},1)}),t("tables().body()","table().body()",function(){return this.iterator("table",function(t){return t.nTBody},1)}),t("tables().header()","table().header()",function(){return this.iterator("table",function(t){return t.nTHead},1)}),t("tables().footer()","table().footer()",function(){return this.iterator("table",function(t){return t.nTFoot},1)}),t("tables().containers()","table().container()",function(){return this.iterator("table",function(t){return t.nTableWrapper},1)}),e("draw()",function(e){return this.iterator("table",function(t){"page"===e?v(t):u(t,!1===(e="string"==typeof e?"full-hold"!==e:e))})}),e("page()",function(e){return e===N?this.page.info().page:this.iterator("table",function(t){Yt(t,e)})}),e("page.info()",function(t){var e,n,a,r,o;return 0===this.context.length?N:(n=(e=this.context[0])._iDisplayStart,a=e.oFeatures.bPaginate?e._iDisplayLength:-1,r=e.fnRecordsDisplay(),{page:(o=-1===a)?0:Math.floor(n/a),pages:o?1:Math.ceil(r/a),start:n,end:e.fnDisplayEnd(),length:a,recordsTotal:e.fnRecordsTotal(),recordsDisplay:r,serverSide:"ssp"===E(e)})}),e("page.len()",function(e){return e===N?0!==this.context.length?this.context[0]._iDisplayLength:N:this.iterator("table",function(t){Gt(t,e)})}),e("ajax.json()",function(){var t=this.context;if(0<t.length)return t[0].json}),e("ajax.params()",function(){var t=this.context;if(0<t.length)return t[0].oAjaxData}),e("ajax.reload()",function(e,n){return this.iterator("table",function(t){De(t,!1===n,e)})}),e("ajax.url()",function(e){var t=this.context;return e===N?0===t.length?N:(t=t[0]).ajax?P.isPlainObject(t.ajax)?t.ajax.url:t.ajax:t.sAjaxSource:this.iterator("table",function(t){P.isPlainObject(t.ajax)?t.ajax.url=e:t.ajax=e})}),e("ajax.url().load()",function(e,n){return this.iterator("table",function(t){De(t,!1===n,e)})}),function(t,e){var n,a=[],r=t.aiDisplay,o=t.aiDisplayMaster,i=e.search,l=e.order,e=e.page;if("ssp"==E(t))return"removed"===i?[]:f(0,o.length);if("current"==e)for(u=t._iDisplayStart,c=t.fnDisplayEnd();u<c;u++)a.push(r[u]);else if("current"==l||"applied"==l){if("none"==i)a=o.slice();else if("applied"==i)a=r.slice();else if("removed"==i){for(var s={},u=0,c=r.length;u<c;u++)s[r[u]]=null;a=P.map(o,function(t){return s.hasOwnProperty(t)?null:t})}}else if("index"==l||"original"==l)for(u=0,c=t.aoData.length;u<c;u++)("none"==i||-1===(n=P.inArray(u,r))&&"removed"==i||0<=n&&"applied"==i)&&a.push(u);return a}),Le=(e("rows()",function(e,n){e===N?e="":P.isPlainObject(e)&&(n=e,e=""),n=we(n);var t=this.iterator("table",function(t){return _e("row",e,function(n){var t=d(n),a=r.aoData;if(null!==t&&!o)return[t];if(i=i||Fe(r,o),null!==t&&-1!==P.inArray(t,i))return[t];if(null===n||n===N||""===n)return i;if("function"==typeof n)return P.map(i,function(t){var e=a[t];return n(t,e._aData,e.nTr)?t:null});if(n.nodeName)return t=n._DT_RowIndex,e=n._DT_CellIndex,t!==N?a[t]&&a[t].nTr===n?[t]:[]:e?a[e.row]&&a[e.row].nTr===n.parentNode?[e.row]:[]:(t=P(n).closest("*[data-dt-row]")).length?[t.data("dt-row")]:[];if("string"==typeof n&&"#"===n.charAt(0)){var e=r.aIds[n.replace(/^#/,"")];if(e!==N)return[e.idx]}t=_(m(r.aoData,i,"nTr"));return P(t).filter(n).map(function(){return this._DT_RowIndex}).toArray()},r=t,o=n);var r,o,i},1);return t.selector.rows=e,t.selector.opts=n,t}),e("rows().nodes()",function(){return this.iterator("row",function(t,e){return t.aoData[e].nTr||N},1)}),e("rows().data()",function(){return this.iterator(!0,"rows",function(t,e){return m(t.aoData,e,"_aData")},1)}),t("rows().cache()","row().cache()",function(n){return this.iterator("row",function(t,e){t=t.aoData[e];return"search"===n?t._aFilterData:t._aSortData},1)}),t("rows().invalidate()","row().invalidate()",function(n){return this.iterator("row",function(t,e){bt(t,e,n)})}),t("rows().indexes()","row().index()",function(){return this.iterator("row",function(t,e){return e},1)}),t("rows().ids()","row().id()",function(t){for(var e=[],n=this.context,a=0,r=n.length;a<r;a++)for(var o=0,i=this[a].length;o<i;o++){var l=n[a].rowIdFn(n[a].aoData[this[a][o]]._aData);e.push((!0===t?"#":"")+l)}return new B(n,e)}),t("rows().remove()","row().remove()",function(){var f=this;return this.iterator("row",function(t,e,n){var a,r,o,i,l,s,u=t.aoData,c=u[e];for(u.splice(e,1),a=0,r=u.length;a<r;a++)if(s=(l=u[a]).anCells,null!==l.nTr&&(l.nTr._DT_RowIndex=a),null!==s)for(o=0,i=s.length;o<i;o++)s[o]._DT_CellIndex.row=a;gt(t.aiDisplayMaster,e),gt(t.aiDisplay,e),gt(f[n],e,!1),0<t._iRecordsDisplay&&t._iRecordsDisplay--,Se(t);n=t.rowIdFn(c._aData);n!==N&&delete t.aIds[n]}),this.iterator("table",function(t){for(var e=0,n=t.aoData.length;e<n;e++)t.aoData[e].idx=e}),this}),e("rows.add()",function(o){var t=this.iterator("table",function(t){for(var e,n=[],a=0,r=o.length;a<r;a++)(e=o[a]).nodeName&&"TR"===e.nodeName.toUpperCase()?n.push(ut(t,e)[0]):n.push(x(t,e));return n},1),e=this.rows(-1);return e.pop(),P.merge(e,t),e}),e("row()",function(t,e){return Ce(this.rows(t,e))}),e("row().data()",function(t){var e,n=this.context;return t===N?n.length&&this.length?n[0].aoData[this[0]]._aData:N:((e=n[0].aoData[this[0]])._aData=t,Array.isArray(t)&&e.nTr&&e.nTr.id&&b(n[0].rowId)(t,e.nTr.id),bt(n[0],this[0],"data"),this)}),e("row().node()",function(){var t=this.context;return t.length&&this.length&&t[0].aoData[this[0]].nTr||null}),e("row.add()",function(e){e instanceof P&&e.length&&(e=e[0]);var t=this.iterator("table",function(t){return e.nodeName&&"TR"===e.nodeName.toUpperCase()?ut(t,e)[0]:x(t,e)});return this.row(t[0])}),P(y).on("plugin-init.dt",function(t,e){var n=new B(e),a="on-plugin-init",r="stateSaveParams."+a,o="destroy. "+a,a=(n.on(r,function(t,e,n){for(var a=e.rowIdFn,r=e.aoData,o=[],i=0;i<r.length;i++)r[i]._detailsShow&&o.push("#"+a(r[i]._aData));n.childRows=o}),n.on(o,function(){n.off(r+" "+o)}),n.state.loaded());a&&a.childRows&&n.rows(P.map(a.childRows,function(t){return t.replace(/:/g,"\\:")})).every(function(){R(e,null,"requestChild",[this])})}),w.util.throttle(function(t){de(t[0])},500)),Re=function(t,e){var n=t.context;n.length&&(e=n[0].aoData[e!==N?e:t[0]])&&e._details&&(e._details.remove(),e._detailsShow=N,e._details=N,P(e.nTr).removeClass("dt-hasChild"),Le(n))},Pe="row().child",je=Pe+"()",Ne=(e(je,function(t,e){var n=this.context;return t===N?n.length&&this.length?n[0].aoData[this[0]]._details:N:(!0===t?this.child.show():!1===t?Re(this):n.length&&this.length&&Te(n[0],n[0].aoData[this[0]],t,e),this)}),e([Pe+".show()",je+".show()"],function(t){return xe(this,!0),this}),e([Pe+".hide()",je+".hide()"],function(){return xe(this,!1),this}),e([Pe+".remove()",je+".remove()"],function(){return Re(this),this}),e(Pe+".isShown()",function(){var t=this.context;return t.length&&this.length&&t[0].aoData[this[0]]._detailsShow||!1}),/^([^:]+):(name|visIdx|visible)$/),He=(e("columns()",function(n,a){n===N?n="":P.isPlainObject(n)&&(a=n,n=""),a=we(a);var t=this.iterator("table",function(t){return e=n,l=a,s=(i=t).aoColumns,u=H(s,"sName"),c=H(s,"nTh"),_e("column",e,function(n){var a,t=d(n);if(""===n)return f(s.length);if(null!==t)return[0<=t?t:s.length+t];if("function"==typeof n)return a=Fe(i,l),P.map(s,function(t,e){return n(e,Ae(i,e,0,0,a),c[e])?e:null});var r="string"==typeof n?n.match(Ne):"";if(r)switch(r[2]){case"visIdx":case"visible":var e,o=parseInt(r[1],10);return o<0?[(e=P.map(s,function(t,e){return t.bVisible?e:null}))[e.length+o]]:[rt(i,o)];case"name":return P.map(u,function(t,e){return t===r[1]?e:null});default:return[]}return n.nodeName&&n._DT_CellIndex?[n._DT_CellIndex.column]:(t=P(c).filter(n).map(function(){return P.inArray(this,c)}).toArray()).length||!n.nodeName?t:(t=P(n).closest("*[data-dt-column]")).length?[t.data("dt-column")]:[]},i,l);var i,e,l,s,u,c},1);return t.selector.cols=n,t.selector.opts=a,t}),t("columns().header()","column().header()",function(t,e){return this.iterator("column",function(t,e){return t.aoColumns[e].nTh},1)}),t("columns().footer()","column().footer()",function(t,e){return this.iterator("column",function(t,e){return t.aoColumns[e].nTf},1)}),t("columns().data()","column().data()",function(){return this.iterator("column-rows",Ae,1)}),t("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(t,e){return t.aoColumns[e].mData},1)}),t("columns().cache()","column().cache()",function(o){return this.iterator("column-rows",function(t,e,n,a,r){return m(t.aoData,r,"search"===o?"_aFilterData":"_aSortData",e)},1)}),t("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(t,e,n,a,r){return m(t.aoData,r,"anCells",e)},1)}),t("columns().visible()","column().visible()",function(f,n){var e=this,t=this.iterator("column",function(t,e){if(f===N)return t.aoColumns[e].bVisible;var n,a,r=e,e=f,o=t.aoColumns,i=o[r],l=t.aoData;if(e===N)i.bVisible;else if(i.bVisible!==e){if(e)for(var s=P.inArray(!0,H(o,"bVisible"),r+1),u=0,c=l.length;u<c;u++)a=l[u].nTr,n=l[u].anCells,a&&a.insertBefore(n[r],n[s]||null);else P(H(t.aoData,"anCells",r)).detach();i.bVisible=e}});return f!==N&&this.iterator("table",function(t){Dt(t,t.aoHeader),Dt(t,t.aoFooter),t.aiDisplay.length||P(t.nTBody).find("td[colspan]").attr("colspan",T(t)),de(t),e.iterator("column",function(t,e){R(t,null,"column-visibility",[t,e,f,n])}),n!==N&&!n||e.columns.adjust()}),t}),t("columns().indexes()","column().index()",function(n){return this.iterator("column",function(t,e){return"visible"===n?ot(t,e):e},1)}),e("columns.adjust()",function(){return this.iterator("table",function(t){O(t)},1)}),e("column.index()",function(t,e){var n;if(0!==this.context.length)return n=this.context[0],"fromVisible"===t||"toData"===t?rt(n,e):"fromData"===t||"toVisible"===t?ot(n,e):void 0}),e("column()",function(t,e){return Ce(this.columns(t,e))}),e("cells()",function(g,t,b){var a,r,o,i,l,s,e;return P.isPlainObject(g)&&(g.row===N?(b=g,g=null):(b=t,t=null)),P.isPlainObject(t)&&(b=t,t=null),null===t||t===N?this.iterator("table",function(t){return a=t,t=g,e=we(b),f=a.aoData,d=Fe(a,e),n=_(m(f,d,"anCells")),h=P(Y([],n)),p=a.aoColumns.length,_e("cell",t,function(t){var e,n="function"==typeof t;if(null===t||t===N||n){for(o=[],i=0,l=d.length;i<l;i++)for(r=d[i],s=0;s<p;s++)u={row:r,column:s},(!n||(c=f[r],t(u,S(a,r,s),c.anCells?c.anCells[s]:null)))&&o.push(u);return o}return P.isPlainObject(t)?t.column!==N&&t.row!==N&&-1!==P.inArray(t.row,d)?[t]:[]:(e=h.filter(t).map(function(t,e){return{row:e._DT_CellIndex.row,column:e._DT_CellIndex.column}}).toArray()).length||!t.nodeName?e:(c=P(t).closest("*[data-dt-row]")).length?[{row:c.data("dt-row"),column:c.data("dt-column")}]:[]},a,e);var a,e,r,o,i,l,s,u,c,f,d,n,h,p}):(e=b?{page:b.page,order:b.order,search:b.search}:{},a=this.columns(t,e),r=this.rows(g,e),e=this.iterator("table",function(t,e){var n=[];for(o=0,i=r[e].length;o<i;o++)for(l=0,s=a[e].length;l<s;l++)n.push({row:r[e][o],column:a[e][l]});return n},1),e=b&&b.selected?this.cells(e,b):e,P.extend(e.selector,{cols:t,rows:g,opts:b}),e)}),t("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(t,e,n){t=t.aoData[e];return t&&t.anCells?t.anCells[n]:N},1)}),e("cells().data()",function(){return this.iterator("cell",function(t,e,n){return S(t,e,n)},1)}),t("cells().cache()","cell().cache()",function(a){return a="search"===a?"_aFilterData":"_aSortData",this.iterator("cell",function(t,e,n){return t.aoData[e][a][n]},1)}),t("cells().render()","cell().render()",function(a){return this.iterator("cell",function(t,e,n){return S(t,e,n,a)},1)}),t("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(t,e,n){return{row:e,column:n,columnVisible:ot(t,n)}},1)}),t("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(t,e,n){bt(t,e,a,n)})}),e("cell()",function(t,e,n){return Ce(this.cells(t,e,n))}),e("cell().data()",function(t){var e=this.context,n=this[0];return t===N?e.length&&n.length?S(e[0],n[0].row,n[0].column):N:(ct(e[0],n[0].row,n[0].column,t),bt(e[0],n[0].row,"data",n[0].column),this)}),e("order()",function(e,t){var n=this.context;return e===N?0!==n.length?n[0].aaSorting:N:("number"==typeof e?e=[[e,t]]:e.length&&!Array.isArray(e[0])&&(e=Array.prototype.slice.call(arguments)),this.iterator("table",function(t){t.aaSorting=e.slice()}))}),e("order.listener()",function(e,n,a){return this.iterator("table",function(t){ue(t,e,n,a)})}),e("order.fixed()",function(e){var t;return e?this.iterator("table",function(t){t.aaSortingFixed=P.extend(!0,{},e)}):(t=(t=this.context).length?t[0].aaSortingFixed:N,Array.isArray(t)?{pre:t}:t)}),e(["columns().order()","column().order()"],function(a){var r=this;return this.iterator("table",function(t,e){var n=[];P.each(r[e],function(t,e){n.push([e,a])}),t.aaSorting=n})}),e("search()",function(e,n,a,r){var t=this.context;return e===N?0!==t.length?t[0].oPreviousSearch.sSearch:N:this.iterator("table",function(t){t.oFeatures.bFilter&&Rt(t,P.extend({},t.oPreviousSearch,{sSearch:e+"",bRegex:null!==n&&n,bSmart:null===a||a,bCaseInsensitive:null===r||r}),1)})}),t("columns().search()","column().search()",function(a,r,o,i){return this.iterator("column",function(t,e){var n=t.aoPreSearchCols;if(a===N)return n[e].sSearch;t.oFeatures.bFilter&&(P.extend(n[e],{sSearch:a+"",bRegex:null!==r&&r,bSmart:null===o||o,bCaseInsensitive:null===i||i}),Rt(t,t.oPreviousSearch,1))})}),e("state()",function(){return this.context.length?this.context[0].oSavedState:null}),e("state.clear()",function(){return this.iterator("table",function(t){t.fnStateSaveCallback.call(t.oInstance,t,{})})}),e("state.loaded()",function(){return this.context.length?this.context[0].oLoadedState:null}),e("state.save()",function(){return this.iterator("table",function(t){de(t)})}),w.use=function(t,e){"lib"===e||t.fn?P=t:"win"!=e&&!t.document||(y=(j=t).document)},w.factory=function(t,e){var n=!1;return t&&t.document&&(y=(j=t).document),e&&e.fn&&e.fn.jquery&&(P=e,n=!0),n},w.versionCheck=w.fnVersionCheck=function(t){for(var e,n,a=w.version.split("."),r=t.split("."),o=0,i=r.length;o<i;o++)if((e=parseInt(a[o],10)||0)!==(n=parseInt(r[o],10)||0))return n<e;return!0},w.isDataTable=w.fnIsDataTable=function(t){var r=P(t).get(0),o=!1;return t instanceof w.Api||(P.each(w.settings,function(t,e){var n=e.nScrollHead?P("table",e.nScrollHead)[0]:null,a=e.nScrollFoot?P("table",e.nScrollFoot)[0]:null;e.nTable!==r&&n!==r&&a!==r||(o=!0)}),o)},w.tables=w.fnTables=function(e){var t=!1,n=(P.isPlainObject(e)&&(t=e.api,e=e.visible),P.map(w.settings,function(t){if(!e||P(t.nTable).is(":visible"))return t.nTable}));return t?new B(n):n},w.camelToHungarian=C,e("$()",function(t,e){e=this.rows(e).nodes(),e=P(e);return P([].concat(e.filter(t).toArray(),e.find(t).toArray()))}),P.each(["on","one","off"],function(t,n){e(n+"()",function(){var t=Array.prototype.slice.call(arguments),e=(t[0]=P.map(t[0].split(/\s/),function(t){return t.match(/\.dt\b/)?t:t+".dt"}).join(" "),P(this.tables().nodes()));return e[n].apply(e,t),this})}),e("clear()",function(){return this.iterator("table",function(t){pt(t)})}),e("settings()",function(){return new B(this.context,this.context)}),e("init()",function(){var t=this.context;return t.length?t[0].oInit:null}),e("data()",function(){return this.iterator("table",function(t){return H(t.aoData,"_aData")}).flatten()}),e("destroy()",function(c){return c=c||!1,this.iterator("table",function(e){var n,t=e.oClasses,a=e.nTable,r=e.nTBody,o=e.nTHead,i=e.nTFoot,l=P(a),r=P(r),s=P(e.nTableWrapper),u=P.map(e.aoData,function(t){return t.nTr}),i=(e.bDestroying=!0,R(e,"aoDestroyCallback","destroy",[e]),c||new B(e).columns().visible(!0),s.off(".DT").find(":not(tbody *)").off(".DT"),P(j).off(".DT-"+e.sInstance),a!=o.parentNode&&(l.children("thead").detach(),l.append(o)),i&&a!=i.parentNode&&(l.children("tfoot").detach(),l.append(i)),e.aaSorting=[],e.aaSortingFixed=[],ce(e),P(u).removeClass(e.asStripeClasses.join(" ")),P("th, td",o).removeClass(t.sSortable+" "+t.sSortableAsc+" "+t.sSortableDesc+" "+t.sSortableNone),r.children().detach(),r.append(u),e.nTableWrapper.parentNode),o=c?"remove":"detach",u=(l[o](),s[o](),!c&&i&&(i.insertBefore(a,e.nTableReinsertBefore),l.css("width",e.sDestroyWidth).removeClass(t.sTable),n=e.asDestroyStripes.length)&&r.children().each(function(t){P(this).addClass(e.asDestroyStripes[t%n])}),P.inArray(e,w.settings));-1!==u&&w.settings.splice(u,1)})}),P.each(["column","row","cell"],function(t,s){e(s+"s().every()",function(o){var i=this.selector.opts,l=this;return this.iterator(s,function(t,e,n,a,r){o.call(l[s](e,"cell"===s?n:i,"cell"===s?i:N),e,n,a,r)})})}),e("i18n()",function(t,e,n){var a=this.context[0],t=A(t)(a.oLanguage);return t===N&&(t=e),(t=n!==N&&P.isPlainObject(t)?t[n]!==N?t[n]:t._:t).replace("%d",n)}),w.version="1.13.4",w.settings=[],w.models={},w.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0,return:!1},w.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1},w.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null},w.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(t){try{return JSON.parse((-1===t.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+t.sInstance+"_"+location.pathname))}catch(t){return{}}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(t,e){try{(-1===t.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+t.sInstance+"_"+location.pathname,JSON.stringify(e))}catch(t){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:P.extend({},w.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"},i(w.defaults),w.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null},i(w.defaults.column),w.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,jqXHR:null,json:N,oAjaxData:N,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==E(this)?+this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==E(this)?+this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var t=this._iDisplayLength,e=this._iDisplayStart,n=e+t,a=this.aiDisplay.length,r=this.oFeatures,o=r.bPaginate;return r.bServerSide?!1===o||-1===t?e+a:Math.min(e+t,this._iRecordsDisplay):!o||a<n||-1===t?a:n},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null},w.ext=p={buttons:{},classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:w.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:w.version},P.extend(p,{afnFiltering:p.search,aTypes:p.type.detect,ofnSearch:p.type.search,oSort:p.type.order,afnSortData:p.order,aoFeatures:p.feature,oApi:p.internal,oStdClasses:p.classes,oPagination:p.pager}),P.extend(w.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_desc_disabled",sSortableDesc:"sorting_asc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""}),w.ext.pager);function Oe(t,e){var n=[],a=He.numbers_length,r=Math.floor(a/2);return e<=a?n=f(0,e):t<=r?((n=f(0,a-2)).push("ellipsis"),n.push(e-1)):((e-1-r<=t?n=f(e-(a-2),e):((n=f(t-r+2,t+r-1)).push("ellipsis"),n.push(e-1),n)).splice(0,0,"ellipsis"),n.splice(0,0,0)),n.DT_el="span",n}P.extend(He,{simple:function(t,e){return["previous","next"]},full:function(t,e){return["first","previous","next","last"]},numbers:function(t,e){return[Oe(t,e)]},simple_numbers:function(t,e){return["previous",Oe(t,e),"next"]},full_numbers:function(t,e){return["first","previous",Oe(t,e),"next","last"]},first_last_numbers:function(t,e){return["first",Oe(t,e),"last"]},_numbers:Oe,numbers_length:7}),P.extend(!0,w.ext.renderer,{pageButton:{_:function(c,t,f,e,d,h){function p(t,e){for(var n,a,r,o=m.sPageButtonDisabled,i=function(t){Yt(c,t.data.action,!0)},l=0,s=e.length;l<s;l++)if(n=e[l],Array.isArray(n)){var u=P("<"+(n.DT_el||"div")+"/>").appendTo(t);p(u,n)}else{switch(g=null,b=n,a=c.iTabIndex,n){case"ellipsis":t.append('<span class="ellipsis">&#x2026;</span>');break;case"first":g=S.sFirst,0===d&&(a=-1,b+=" "+o);break;case"previous":g=S.sPrevious,0===d&&(a=-1,b+=" "+o);break;case"next":g=S.sNext,0!==h&&d!==h-1||(a=-1,b+=" "+o);break;case"last":g=S.sLast,0!==h&&d!==h-1||(a=-1,b+=" "+o);break;default:g=c.fnFormatNumber(n+1),b=d===n?m.sPageButtonActive:""}null!==g&&(u=c.oInit.pagingTag||"a",r=-1!==b.indexOf(o),me(P("<"+u+">",{class:m.sPageButton+" "+b,"aria-controls":c.sTableId,"aria-disabled":r?"true":null,"aria-label":v[n],"aria-role":"link","aria-current":b===m.sPageButtonActive?"page":null,"data-dt-idx":n,tabindex:a,id:0===f&&"string"==typeof n?c.sTableId+"_"+n:null}).html(g).appendTo(t),{action:n},i))}}var g,b,n,m=c.oClasses,S=c.oLanguage.oPaginate,v=c.oLanguage.oAria.paginate||{};try{n=P(t).find(y.activeElement).data("dt-idx")}catch(t){}p(P(t).empty(),e),n!==N&&P(t).find("[data-dt-idx="+n+"]").trigger("focus")}}}),P.extend(w.ext.type.detect,[function(t,e){e=e.oLanguage.sDecimal;return l(t,e)?"num"+e:null},function(t,e){var n;return(!t||t instanceof Date||X.test(t))&&(null!==(n=Date.parse(t))&&!isNaN(n)||h(t))?"date":null},function(t,e){e=e.oLanguage.sDecimal;return l(t,e,!0)?"num-fmt"+e:null},function(t,e){e=e.oLanguage.sDecimal;return a(t,e)?"html-num"+e:null},function(t,e){e=e.oLanguage.sDecimal;return a(t,e,!0)?"html-num-fmt"+e:null},function(t,e){return h(t)||"string"==typeof t&&-1!==t.indexOf("<")?"html":null}]),P.extend(w.ext.type.search,{html:function(t){return h(t)?t:"string"==typeof t?t.replace(U," ").replace(V,""):""},string:function(t){return!h(t)&&"string"==typeof t?t.replace(U," "):t}});function ke(t,e,n,a){var r;return 0===t||t&&"-"!==t?"number"==(r=typeof t)||"bigint"==r?t:+(t=(t=e?G(t,e):t).replace&&(n&&(t=t.replace(n,"")),a)?t.replace(a,""):t):-1/0}function Me(n){P.each({num:function(t){return ke(t,n)},"num-fmt":function(t){return ke(t,n,q)},"html-num":function(t){return ke(t,n,V)},"html-num-fmt":function(t){return ke(t,n,V,q)}},function(t,e){p.type.order[t+n+"-pre"]=e,t.match(/^html\-/)&&(p.type.search[t+n]=p.type.search.html)})}P.extend(p.type.order,{"date-pre":function(t){t=Date.parse(t);return isNaN(t)?-1/0:t},"html-pre":function(t){return h(t)?"":t.replace?t.replace(/<.*?>/g,"").toLowerCase():t+""},"string-pre":function(t){return h(t)?"":"string"==typeof t?t.toLowerCase():t.toString?t.toString():""},"string-asc":function(t,e){return t<e?-1:e<t?1:0},"string-desc":function(t,e){return t<e?1:e<t?-1:0}}),Me(""),P.extend(!0,w.ext.renderer,{header:{_:function(r,o,i,l){P(r.nTable).on("order.dt.DT",function(t,e,n,a){r===e&&(e=i.idx,o.removeClass(l.sSortAsc+" "+l.sSortDesc).addClass("asc"==a[e]?l.sSortAsc:"desc"==a[e]?l.sSortDesc:i.sSortingClass))})},jqueryui:function(r,o,i,l){P("<div/>").addClass(l.sSortJUIWrapper).append(o.contents()).append(P("<span/>").addClass(l.sSortIcon+" "+i.sSortingClassJUI)).appendTo(o),P(r.nTable).on("order.dt.DT",function(t,e,n,a){r===e&&(e=i.idx,o.removeClass(l.sSortAsc+" "+l.sSortDesc).addClass("asc"==a[e]?l.sSortAsc:"desc"==a[e]?l.sSortDesc:i.sSortingClass),o.find("span."+l.sSortIcon).removeClass(l.sSortJUIAsc+" "+l.sSortJUIDesc+" "+l.sSortJUI+" "+l.sSortJUIAscAllowed+" "+l.sSortJUIDescAllowed).addClass("asc"==a[e]?l.sSortJUIAsc:"desc"==a[e]?l.sSortJUIDesc:i.sSortingClassJUI))})}}});function We(t){return"string"==typeof(t=Array.isArray(t)?t.join(","):t)?t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):t}function Ee(t,e,n,a,r){return j.moment?t[e](r):j.luxon?t[n](r):a?t[a](r):t}var Be=!1;function Ue(t,e,n){var a;if(j.moment){if(!(a=j.moment.utc(t,e,n,!0)).isValid())return null}else if(j.luxon){if(!(a=e&&"string"==typeof t?j.luxon.DateTime.fromFormat(t,e):j.luxon.DateTime.fromISO(t)).isValid)return null;a.setLocale(n)}else e?(Be||alert("DataTables warning: Formatted date without Moment.js or Luxon - https://datatables.net/tn/17"),Be=!0):a=new Date(t);return a}function Ve(s){return function(a,r,o,i){0===arguments.length?(o="en",a=r=null):1===arguments.length?(o="en",r=a,a=null):2===arguments.length&&(o=r,r=a,a=null);var l="datetime-"+r;return w.ext.type.order[l]||(w.ext.type.detect.unshift(function(t){return t===l&&l}),w.ext.type.order[l+"-asc"]=function(t,e){t=t.valueOf(),e=e.valueOf();return t===e?0:t<e?-1:1},w.ext.type.order[l+"-desc"]=function(t,e){t=t.valueOf(),e=e.valueOf();return t===e?0:e<t?-1:1}),function(t,e){var n;return null!==t&&t!==N||(t="--now"===i?(n=new Date,new Date(Date.UTC(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours(),n.getMinutes(),n.getSeconds()))):""),"type"===e?l:""===t?"sort"!==e?"":Ue("0000-01-01 00:00:00",null,o):!(null===r||a!==r||"sort"===e||"type"===e||t instanceof Date)||null===(n=Ue(t,a,o))?t:"sort"===e?n:(t=null===r?Ee(n,"toDate","toJSDate","")[s]():Ee(n,"format","toFormat","toISOString",r),"display"===e?We(t):t)}}}var Xe=",",Je=".";if(Intl)try{for(var qe=(new Intl.NumberFormat).formatToParts(100000.1),n=0;n<qe.length;n++)"group"===qe[n].type?Xe=qe[n].value:"decimal"===qe[n].type&&(Je=qe[n].value)}catch(t){}function Ge(e){return function(){var t=[ge(this[w.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return w.ext.internal[e].apply(this,t)}}return w.datetime=function(n,a){var r="datetime-detect-"+n;a=a||"en",w.ext.type.order[r]||(w.ext.type.detect.unshift(function(t){var e=Ue(t,n,a);return!(""!==t&&!e)&&r}),w.ext.type.order[r+"-pre"]=function(t){return Ue(t,n,a)||0})},w.render={date:Ve("toLocaleDateString"),datetime:Ve("toLocaleString"),time:Ve("toLocaleTimeString"),number:function(a,r,o,i,l){return null!==a&&a!==N||(a=Xe),null!==r&&r!==N||(r=Je),{display:function(t){if("number"!=typeof t&&"string"!=typeof t)return t;if(""===t||null===t)return t;var e=t<0?"-":"",n=parseFloat(t);if(isNaN(n))return We(t);n=n.toFixed(o),t=Math.abs(n);n=parseInt(t,10),t=o?r+(t-n).toFixed(o).substring(2):"";return(e=0===n&&0===parseFloat(t)?"":e)+(i||"")+n.toString().replace(/\B(?=(\d{3})+(?!\d))/g,a)+t+(l||"")}}},text:function(){return{display:We,filter:We}}},P.extend(w.ext.internal,{_fnExternApiFunc:Ge,_fnBuildAjax:Tt,_fnAjaxUpdate:xt,_fnAjaxParameters:At,_fnAjaxUpdateDraw:It,_fnAjaxDataSrc:Ft,_fnAddColumn:nt,_fnColumnOptions:at,_fnAdjustColumnSizing:O,_fnVisibleToColumnIndex:rt,_fnColumnIndexToVisible:ot,_fnVisbleColumns:T,_fnGetColumns:it,_fnColumnTypes:lt,_fnApplyColumnDefs:st,_fnHungarianMap:i,_fnCamelToHungarian:C,_fnLanguageCompat:Z,_fnBrowserDetect:tt,_fnAddData:x,_fnAddTr:ut,_fnNodeToDataIndex:function(t,e){return e._DT_RowIndex!==N?e._DT_RowIndex:null},_fnNodeToColumnIndex:function(t,e,n){return P.inArray(n,t.aoData[e].anCells)},_fnGetCellData:S,_fnSetCellData:ct,_fnSplitObjNotation:dt,_fnGetObjectDataFn:A,_fnSetObjectDataFn:b,_fnGetDataMaster:ht,_fnClearTable:pt,_fnDeleteIndex:gt,_fnInvalidate:bt,_fnGetRowElements:mt,_fnCreateTr:St,_fnBuildHead:yt,_fnDrawHead:Dt,_fnDraw:v,_fnReDraw:u,_fnAddOptionsHtml:_t,_fnDetectHeader:wt,_fnGetUniqueThs:Ct,_fnFeatureHtmlFilter:Lt,_fnFilterComplete:Rt,_fnFilterCustom:Pt,_fnFilterColumn:jt,_fnFilter:Nt,_fnFilterCreateSearch:Ht,_fnEscapeRegex:Ot,_fnFilterData:Wt,_fnFeatureHtmlInfo:Ut,_fnUpdateInfo:Vt,_fnInfoMacros:Xt,_fnInitialise:Jt,_fnInitComplete:qt,_fnLengthChange:Gt,_fnFeatureHtmlLength:$t,_fnFeatureHtmlPaginate:zt,_fnPageChange:Yt,_fnFeatureHtmlProcessing:Zt,_fnProcessingDisplay:D,_fnFeatureHtmlTable:Kt,_fnScrollDraw:Qt,_fnApplyToChildren:k,_fnCalculateColumnWidths:ee,_fnThrottle:ne,_fnConvertToWidth:ae,_fnGetWidestNode:re,_fnGetMaxLenString:oe,_fnStringToCss:M,_fnSortFlatten:I,_fnSort:ie,_fnSortAria:le,_fnSortListener:se,_fnSortAttachListener:ue,_fnSortingClasses:ce,_fnSortData:fe,_fnSaveState:de,_fnLoadState:he,_fnImplementState:pe,_fnSettingsFromNode:ge,_fnLog:W,_fnMap:F,_fnBindAction:me,_fnCallbackReg:L,_fnCallbackFire:R,_fnLengthOverflow:Se,_fnRenderer:ve,_fnDataSource:E,_fnRowAttributes:vt,_fnExtend:be,_fnCalculateEnd:function(){}}),((P.fn.dataTable=w).$=P).fn.dataTableSettings=w.settings,P.fn.dataTableExt=w.ext,P.fn.DataTable=function(t){return P(this).dataTable(t).api()},P.each(w,function(t,e){P.fn.DataTable[t]=e}),w});
\ No newline at end of file
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 1d6f8559d..23963a6e1 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -21,7 +21,7 @@
     <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
     {{-- <link rel="stylesheet" href="{{asset('css/adminlte.min.css')}}"> --}}
-    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.css" />
+    href="{{ asset('plugins/datatables/jquery.dataTables.min.css') }}">
 
     {{-- summernote --}}
     <link rel="stylesheet" href="{{ asset('plugins/summernote/summernote-bs4.min.css') }}">
@@ -474,7 +474,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
     <!-- Scripts -->
     <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10.14.1/dist/sweetalert2.all.min.js"></script>
 
-    <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script>
+    <script src="{{ asset('plugins/datatables/jquery.dataTables.min.js') }}"></script>
     <!-- Summernote -->
     <script src="{{ asset('plugins/summernote/summernote-bs4.min.js') }}"></script>
     <!-- select2 -->

From c8ce65c8e39438b3a569d3659d2c4e102874b16b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sat, 29 Apr 2023 23:35:31 +0200
Subject: [PATCH 097/514] Create v1.13.4

---
 public/plugins/datatables/v1.13.4 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 public/plugins/datatables/v1.13.4

diff --git a/public/plugins/datatables/v1.13.4 b/public/plugins/datatables/v1.13.4
new file mode 100644
index 000000000..e69de29bb

From 4f42c23a4ef62eb90bc1388590c676154b99cfdd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sat, 29 Apr 2023 23:38:20 +0200
Subject: [PATCH 098/514] update alpine to local

---
 public/plugins/alpinejs/3.12.0_cdn.min.js   | 5 +++++
 themes/default/views/layouts/main.blade.php | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)
 create mode 100644 public/plugins/alpinejs/3.12.0_cdn.min.js

diff --git a/public/plugins/alpinejs/3.12.0_cdn.min.js b/public/plugins/alpinejs/3.12.0_cdn.min.js
new file mode 100644
index 000000000..d806d3234
--- /dev/null
+++ b/public/plugins/alpinejs/3.12.0_cdn.min.js
@@ -0,0 +1,5 @@
+(()=>{var Ye=!1,Ze=!1,V=[],Qe=-1;function Bt(e){hn(e)}function hn(e){V.includes(e)||V.push(e),_n()}function ye(e){let t=V.indexOf(e);t!==-1&&t>Qe&&V.splice(t,1)}function _n(){!Ze&&!Ye&&(Ye=!0,queueMicrotask(gn))}function gn(){Ye=!1,Ze=!0;for(let e=0;e<V.length;e++)V[e](),Qe=e;V.length=0,Qe=-1,Ze=!1}var C,P,L,et,Xe=!0;function Kt(e){Xe=!1,e(),Xe=!0}function zt(e){C=e.reactive,L=e.release,P=t=>e.effect(t,{scheduler:r=>{Xe?Bt(r):r()}}),et=e.raw}function tt(e){P=e}function Vt(e){let t=()=>{};return[n=>{let i=P(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),L(i))},i},()=>{t()}]}var Ht=[],qt=[],Ut=[];function Wt(e){Ut.push(e)}function we(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,qt.push(t))}function Gt(e){Ht.push(e)}function Jt(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function nt(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var it=new MutationObserver(ct),ot=!1;function se(){it.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ot=!0}function st(){xn(),it.disconnect(),ot=!1}var oe=[],rt=!1;function xn(){oe=oe.concat(it.takeRecords()),oe.length&&!rt&&(rt=!0,queueMicrotask(()=>{yn(),rt=!1}))}function yn(){ct(oe),oe.length=0}function h(e){if(!ot)return e();st();let t=e();return se(),t}var at=!1,be=[];function Yt(){at=!0}function Zt(){at=!1,ct(be),be=[]}function ct(e){if(at){be=be.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;o<e.length;o++)if(!e[o].target._x_ignoreMutationObserver&&(e[o].type==="childList"&&(e[o].addedNodes.forEach(s=>s.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{nt(s,o)}),n.forEach((o,s)=>{Ht.forEach(a=>a(s,o))});for(let o of r)if(!t.includes(o)&&(qt.forEach(s=>s(o)),o._x_cleanups))for(;o._x_cleanups.length;)o._x_cleanups.pop()();t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.includes(o)||o.isConnected&&(delete o._x_ignoreSelf,delete o._x_ignore,Ut.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function Ee(e){return j($(e))}function R(e,t,r){return e._x_dataStack=[t,...$(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function lt(e,t){let r=e._x_dataStack[0];Object.entries(t).forEach(([n,i])=>{r[n]=i})}function $(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?$(e.host):e.parentNode?$(e.parentNode):[]}function j(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function ve(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Se(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>bn(n,i),s=>ut(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function bn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ut(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ut(e[t[0]],t.slice(1),r)}}var Qt={};function y(e,t){Qt[e]=t}function ae(e,t){return Object.entries(Qt).forEach(([r,n])=>{Object.defineProperty(e,`$${r}`,{get(){let[i,o]=ft(t);return i={interceptor:Se,...i},we(t,o),n(t,i)},enumerable:!1})}),e}function Xt(e,t,r,...n){try{return r(...n)}catch(i){Z(i,e,t)}}function Z(e,t,r=void 0){Object.assign(e,{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message}
+
+${r?'Expression: "'+r+`"
+
+`:""}`,t),setTimeout(()=>{throw e},0)}var Ae=!0;function er(e){let t=Ae;Ae=!1,e(),Ae=t}function I(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return tr(...e)}var tr=pt;function rr(e){tr=e}function pt(e,t){let r={};ae(r,e);let n=[r,...$(e)],i=typeof t=="function"?wn(n,t):vn(n,t,e);return Xt.bind(null,e,t,i)}function wn(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(j([n,...e]),i);Oe(r,o)}}var dt={};function En(e,t){if(dt[e])return dt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(async()=>{ ${e} })()`:e,o=(()=>{try{return new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`)}catch(s){return Z(s,t,e),Promise.resolve()}})();return dt[e]=o,o}function vn(e,t,r){let n=En(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=j([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>Z(l,r,t));n.finished?(Oe(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Oe(i,l,a,s,r)}).catch(l=>Z(l,r,t)).finally(()=>n.result=void 0)}}}function Oe(e,t,r,n,i){if(Ae&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Oe(e,s,r,n)).catch(s=>Z(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var gt="x-";function S(e=""){return gt+e}function nr(e){gt=e}var mt={};function p(e,t){return mt[e]=t,{before(r){if(!mt[r]){console.warn("Cannot find directive `${directive}`. `${name}` will use the default order of execution");return}let n=H.indexOf(r);H.splice(n>=0?n:H.indexOf("DEFAULT"),0,e)}}}function le(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=xt(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(sr((o,s)=>n[o]=s)).filter(cr).map(An(n,r)).sort(On).map(o=>Sn(e,o))}function xt(e){return Array.from(e).map(sr()).filter(t=>!cr(t))}var ht=!1,ce=new Map,ir=Symbol();function or(e){ht=!0;let t=Symbol();ir=t,ce.set(t,[]);let r=()=>{for(;ce.get(t).length;)ce.get(t).shift()();ce.delete(t)},n=()=>{ht=!1,r()};e(r),n()}function ft(e){let t=[],r=a=>t.push(a),[n,i]=Vt(e);return t.push(i),[{Alpine:F,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:I.bind(I,e)},()=>t.forEach(a=>a())]}function Sn(e,t){let r=()=>{},n=mt[t.type]||r,[i,o]=ft(e);Jt(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),ht?ce.get(ir).push(n):n())};return s.runCleanups=o,s}var Ce=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Te=e=>e;function sr(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=ar.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var ar=[];function Q(e){ar.push(e)}function cr({name:e}){return lr().test(e)}var lr=()=>new RegExp(`^${gt}([^:^.]+)\\b`);function An(e,t){return({name:r,value:n})=>{let i=r.match(lr()),o=r.match(/:([a-zA-Z0-9\-:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var _t="DEFAULT",H=["ignore","ref","data","id","bind","init","for","model","modelable","transition","show","if",_t,"teleport"];function On(e,t){let r=H.indexOf(e.type)===-1?_t:e.type,n=H.indexOf(t.type)===-1?_t:t.type;return H.indexOf(r)-H.indexOf(n)}function q(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function A(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>A(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)A(n,t,!1),n=n.nextElementSibling}function T(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}function ur(){document.body||T("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?"),q(document,"alpine:init"),q(document,"alpine:initializing"),se(),Wt(t=>v(t,A)),we(t=>bt(t)),Gt((t,r)=>{le(t,r).forEach(n=>n())});let e=t=>!U(t.parentElement,!0);Array.from(document.querySelectorAll(pr())).filter(e).forEach(t=>{v(t)}),q(document,"alpine:initialized")}var yt=[],fr=[];function dr(){return yt.map(e=>e())}function pr(){return yt.concat(fr).map(e=>e())}function Me(e){yt.push(e)}function Re(e){fr.push(e)}function U(e,t=!1){return X(e,r=>{if((t?pr():dr()).some(i=>r.matches(i)))return!0})}function X(e,t){if(e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),!!e.parentElement)return X(e.parentElement,t)}}function mr(e){return dr().some(t=>e.matches(t))}var hr=[];function _r(e){hr.push(e)}function v(e,t=A,r=()=>{}){or(()=>{t(e,(n,i)=>{r(n,i),hr.forEach(o=>o(n,i)),le(n,n.attributes).forEach(o=>o()),n._x_ignore&&i()})})}function bt(e){A(e,t=>nt(t))}var wt=[],Et=!1;function ee(e=()=>{}){return queueMicrotask(()=>{Et||setTimeout(()=>{Ne()})}),new Promise(t=>{wt.push(()=>{e(),t()})})}function Ne(){for(Et=!1;wt.length;)wt.shift()()}function gr(){Et=!0}function ue(e,t){return Array.isArray(t)?xr(e,t.join(" ")):typeof t=="object"&&t!==null?Cn(e,t):typeof t=="function"?ue(e,t()):xr(e,t)}function xr(e,t){let r=o=>o.split(" ").filter(Boolean),n=o=>o.split(" ").filter(s=>!e.classList.contains(s)).filter(Boolean),i=o=>(e.classList.add(...o),()=>{e.classList.remove(...o)});return t=t===!0?t="":t||"",i(n(t))}function Cn(e,t){let r=a=>a.split(" ").filter(Boolean),n=Object.entries(t).flatMap(([a,c])=>c?r(a):!1).filter(Boolean),i=Object.entries(t).flatMap(([a,c])=>c?!1:r(a)).filter(Boolean),o=[],s=[];return i.forEach(a=>{e.classList.contains(a)&&(e.classList.remove(a),s.push(a))}),n.forEach(a=>{e.classList.contains(a)||(e.classList.add(a),o.push(a))}),()=>{s.forEach(a=>e.classList.add(a)),o.forEach(a=>e.classList.remove(a))}}function W(e,t){return typeof t=="object"&&t!==null?Tn(e,t):Mn(e,t)}function Tn(e,t){let r={};return Object.entries(t).forEach(([n,i])=>{r[n]=e.style[n],n.startsWith("--")||(n=Rn(n)),e.style.setProperty(n,i)}),setTimeout(()=>{e.style.length===0&&e.removeAttribute("style")}),()=>{W(e,r)}}function Mn(e,t){let r=e.getAttribute("style",t);return e.setAttribute("style",t),()=>{e.setAttribute("style",r||"")}}function Rn(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function fe(e,t=()=>{}){let r=!1;return function(){r?t.apply(this,arguments):(r=!0,e.apply(this,arguments))}}p("transition",(e,{value:t,modifiers:r,expression:n},{evaluate:i})=>{typeof n=="function"&&(n=i(n)),n?Nn(e,n,t):Dn(e,r,t)});function Nn(e,t,r){yr(e,ue,""),{enter:i=>{e._x_transition.enter.during=i},"enter-start":i=>{e._x_transition.enter.start=i},"enter-end":i=>{e._x_transition.enter.end=i},leave:i=>{e._x_transition.leave.during=i},"leave-start":i=>{e._x_transition.leave.start=i},"leave-end":i=>{e._x_transition.leave.end=i}}[r](t)}function Dn(e,t,r){yr(e,W);let n=!t.includes("in")&&!t.includes("out")&&!r,i=n||t.includes("in")||["enter"].includes(r),o=n||t.includes("out")||["leave"].includes(r);t.includes("in")&&!n&&(t=t.filter((_,b)=>b<t.indexOf("out"))),t.includes("out")&&!n&&(t=t.filter((_,b)=>b>t.indexOf("out")));let s=!t.includes("opacity")&&!t.includes("scale"),a=s||t.includes("opacity"),c=s||t.includes("scale"),l=a?0:1,u=c?de(t,"scale",95)/100:1,d=de(t,"delay",0),m=de(t,"origin","center"),w="opacity, transform",k=de(t,"duration",150)/1e3,ge=de(t,"duration",75)/1e3,f="cubic-bezier(0.4, 0.0, 0.2, 1)";i&&(e._x_transition.enter.during={transformOrigin:m,transitionDelay:d,transitionProperty:w,transitionDuration:`${k}s`,transitionTimingFunction:f},e._x_transition.enter.start={opacity:l,transform:`scale(${u})`},e._x_transition.enter.end={opacity:1,transform:"scale(1)"}),o&&(e._x_transition.leave.during={transformOrigin:m,transitionDelay:d,transitionProperty:w,transitionDuration:`${ge}s`,transitionTimingFunction:f},e._x_transition.leave.start={opacity:1,transform:"scale(1)"},e._x_transition.leave.end={opacity:l,transform:`scale(${u})`})}function yr(e,t,r={}){e._x_transition||(e._x_transition={enter:{during:r,start:r,end:r},leave:{during:r,start:r,end:r},in(n=()=>{},i=()=>{}){De(e,t,{during:this.enter.during,start:this.enter.start,end:this.enter.end},n,i)},out(n=()=>{},i=()=>{}){De(e,t,{during:this.leave.during,start:this.leave.start,end:this.leave.end},n,i)}})}window.Element.prototype._x_toggleAndCascadeWithTransitions=function(e,t,r,n){let i=document.visibilityState==="visible"?requestAnimationFrame:setTimeout,o=()=>i(r);if(t){e._x_transition&&(e._x_transition.enter||e._x_transition.leave)?e._x_transition.enter&&(Object.entries(e._x_transition.enter.during).length||Object.entries(e._x_transition.enter.start).length||Object.entries(e._x_transition.enter.end).length)?e._x_transition.in(r):o():e._x_transition?e._x_transition.in(r):o();return}e._x_hidePromise=e._x_transition?new Promise((s,a)=>{e._x_transition.out(()=>{},()=>s(n)),e._x_transitioning.beforeCancel(()=>a({isFromCancelledTransition:!0}))}):Promise.resolve(n),queueMicrotask(()=>{let s=br(e);s?(s._x_hideChildren||(s._x_hideChildren=[]),s._x_hideChildren.push(e)):i(()=>{let a=c=>{let l=Promise.all([c._x_hidePromise,...(c._x_hideChildren||[]).map(a)]).then(([u])=>u());return delete c._x_hidePromise,delete c._x_hideChildren,l};a(e).catch(c=>{if(!c.isFromCancelledTransition)throw c})})})};function br(e){let t=e.parentNode;if(t)return t._x_hidePromise?t:br(t)}function De(e,t,{during:r,start:n,end:i}={},o=()=>{},s=()=>{}){if(e._x_transitioning&&e._x_transitioning.cancel(),Object.keys(r).length===0&&Object.keys(n).length===0&&Object.keys(i).length===0){o(),s();return}let a,c,l;Pn(e,{start(){a=t(e,n)},during(){c=t(e,r)},before:o,end(){a(),l=t(e,i)},after:s,cleanup(){c(),l()}})}function Pn(e,t){let r,n,i,o=fe(()=>{h(()=>{r=!0,n||t.before(),i||(t.end(),Ne()),t.after(),e.isConnected&&t.cleanup(),delete e._x_transitioning})});e._x_transitioning={beforeCancels:[],beforeCancel(s){this.beforeCancels.push(s)},cancel:fe(function(){for(;this.beforeCancels.length;)this.beforeCancels.shift()();o()}),finish:o},h(()=>{t.start(),t.during()}),gr(),requestAnimationFrame(()=>{if(r)return;let s=Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s",""))*1e3,a=Number(getComputedStyle(e).transitionDelay.replace(/,.*/,"").replace("s",""))*1e3;s===0&&(s=Number(getComputedStyle(e).animationDuration.replace("s",""))*1e3),h(()=>{t.before()}),n=!0,requestAnimationFrame(()=>{r||(h(()=>{t.end()}),Ne(),setTimeout(e._x_transitioning.finish,s+a),i=!0)})})}function de(e,t,r){if(e.indexOf(t)===-1)return r;let n=e[e.indexOf(t)+1];if(!n||t==="scale"&&isNaN(n))return r;if(t==="duration"){let i=n.match(/([0-9]+)ms/);if(i)return i[1]}return t==="origin"&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[n,e[e.indexOf(t)+2]].join(" "):n}var te=!1;function N(e,t=()=>{}){return(...r)=>te?t(...r):e(...r)}function wr(e){return(...t)=>te&&e(...t)}function Er(e,t){t._x_dataStack||(t._x_dataStack=e._x_dataStack),te=!0,kn(()=>{In(t)}),te=!1}function In(e){let t=!1;v(e,(n,i)=>{A(n,(o,s)=>{if(t&&mr(o))return s();t=!0,i(o,s)})})}function kn(e){let t=P;tt((r,n)=>{let i=t(r);return L(i),()=>{}}),e(),tt(t)}function pe(e,t,r,n=[]){switch(e._x_bindings||(e._x_bindings=C({})),e._x_bindings[t]=r,t=n.includes("camel")?zn(t):t,t){case"value":Ln(e,r);break;case"style":jn(e,r);break;case"class":$n(e,r);break;default:Fn(e,t,r);break}}function Ln(e,t){if(e.type==="radio")e.attributes.value===void 0&&(e.value=t),window.fromModel&&(e.checked=vr(e.value,t));else if(e.type==="checkbox")Number.isInteger(t)?e.value=t:!Number.isInteger(t)&&!Array.isArray(t)&&typeof t!="boolean"&&![null,void 0].includes(t)?e.value=String(t):Array.isArray(t)?e.checked=t.some(r=>vr(r,e.value)):e.checked=!!t;else if(e.tagName==="SELECT")Kn(e,t);else{if(e.value===t)return;e.value=t}}function $n(e,t){e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedClasses=ue(e,t)}function jn(e,t){e._x_undoAddedStyles&&e._x_undoAddedStyles(),e._x_undoAddedStyles=W(e,t)}function Fn(e,t,r){[null,void 0,!1].includes(r)&&Vn(t)?e.removeAttribute(t):(Sr(t)&&(r=t),Bn(e,t,r))}function Bn(e,t,r){e.getAttribute(t)!=r&&e.setAttribute(t,r)}function Kn(e,t){let r=[].concat(t).map(n=>n+"");Array.from(e.options).forEach(n=>{n.selected=r.includes(n.value)})}function zn(e){return e.toLowerCase().replace(/-(\w)/g,(t,r)=>r.toUpperCase())}function vr(e,t){return e==t}function Sr(e){return["disabled","checked","required","readonly","hidden","open","selected","autofocus","itemscope","multiple","novalidate","allowfullscreen","allowpaymentrequest","formnovalidate","autoplay","controls","loop","muted","playsinline","default","ismap","reversed","async","defer","nomodule"].includes(e)}function Vn(e){return!["aria-pressed","aria-checked","aria-expanded","aria-selected"].includes(e)}function Ar(e,t,r){if(e._x_bindings&&e._x_bindings[t]!==void 0)return e._x_bindings[t];let n=e.getAttribute(t);return n===null?typeof r=="function"?r():r:n===""?!0:Sr(t)?!![t,"true"].includes(n):n}function Pe(e,t){var r;return function(){var n=this,i=arguments,o=function(){r=null,e.apply(n,i)};clearTimeout(r),r=setTimeout(o,t)}}function Ie(e,t){let r;return function(){let n=this,i=arguments;r||(e.apply(n,i),r=!0,setTimeout(()=>r=!1,t))}}function Or(e){e(F)}var G={},Cr=!1;function Tr(e,t){if(Cr||(G=C(G),Cr=!0),t===void 0)return G[e];G[e]=t,typeof t=="object"&&t!==null&&t.hasOwnProperty("init")&&typeof t.init=="function"&&G[e].init(),ve(G[e])}function Mr(){return G}var Rr={};function Nr(e,t){let r=typeof t!="function"?()=>t:t;e instanceof Element?vt(e,r()):Rr[e]=r}function Dr(e){return Object.entries(Rr).forEach(([t,r])=>{Object.defineProperty(e,t,{get(){return(...n)=>r(...n)}})}),e}function vt(e,t,r){let n=[];for(;n.length;)n.pop()();let i=Object.entries(t).map(([s,a])=>({name:s,value:a})),o=xt(i);i=i.map(s=>o.find(a=>a.name===s.name)?{name:`x-bind:${s.name}`,value:`"${s.value}"`}:s),le(e,i,r).map(s=>{n.push(s.runCleanups),s()})}var Pr={};function Ir(e,t){Pr[e]=t}function kr(e,t){return Object.entries(Pr).forEach(([r,n])=>{Object.defineProperty(e,r,{get(){return(...i)=>n.bind(t)(...i)},enumerable:!1})}),e}var Hn={get reactive(){return C},get release(){return L},get effect(){return P},get raw(){return et},version:"3.12.0",flushAndStopDeferringMutations:Zt,dontAutoEvaluateFunctions:er,disableEffectScheduling:Kt,startObservingMutations:se,stopObservingMutations:st,setReactivityEngine:zt,closestDataStack:$,skipDuringClone:N,onlyDuringClone:wr,addRootSelector:Me,addInitSelector:Re,addScopeToNode:R,deferMutations:Yt,mapAttributes:Q,evaluateLater:x,interceptInit:_r,setEvaluator:rr,mergeProxies:j,findClosest:X,closestRoot:U,destroyTree:bt,interceptor:Se,transition:De,setStyles:W,mutateDom:h,directive:p,throttle:Ie,debounce:Pe,evaluate:I,initTree:v,nextTick:ee,prefixed:S,prefix:nr,plugin:Or,magic:y,store:Tr,start:ur,clone:Er,bound:Ar,$data:Ee,walk:A,data:Ir,bind:Nr},F=Hn;function St(e,t){let r=Object.create(null),n=e.split(",");for(let i=0;i<n.length;i++)r[n[i]]=!0;return t?i=>!!r[i.toLowerCase()]:i=>!!r[i]}var qn="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly";var cs=St(qn+",async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected");var Lr=Object.freeze({}),ls=Object.freeze([]);var At=Object.assign;var Un=Object.prototype.hasOwnProperty,me=(e,t)=>Un.call(e,t),B=Array.isArray,re=e=>$r(e)==="[object Map]";var Wn=e=>typeof e=="string",ke=e=>typeof e=="symbol",he=e=>e!==null&&typeof e=="object";var Gn=Object.prototype.toString,$r=e=>Gn.call(e),Ot=e=>$r(e).slice(8,-1);var Le=e=>Wn(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e;var $e=e=>{let t=Object.create(null);return r=>t[r]||(t[r]=e(r))},Jn=/-(\w)/g,us=$e(e=>e.replace(Jn,(t,r)=>r?r.toUpperCase():"")),Yn=/\B([A-Z])/g,fs=$e(e=>e.replace(Yn,"-$1").toLowerCase()),Ct=$e(e=>e.charAt(0).toUpperCase()+e.slice(1)),ds=$e(e=>e?`on${Ct(e)}`:""),Tt=(e,t)=>e!==t&&(e===e||t===t);var Mt=new WeakMap,_e=[],D,J=Symbol("iterate"),Rt=Symbol("Map key iterate");function Zn(e){return e&&e._isEffect===!0}function jr(e,t=Lr){Zn(e)&&(e=e.raw);let r=Xn(e,t);return t.lazy||r(),r}function Fr(e){e.active&&(Br(e),e.options.onStop&&e.options.onStop(),e.active=!1)}var Qn=0;function Xn(e,t){let r=function(){if(!r.active)return e();if(!_e.includes(r)){Br(r);try{return ti(),_e.push(r),D=r,e()}finally{_e.pop(),Kr(),D=_e[_e.length-1]}}};return r.id=Qn++,r.allowRecurse=!!t.allowRecurse,r._isEffect=!0,r.active=!0,r.raw=e,r.deps=[],r.options=t,r}function Br(e){let{deps:t}=e;if(t.length){for(let r=0;r<t.length;r++)t[r].delete(e);t.length=0}}var ne=!0,Dt=[];function ei(){Dt.push(ne),ne=!1}function ti(){Dt.push(ne),ne=!0}function Kr(){let e=Dt.pop();ne=e===void 0?!0:e}function M(e,t,r){if(!ne||D===void 0)return;let n=Mt.get(e);n||Mt.set(e,n=new Map);let i=n.get(r);i||n.set(r,i=new Set),i.has(D)||(i.add(D),D.deps.push(i),D.options.onTrack&&D.options.onTrack({effect:D,target:e,type:t,key:r}))}function z(e,t,r,n,i,o){let s=Mt.get(e);if(!s)return;let a=new Set,c=u=>{u&&u.forEach(d=>{(d!==D||d.allowRecurse)&&a.add(d)})};if(t==="clear")s.forEach(c);else if(r==="length"&&B(e))s.forEach((u,d)=>{(d==="length"||d>=n)&&c(u)});else switch(r!==void 0&&c(s.get(r)),t){case"add":B(e)?Le(r)&&c(s.get("length")):(c(s.get(J)),re(e)&&c(s.get(Rt)));break;case"delete":B(e)||(c(s.get(J)),re(e)&&c(s.get(Rt)));break;case"set":re(e)&&c(s.get(J));break}let l=u=>{u.options.onTrigger&&u.options.onTrigger({effect:u,target:e,key:r,type:t,newValue:n,oldValue:i,oldTarget:o}),u.options.scheduler?u.options.scheduler(u):u()};a.forEach(l)}var ri=St("__proto__,__v_isRef,__isVue"),zr=new Set(Object.getOwnPropertyNames(Symbol).map(e=>Symbol[e]).filter(ke)),ni=Be(),ii=Be(!1,!0),oi=Be(!0),si=Be(!0,!0),Fe={};["includes","indexOf","lastIndexOf"].forEach(e=>{let t=Array.prototype[e];Fe[e]=function(...r){let n=g(this);for(let o=0,s=this.length;o<s;o++)M(n,"get",o+"");let i=t.apply(n,r);return i===-1||i===!1?t.apply(n,r.map(g)):i}});["push","pop","shift","unshift","splice"].forEach(e=>{let t=Array.prototype[e];Fe[e]=function(...r){ei();let n=t.apply(this,r);return Kr(),n}});function Be(e=!1,t=!1){return function(n,i,o){if(i==="__v_isReactive")return!e;if(i==="__v_isReadonly")return e;if(i==="__v_raw"&&o===(e?t?_i:rn:t?hi:tn).get(n))return n;let s=B(n);if(!e&&s&&me(Fe,i))return Reflect.get(Fe,i,o);let a=Reflect.get(n,i,o);return(ke(i)?zr.has(i):ri(i))||(e||M(n,"get",i),t)?a:Nt(a)?!s||!Le(i)?a.value:a:he(a)?e?nn(a):We(a):a}}var ai=Vr(),ci=Vr(!0);function Vr(e=!1){return function(r,n,i,o){let s=r[n];if(!e&&(i=g(i),s=g(s),!B(r)&&Nt(s)&&!Nt(i)))return s.value=i,!0;let a=B(r)&&Le(n)?Number(n)<r.length:me(r,n),c=Reflect.set(r,n,i,o);return r===g(o)&&(a?Tt(i,s)&&z(r,"set",n,i,s):z(r,"add",n,i)),c}}function li(e,t){let r=me(e,t),n=e[t],i=Reflect.deleteProperty(e,t);return i&&r&&z(e,"delete",t,void 0,n),i}function ui(e,t){let r=Reflect.has(e,t);return(!ke(t)||!zr.has(t))&&M(e,"has",t),r}function fi(e){return M(e,"iterate",B(e)?"length":J),Reflect.ownKeys(e)}var Hr={get:ni,set:ai,deleteProperty:li,has:ui,ownKeys:fi},qr={get:oi,set(e,t){return console.warn(`Set operation on key "${String(t)}" failed: target is readonly.`,e),!0},deleteProperty(e,t){return console.warn(`Delete operation on key "${String(t)}" failed: target is readonly.`,e),!0}},xs=At({},Hr,{get:ii,set:ci}),ys=At({},qr,{get:si}),Pt=e=>he(e)?We(e):e,It=e=>he(e)?nn(e):e,kt=e=>e,Ke=e=>Reflect.getPrototypeOf(e);function ze(e,t,r=!1,n=!1){e=e.__v_raw;let i=g(e),o=g(t);t!==o&&!r&&M(i,"get",t),!r&&M(i,"get",o);let{has:s}=Ke(i),a=n?kt:r?It:Pt;if(s.call(i,t))return a(e.get(t));if(s.call(i,o))return a(e.get(o));e!==i&&e.get(t)}function Ve(e,t=!1){let r=this.__v_raw,n=g(r),i=g(e);return e!==i&&!t&&M(n,"has",e),!t&&M(n,"has",i),e===i?r.has(e):r.has(e)||r.has(i)}function He(e,t=!1){return e=e.__v_raw,!t&&M(g(e),"iterate",J),Reflect.get(e,"size",e)}function Ur(e){e=g(e);let t=g(this);return Ke(t).has.call(t,e)||(t.add(e),z(t,"add",e,e)),this}function Wr(e,t){t=g(t);let r=g(this),{has:n,get:i}=Ke(r),o=n.call(r,e);o?en(r,n,e):(e=g(e),o=n.call(r,e));let s=i.call(r,e);return r.set(e,t),o?Tt(t,s)&&z(r,"set",e,t,s):z(r,"add",e,t),this}function Gr(e){let t=g(this),{has:r,get:n}=Ke(t),i=r.call(t,e);i?en(t,r,e):(e=g(e),i=r.call(t,e));let o=n?n.call(t,e):void 0,s=t.delete(e);return i&&z(t,"delete",e,void 0,o),s}function Jr(){let e=g(this),t=e.size!==0,r=re(e)?new Map(e):new Set(e),n=e.clear();return t&&z(e,"clear",void 0,void 0,r),n}function qe(e,t){return function(n,i){let o=this,s=o.__v_raw,a=g(s),c=t?kt:e?It:Pt;return!e&&M(a,"iterate",J),s.forEach((l,u)=>n.call(i,c(l),c(u),o))}}function je(e,t,r){return function(...n){let i=this.__v_raw,o=g(i),s=re(o),a=e==="entries"||e===Symbol.iterator&&s,c=e==="keys"&&s,l=i[e](...n),u=r?kt:t?It:Pt;return!t&&M(o,"iterate",c?Rt:J),{next(){let{value:d,done:m}=l.next();return m?{value:d,done:m}:{value:a?[u(d[0]),u(d[1])]:u(d),done:m}},[Symbol.iterator](){return this}}}}function K(e){return function(...t){{let r=t[0]?`on key "${t[0]}" `:"";console.warn(`${Ct(e)} operation ${r}failed: target is readonly.`,g(this))}return e==="delete"?!1:this}}var Yr={get(e){return ze(this,e)},get size(){return He(this)},has:Ve,add:Ur,set:Wr,delete:Gr,clear:Jr,forEach:qe(!1,!1)},Zr={get(e){return ze(this,e,!1,!0)},get size(){return He(this)},has:Ve,add:Ur,set:Wr,delete:Gr,clear:Jr,forEach:qe(!1,!0)},Qr={get(e){return ze(this,e,!0)},get size(){return He(this,!0)},has(e){return Ve.call(this,e,!0)},add:K("add"),set:K("set"),delete:K("delete"),clear:K("clear"),forEach:qe(!0,!1)},Xr={get(e){return ze(this,e,!0,!0)},get size(){return He(this,!0)},has(e){return Ve.call(this,e,!0)},add:K("add"),set:K("set"),delete:K("delete"),clear:K("clear"),forEach:qe(!0,!0)},di=["keys","values","entries",Symbol.iterator];di.forEach(e=>{Yr[e]=je(e,!1,!1),Qr[e]=je(e,!0,!1),Zr[e]=je(e,!1,!0),Xr[e]=je(e,!0,!0)});function Ue(e,t){let r=t?e?Xr:Zr:e?Qr:Yr;return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(me(r,i)&&i in n?r:n,i,o)}var pi={get:Ue(!1,!1)},bs={get:Ue(!1,!0)},mi={get:Ue(!0,!1)},ws={get:Ue(!0,!0)};function en(e,t,r){let n=g(r);if(n!==r&&t.call(e,n)){let i=Ot(e);console.warn(`Reactive ${i} contains both the raw and reactive versions of the same object${i==="Map"?" as keys":""}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`)}}var tn=new WeakMap,hi=new WeakMap,rn=new WeakMap,_i=new WeakMap;function gi(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function xi(e){return e.__v_skip||!Object.isExtensible(e)?0:gi(Ot(e))}function We(e){return e&&e.__v_isReadonly?e:on(e,!1,Hr,pi,tn)}function nn(e){return on(e,!0,qr,mi,rn)}function on(e,t,r,n,i){if(!he(e))return console.warn(`value cannot be made reactive: ${String(e)}`),e;if(e.__v_raw&&!(t&&e.__v_isReactive))return e;let o=i.get(e);if(o)return o;let s=xi(e);if(s===0)return e;let a=new Proxy(e,s===2?n:r);return i.set(e,a),a}function g(e){return e&&g(e.__v_raw)||e}function Nt(e){return Boolean(e&&e.__v_isRef===!0)}y("nextTick",()=>ee);y("dispatch",e=>q.bind(q,e));y("watch",(e,{evaluateLater:t,effect:r})=>(n,i)=>{let o=t(n),s=!0,a,c=r(()=>o(l=>{JSON.stringify(l),s?a=l:queueMicrotask(()=>{i(l,a),a=l}),s=!1}));e._x_effects.delete(c)});y("store",Mr);y("data",e=>Ee(e));y("root",e=>U(e));y("refs",e=>(e._x_refs_proxy||(e._x_refs_proxy=j(yi(e))),e._x_refs_proxy));function yi(e){let t=[],r=e;for(;r;)r._x_refs&&t.push(r._x_refs),r=r.parentNode;return t}var Lt={};function $t(e){return Lt[e]||(Lt[e]=0),++Lt[e]}function sn(e,t){return X(e,r=>{if(r._x_ids&&r._x_ids[t])return!0})}function an(e,t){e._x_ids||(e._x_ids={}),e._x_ids[t]||(e._x_ids[t]=$t(t))}y("id",e=>(t,r=null)=>{let n=sn(e,t),i=n?n._x_ids[t]:$t(t);return r?`${t}-${i}-${r}`:`${t}-${i}`});y("el",e=>e);cn("Focus","focus","focus");cn("Persist","persist","persist");function cn(e,t,r){y(t,n=>T(`You can't use [$${directiveName}] without first installing the "${e}" plugin here: https://alpinejs.dev/plugins/${r}`,n))}function ln({get:e,set:t},{get:r,set:n}){let i=!0,o,s,a,c,l=P(()=>{let u,d;i?(u=e(),n(u),d=r(),i=!1):(u=e(),d=r(),a=JSON.stringify(u),c=JSON.stringify(d),a!==o?(d=r(),n(u),d=u):(t(d),u=d)),o=JSON.stringify(u),s=JSON.stringify(d)});return()=>{L(l)}}p("modelable",(e,{expression:t},{effect:r,evaluateLater:n,cleanup:i})=>{let o=n(t),s=()=>{let u;return o(d=>u=d),u},a=n(`${t} = __placeholder`),c=u=>a(()=>{},{scope:{__placeholder:u}}),l=s();c(l),queueMicrotask(()=>{if(!e._x_model)return;e._x_removeModelListeners.default();let u=e._x_model.get,d=e._x_model.set,m=ln({get(){return u()},set(w){d(w)}},{get(){return s()},set(w){c(w)}});i(m)})});var bi=document.createElement("div");p("teleport",(e,{modifiers:t,expression:r},{cleanup:n})=>{e.tagName.toLowerCase()!=="template"&&T("x-teleport can only be used on a <template> tag",e);let i=N(()=>document.querySelector(r),()=>bi)();i||T(`Cannot find x-teleport element for selector: "${r}"`);let o=e.content.cloneNode(!0).firstElementChild;e._x_teleport=o,o._x_teleportBack=e,e._x_forwardEvents&&e._x_forwardEvents.forEach(s=>{o.addEventListener(s,a=>{a.stopPropagation(),e.dispatchEvent(new a.constructor(a.type,a))})}),R(o,{},e),h(()=>{t.includes("prepend")?i.parentNode.insertBefore(o,i):t.includes("append")?i.parentNode.insertBefore(o,i.nextSibling):i.appendChild(o),v(o),o._x_ignore=!0}),n(()=>o.remove())});var un=()=>{};un.inline=(e,{modifiers:t},{cleanup:r})=>{t.includes("self")?e._x_ignoreSelf=!0:e._x_ignore=!0,r(()=>{t.includes("self")?delete e._x_ignoreSelf:delete e._x_ignore})};p("ignore",un);p("effect",(e,{expression:t},{effect:r})=>r(x(e,t)));function ie(e,t,r,n){let i=e,o=c=>n(c),s={},a=(c,l)=>u=>l(c,u);if(r.includes("dot")&&(t=wi(t)),r.includes("camel")&&(t=Ei(t)),r.includes("passive")&&(s.passive=!0),r.includes("capture")&&(s.capture=!0),r.includes("window")&&(i=window),r.includes("document")&&(i=document),r.includes("prevent")&&(o=a(o,(c,l)=>{l.preventDefault(),c(l)})),r.includes("stop")&&(o=a(o,(c,l)=>{l.stopPropagation(),c(l)})),r.includes("self")&&(o=a(o,(c,l)=>{l.target===e&&c(l)})),(r.includes("away")||r.includes("outside"))&&(i=document,o=a(o,(c,l)=>{e.contains(l.target)||l.target.isConnected!==!1&&(e.offsetWidth<1&&e.offsetHeight<1||e._x_isShown!==!1&&c(l))})),r.includes("once")&&(o=a(o,(c,l)=>{c(l),i.removeEventListener(t,o,s)})),o=a(o,(c,l)=>{Si(t)&&Ai(l,r)||c(l)}),r.includes("debounce")){let c=r[r.indexOf("debounce")+1]||"invalid-wait",l=Ge(c.split("ms")[0])?Number(c.split("ms")[0]):250;o=Pe(o,l)}if(r.includes("throttle")){let c=r[r.indexOf("throttle")+1]||"invalid-wait",l=Ge(c.split("ms")[0])?Number(c.split("ms")[0]):250;o=Ie(o,l)}return i.addEventListener(t,o,s),()=>{i.removeEventListener(t,o,s)}}function wi(e){return e.replace(/-/g,".")}function Ei(e){return e.toLowerCase().replace(/-(\w)/g,(t,r)=>r.toUpperCase())}function Ge(e){return!Array.isArray(e)&&!isNaN(e)}function vi(e){return[" ","_"].includes(e)?e:e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]/,"-").toLowerCase()}function Si(e){return["keydown","keyup"].includes(e)}function Ai(e,t){let r=t.filter(o=>!["window","document","prevent","stop","once","capture"].includes(o));if(r.includes("debounce")){let o=r.indexOf("debounce");r.splice(o,Ge((r[o+1]||"invalid-wait").split("ms")[0])?2:1)}if(r.includes("throttle")){let o=r.indexOf("throttle");r.splice(o,Ge((r[o+1]||"invalid-wait").split("ms")[0])?2:1)}if(r.length===0||r.length===1&&fn(e.key).includes(r[0]))return!1;let i=["ctrl","shift","alt","meta","cmd","super"].filter(o=>r.includes(o));return r=r.filter(o=>!i.includes(o)),!(i.length>0&&i.filter(s=>((s==="cmd"||s==="super")&&(s="meta"),e[`${s}Key`])).length===i.length&&fn(e.key).includes(r[0]))}function fn(e){if(!e)return[];e=vi(e);let t={ctrl:"control",slash:"/",space:" ",spacebar:" ",cmd:"meta",esc:"escape",up:"arrow-up",down:"arrow-down",left:"arrow-left",right:"arrow-right",period:".",equal:"=",minus:"-",underscore:"_"};return t[e]=e,Object.keys(t).map(r=>{if(t[r]===e)return r}).filter(r=>r)}p("model",(e,{modifiers:t,expression:r},{effect:n,cleanup:i})=>{let o=e;t.includes("parent")&&(o=e.parentNode);let s=x(o,r),a;typeof r=="string"?a=x(o,`${r} = __placeholder`):typeof r=="function"&&typeof r()=="string"?a=x(o,`${r()} = __placeholder`):a=()=>{};let c=()=>{let m;return s(w=>m=w),dn(m)?m.get():m},l=m=>{let w;s(k=>w=k),dn(w)?w.set(m):a(()=>{},{scope:{__placeholder:m}})};t.includes("fill")&&e.hasAttribute("value")&&(c()===null||c()==="")&&l(e.value),typeof r=="string"&&e.type==="radio"&&h(()=>{e.hasAttribute("name")||e.setAttribute("name",r)});var u=e.tagName.toLowerCase()==="select"||["checkbox","radio"].includes(e.type)||t.includes("lazy")?"change":"input";let d=te?()=>{}:ie(e,u,t,m=>{l(Oi(e,t,m,c()))});if(e._x_removeModelListeners||(e._x_removeModelListeners={}),e._x_removeModelListeners.default=d,i(()=>e._x_removeModelListeners.default()),e.form){let m=ie(e.form,"reset",[],w=>{ee(()=>e._x_model&&e._x_model.set(e.value))});i(()=>m())}e._x_model={get(){return c()},set(m){l(m)}},e._x_forceModelUpdate=m=>{m=m===void 0?c():m,m===void 0&&typeof r=="string"&&r.match(/\./)&&(m=""),window.fromModel=!0,h(()=>pe(e,"value",m)),delete window.fromModel},n(()=>{let m=c();t.includes("unintrusive")&&document.activeElement.isSameNode(e)||e._x_forceModelUpdate(m)})});function Oi(e,t,r,n){return h(()=>{if(r instanceof CustomEvent&&r.detail!==void 0)return typeof r.detail<"u"?r.detail:r.target.value;if(e.type==="checkbox")if(Array.isArray(n)){let i=t.includes("number")?jt(r.target.value):r.target.value;return r.target.checked?n.concat([i]):n.filter(o=>!Ci(o,i))}else return r.target.checked;else{if(e.tagName.toLowerCase()==="select"&&e.multiple)return t.includes("number")?Array.from(r.target.selectedOptions).map(i=>{let o=i.value||i.text;return jt(o)}):Array.from(r.target.selectedOptions).map(i=>i.value||i.text);{let i=r.target.value;return t.includes("number")?jt(i):t.includes("trim")?i.trim():i}}})}function jt(e){let t=e?parseFloat(e):null;return Ti(t)?t:e}function Ci(e,t){return e==t}function Ti(e){return!Array.isArray(e)&&!isNaN(e)}function dn(e){return e!==null&&typeof e=="object"&&typeof e.get=="function"&&typeof e.set=="function"}p("cloak",e=>queueMicrotask(()=>h(()=>e.removeAttribute(S("cloak")))));Re(()=>`[${S("init")}]`);p("init",N((e,{expression:t},{evaluate:r})=>typeof t=="string"?!!t.trim()&&r(t,{},!1):r(t,{},!1)));p("text",(e,{expression:t},{effect:r,evaluateLater:n})=>{let i=n(t);r(()=>{i(o=>{h(()=>{e.textContent=o})})})});p("html",(e,{expression:t},{effect:r,evaluateLater:n})=>{let i=n(t);r(()=>{i(o=>{h(()=>{e.innerHTML=o,e._x_ignoreSelf=!0,v(e),delete e._x_ignoreSelf})})})});Q(Ce(":",Te(S("bind:"))));p("bind",(e,{value:t,modifiers:r,expression:n,original:i},{effect:o})=>{if(!t){let a={};Dr(a),x(e,n)(l=>{vt(e,l,i)},{scope:a});return}if(t==="key")return Mi(e,n);let s=x(e,n);o(()=>s(a=>{a===void 0&&typeof n=="string"&&n.match(/\./)&&(a=""),h(()=>pe(e,t,a,r))}))});function Mi(e,t){e._x_keyExpression=t}Me(()=>`[${S("data")}]`);p("data",N((e,{expression:t},{cleanup:r})=>{t=t===""?"{}":t;let n={};ae(n,e);let i={};kr(i,n);let o=I(e,t,{scope:i});(o===void 0||o===!0)&&(o={}),ae(o,e);let s=C(o);ve(s);let a=R(e,s);s.init&&I(e,s.init),r(()=>{s.destroy&&I(e,s.destroy),a()})}));p("show",(e,{modifiers:t,expression:r},{effect:n})=>{let i=x(e,r);e._x_doHide||(e._x_doHide=()=>{h(()=>{e.style.setProperty("display","none",t.includes("important")?"important":void 0)})}),e._x_doShow||(e._x_doShow=()=>{h(()=>{e.style.length===1&&e.style.display==="none"?e.removeAttribute("style"):e.style.removeProperty("display")})});let o=()=>{e._x_doHide(),e._x_isShown=!1},s=()=>{e._x_doShow(),e._x_isShown=!0},a=()=>setTimeout(s),c=fe(d=>d?s():o(),d=>{typeof e._x_toggleAndCascadeWithTransitions=="function"?e._x_toggleAndCascadeWithTransitions(e,d,s,o):d?a():o()}),l,u=!0;n(()=>i(d=>{!u&&d===l||(t.includes("immediate")&&(d?a():o()),c(d),l=d,u=!1)}))});p("for",(e,{expression:t},{effect:r,cleanup:n})=>{let i=Ni(t),o=x(e,i.items),s=x(e,e._x_keyExpression||"index");e._x_prevKeys=[],e._x_lookup={},r(()=>Ri(e,i,o,s)),n(()=>{Object.values(e._x_lookup).forEach(a=>a.remove()),delete e._x_prevKeys,delete e._x_lookup})});function Ri(e,t,r,n){let i=s=>typeof s=="object"&&!Array.isArray(s),o=e;r(s=>{Di(s)&&s>=0&&(s=Array.from(Array(s).keys(),f=>f+1)),s===void 0&&(s=[]);let a=e._x_lookup,c=e._x_prevKeys,l=[],u=[];if(i(s))s=Object.entries(s).map(([f,_])=>{let b=pn(t,_,f,s);n(E=>u.push(E),{scope:{index:f,...b}}),l.push(b)});else for(let f=0;f<s.length;f++){let _=pn(t,s[f],f,s);n(b=>u.push(b),{scope:{index:f,..._}}),l.push(_)}let d=[],m=[],w=[],k=[];for(let f=0;f<c.length;f++){let _=c[f];u.indexOf(_)===-1&&w.push(_)}c=c.filter(f=>!w.includes(f));let ge="template";for(let f=0;f<u.length;f++){let _=u[f],b=c.indexOf(_);if(b===-1)c.splice(f,0,_),d.push([ge,f]);else if(b!==f){let E=c.splice(f,1)[0],O=c.splice(b-1,1)[0];c.splice(f,0,O),c.splice(b,0,E),m.push([E,O])}else k.push(_);ge=_}for(let f=0;f<w.length;f++){let _=w[f];a[_]._x_effects&&a[_]._x_effects.forEach(ye),a[_].remove(),a[_]=null,delete a[_]}for(let f=0;f<m.length;f++){let[_,b]=m[f],E=a[_],O=a[b],Y=document.createElement("div");h(()=>{O.after(Y),E.after(O),O._x_currentIfEl&&O.after(O._x_currentIfEl),Y.before(E),E._x_currentIfEl&&E.after(E._x_currentIfEl),Y.remove()}),lt(O,l[u.indexOf(b)])}for(let f=0;f<d.length;f++){let[_,b]=d[f],E=_==="template"?o:a[_];E._x_currentIfEl&&(E=E._x_currentIfEl);let O=l[b],Y=u[b],xe=document.importNode(o.content,!0).firstElementChild;R(xe,C(O),o),h(()=>{E.after(xe),v(xe)}),typeof Y=="object"&&T("x-for key cannot be an object, it must be a string or an integer",o),a[Y]=xe}for(let f=0;f<k.length;f++)lt(a[k[f]],l[u.indexOf(k[f])]);o._x_prevKeys=u})}function Ni(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=/^\s*\(|\)\s*$/g,n=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,i=e.match(n);if(!i)return;let o={};o.items=i[2].trim();let s=i[1].replace(r,"").trim(),a=s.match(t);return a?(o.item=s.replace(t,"").trim(),o.index=a[1].trim(),a[2]&&(o.collection=a[2].trim())):o.item=s,o}function pn(e,t,r,n){let i={};return/^\[.*\]$/.test(e.item)&&Array.isArray(t)?e.item.replace("[","").replace("]","").split(",").map(s=>s.trim()).forEach((s,a)=>{i[s]=t[a]}):/^\{.*\}$/.test(e.item)&&!Array.isArray(t)&&typeof t=="object"?e.item.replace("{","").replace("}","").split(",").map(s=>s.trim()).forEach(s=>{i[s]=t[s]}):i[e.item]=t,e.index&&(i[e.index]=r),e.collection&&(i[e.collection]=n),i}function Di(e){return!Array.isArray(e)&&!isNaN(e)}function mn(){}mn.inline=(e,{expression:t},{cleanup:r})=>{let n=U(e);n._x_refs||(n._x_refs={}),n._x_refs[t]=e,r(()=>delete n._x_refs[t])};p("ref",mn);p("if",(e,{expression:t},{effect:r,cleanup:n})=>{let i=x(e,t),o=()=>{if(e._x_currentIfEl)return e._x_currentIfEl;let a=e.content.cloneNode(!0).firstElementChild;return R(a,{},e),h(()=>{e.after(a),v(a)}),e._x_currentIfEl=a,e._x_undoIf=()=>{A(a,c=>{c._x_effects&&c._x_effects.forEach(ye)}),a.remove(),delete e._x_currentIfEl},a},s=()=>{e._x_undoIf&&(e._x_undoIf(),delete e._x_undoIf)};r(()=>i(a=>{a?o():s()})),n(()=>e._x_undoIf&&e._x_undoIf())});p("id",(e,{expression:t},{evaluate:r})=>{r(t).forEach(i=>an(e,i))});Q(Ce("@",Te(S("on:"))));p("on",N((e,{value:t,modifiers:r,expression:n},{cleanup:i})=>{let o=n?x(e,n):()=>{};e.tagName.toLowerCase()==="template"&&(e._x_forwardEvents||(e._x_forwardEvents=[]),e._x_forwardEvents.includes(t)||e._x_forwardEvents.push(t));let s=ie(e,t,r,a=>{o(()=>{},{scope:{$event:a},params:[a]})});i(()=>s())}));Je("Collapse","collapse","collapse");Je("Intersect","intersect","intersect");Je("Focus","trap","focus");Je("Mask","mask","mask");function Je(e,t,r){p(t,n=>T(`You can't use [x-${t}] without first installing the "${e}" plugin here: https://alpinejs.dev/plugins/${r}`,n))}F.setEvaluator(pt);F.setReactivityEngine({reactive:We,effect:jr,release:Fr,raw:g});var Ft=F;window.Alpine=Ft;queueMicrotask(()=>{Ft.start()});})();
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 23963a6e1..9510a2392 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -18,10 +18,10 @@
         href="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('favicon.ico') }}"
         type="image/x-icon">
 
-    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
+    <script src="{{ asset('plugins/alpinejs/3.12.0_cdn.min.js') }}"></script>
 
     {{-- <link rel="stylesheet" href="{{asset('css/adminlte.min.css')}}"> --}}
-    href="{{ asset('plugins/datatables/jquery.dataTables.min.css') }}">
+    <link rel="stylesheet" href="{{ asset('plugins/datatables/jquery.dataTables.min.css') }}">
 
     {{-- summernote --}}
     <link rel="stylesheet" href="{{ asset('plugins/summernote/summernote-bs4.min.css') }}">

From c1165c4561b419080c85630ffdf98bd03bd3996a Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sat, 29 Apr 2023 23:39:59 +0200
Subject: [PATCH 099/514] update sweetalert to local

---
 public/plugins/sweetalert2/sweetalert2.all.min.js | 4 ++--
 themes/default/views/layouts/main.blade.php       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/public/plugins/sweetalert2/sweetalert2.all.min.js b/public/plugins/sweetalert2/sweetalert2.all.min.js
index ba6370388..5f87e64c9 100644
--- a/public/plugins/sweetalert2/sweetalert2.all.min.js
+++ b/public/plugins/sweetalert2/sweetalert2.all.min.js
@@ -1,2 +1,2 @@
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sweetalert2=e()}(this,function(){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function c(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}function s(){return(s=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function u(t){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function l(t,e){return(l=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function d(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}function i(t,e,n){return(i=d()?Reflect.construct:function(t,e,n){var o=[null];o.push.apply(o,e);o=new(Function.bind.apply(t,o));return n&&l(o,n.prototype),o}).apply(null,arguments)}function p(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function f(t,e,n){return(f="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){t=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=u(t)););return t}(t,e);if(t){e=Object.getOwnPropertyDescriptor(t,e);return e.get?e.get.call(n):e.value}})(t,e,n||t)}function m(t){return t.charAt(0).toUpperCase()+t.slice(1)}function h(e){return Object.keys(e).map(function(t){return e[t]})}function g(t){return Array.prototype.slice.call(t)}function v(t,e){e='"'.concat(t,'" is deprecated and will be removed in the next major release. Please use "').concat(e,'" instead.'),-1===Y.indexOf(e)&&(Y.push(e),W(e))}function b(t){return t&&"function"==typeof t.toPromise}function y(t){return b(t)?t.toPromise():Promise.resolve(t)}function w(t){return t&&Promise.resolve(t)===t}function C(t){return t instanceof Element||"object"===r(t=t)&&t.jquery}function k(){return document.body.querySelector(".".concat($.container))}function A(t){var e=k();return e?e.querySelector(t):null}function t(t){return A(".".concat(t))}function x(){return t($.popup)}function n(){var t=x();return g(t.querySelectorAll(".".concat($.icon)))}function B(){var t=n().filter(function(t){return wt(t)});return t.length?t[0]:null}function P(){return t($.title)}function E(){return t($.content)}function S(){return t($.image)}function O(){return t($["progress-steps"])}function T(){return t($["validation-message"])}function L(){return A(".".concat($.actions," .").concat($.confirm))}function q(){return A(".".concat($.actions," .").concat($.deny))}function D(){return A(".".concat($.loader))}function j(){return A(".".concat($.actions," .").concat($.cancel))}function I(){return t($.actions)}function M(){return t($.header)}function H(){return t($.footer)}function V(){return t($["timer-progress-bar"])}function R(){return t($.close)}function N(){var t=g(x().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')).sort(function(t,e){return t=parseInt(t.getAttribute("tabindex")),(e=parseInt(e.getAttribute("tabindex")))<t?1:t<e?-1:0}),e=g(x().querySelectorAll('\n  a[href],\n  area[href],\n  input:not([disabled]),\n  select:not([disabled]),\n  textarea:not([disabled]),\n  button:not([disabled]),\n  iframe,\n  object,\n  embed,\n  [tabindex="0"],\n  [contenteditable],\n  audio[controls],\n  video[controls],\n  summary\n')).filter(function(t){return"-1"!==t.getAttribute("tabindex")});return function(t){for(var e=[],n=0;n<t.length;n++)-1===e.indexOf(t[n])&&e.push(t[n]);return e}(t.concat(e)).filter(function(t){return wt(t)})}function U(){return!G()&&!document.body.classList.contains($["no-backdrop"])}function _(e,t){e.textContent="",t&&(t=(new DOMParser).parseFromString(t,"text/html"),g(t.querySelector("head").childNodes).forEach(function(t){e.appendChild(t)}),g(t.querySelector("body").childNodes).forEach(function(t){e.appendChild(t)}))}function F(t,e){if(e){for(var n=e.split(/\s+/),o=0;o<n.length;o++)if(!t.classList.contains(n[o]))return;return 1}}function z(t,e,n){var o,i;if(i=e,g((o=t).classList).forEach(function(t){-1===h($).indexOf(t)&&-1===h(X).indexOf(t)&&-1===h(i.showClass).indexOf(t)&&o.classList.remove(t)}),e.customClass&&e.customClass[n]){if("string"!=typeof e.customClass[n]&&!e.customClass[n].forEach)return W("Invalid type of customClass.".concat(n,'! Expected string or iterable object, got "').concat(r(e.customClass[n]),'"'));vt(t,e.customClass[n])}}var e="SweetAlert2:",W=function(t){console.warn("".concat(e," ").concat("object"===r(t)?t.join(" "):t))},K=function(t){console.error("".concat(e," ").concat(t))},Y=[],Z=function(t){return"function"==typeof t?t():t},Q=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),J=function(t){var e,n={};for(e in t)n[t[e]]="swal2-"+t[e];return n},$=J(["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","toast-column","show","hide","close","title","header","content","html-container","actions","confirm","deny","cancel","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error"]),X=J(["success","warning","info","question","error"]),G=function(){return document.body.classList.contains($["toast-shown"])},tt={previousBodyPadding:null};function et(t,e){if(!e)return null;switch(e){case"select":case"textarea":case"file":return yt(t,$[e]);case"checkbox":return t.querySelector(".".concat($.checkbox," input"));case"radio":return t.querySelector(".".concat($.radio," input:checked"))||t.querySelector(".".concat($.radio," input:first-child"));case"range":return t.querySelector(".".concat($.range," input"));default:return yt(t,$.input)}}function nt(t){var e;t.focus(),"file"!==t.type&&(e=t.value,t.value="",t.value=e)}function ot(t,e,n){t&&e&&("string"==typeof e&&(e=e.split(/\s+/).filter(Boolean)),e.forEach(function(e){t.forEach?t.forEach(function(t){n?t.classList.add(e):t.classList.remove(e)}):n?t.classList.add(e):t.classList.remove(e)}))}function it(t,e,n){n==="".concat(parseInt(n))&&(n=parseInt(n)),n||0===parseInt(n)?t.style[e]="number"==typeof n?"".concat(n,"px"):n:t.style.removeProperty(e)}function rt(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"flex";t.style.display=e}function at(t){t.style.display="none"}function ct(t,e,n,o){(e=t.querySelector(e))&&(e.style[n]=o)}function st(t,e,n){e?rt(t,n):at(t)}function ut(t){return!!(t.scrollHeight>t.clientHeight)}function lt(t){var e=window.getComputedStyle(t),t=parseFloat(e.getPropertyValue("animation-duration")||"0"),e=parseFloat(e.getPropertyValue("transition-duration")||"0");return 0<t||0<e}function dt(t){var e=1<arguments.length&&void 0!==arguments[1]&&arguments[1],n=V();wt(n)&&(e&&(n.style.transition="none",n.style.width="100%"),setTimeout(function(){n.style.transition="width ".concat(t/1e3,"s linear"),n.style.width="0%"},10))}function pt(){return"undefined"==typeof window||"undefined"==typeof document}function ft(t){Mn.isVisible()&&gt!==t.target.value&&Mn.resetValidationMessage(),gt=t.target.value}function mt(t,e){t instanceof HTMLElement?e.appendChild(t):"object"===r(t)?At(t,e):t&&_(e,t)}function ht(t,e){var n,o,i,r,a=I(),c=D(),s=L(),u=q(),l=j();e.showConfirmButton||e.showDenyButton||e.showCancelButton||at(a),z(a,e,"actions"),Pt(s,"confirm",e),Pt(u,"deny",e),Pt(l,"cancel",e),n=s,o=u,i=l,(r=e).buttonsStyling?(vt([n,o,i],$.styled),r.confirmButtonColor&&(n.style.backgroundColor=r.confirmButtonColor),r.denyButtonColor&&(o.style.backgroundColor=r.denyButtonColor),r.cancelButtonColor&&(i.style.backgroundColor=r.cancelButtonColor)):bt([n,o,i],$.styled),e.reverseButtons&&(a.insertBefore(l,c),a.insertBefore(u,c),a.insertBefore(s,c)),_(c,e.loaderHtml),z(c,e,"loader")}var gt,vt=function(t,e){ot(t,e,!0)},bt=function(t,e){ot(t,e,!1)},yt=function(t,e){for(var n=0;n<t.childNodes.length;n++)if(F(t.childNodes[n],e))return t.childNodes[n]},wt=function(t){return!(!t||!(t.offsetWidth||t.offsetHeight||t.getClientRects().length))},Ct='\n <div aria-labelledby="'.concat($.title,'" aria-describedby="').concat($.content,'" class="').concat($.popup,'" tabindex="-1">\n   <div class="').concat($.header,'">\n     <ul class="').concat($["progress-steps"],'"></ul>\n     <div class="').concat($.icon," ").concat(X.error,'"></div>\n     <div class="').concat($.icon," ").concat(X.question,'"></div>\n     <div class="').concat($.icon," ").concat(X.warning,'"></div>\n     <div class="').concat($.icon," ").concat(X.info,'"></div>\n     <div class="').concat($.icon," ").concat(X.success,'"></div>\n     <img class="').concat($.image,'" />\n     <h2 class="').concat($.title,'" id="').concat($.title,'"></h2>\n     <button type="button" class="').concat($.close,'"></button>\n   </div>\n   <div class="').concat($.content,'">\n     <div id="').concat($.content,'" class="').concat($["html-container"],'"></div>\n     <input class="').concat($.input,'" />\n     <input type="file" class="').concat($.file,'" />\n     <div class="').concat($.range,'">\n       <input type="range" />\n       <output></output>\n     </div>\n     <select class="').concat($.select,'"></select>\n     <div class="').concat($.radio,'"></div>\n     <label for="').concat($.checkbox,'" class="').concat($.checkbox,'">\n       <input type="checkbox" />\n       <span class="').concat($.label,'"></span>\n     </label>\n     <textarea class="').concat($.textarea,'"></textarea>\n     <div class="').concat($["validation-message"],'" id="').concat($["validation-message"],'"></div>\n   </div>\n   <div class="').concat($.actions,'">\n     <div class="').concat($.loader,'"></div>\n     <button type="button" class="').concat($.confirm,'"></button>\n     <button type="button" class="').concat($.deny,'"></button>\n     <button type="button" class="').concat($.cancel,'"></button>\n   </div>\n   <div class="').concat($.footer,'"></div>\n   <div class="').concat($["timer-progress-bar-container"],'">\n     <div class="').concat($["timer-progress-bar"],'"></div>\n   </div>\n </div>\n').replace(/(^|\n)\s*/g,""),kt=function(t){var e,n,o,i,r,a=!!(i=k())&&(i.parentNode.removeChild(i),bt([document.documentElement,document.body],[$["no-backdrop"],$["toast-shown"],$["has-column"]]),!0);pt()?K("SweetAlert2 requires document to initialize"):((r=document.createElement("div")).className=$.container,a&&vt(r,$["no-transition"]),_(r,Ct),(i="string"==typeof(e=t.target)?document.querySelector(e):e).appendChild(r),a=t,(e=x()).setAttribute("role",a.toast?"alert":"dialog"),e.setAttribute("aria-live",a.toast?"polite":"assertive"),a.toast||e.setAttribute("aria-modal","true"),r=i,"rtl"===window.getComputedStyle(r).direction&&vt(k(),$.rtl),t=E(),a=yt(t,$.input),e=yt(t,$.file),n=t.querySelector(".".concat($.range," input")),o=t.querySelector(".".concat($.range," output")),i=yt(t,$.select),r=t.querySelector(".".concat($.checkbox," input")),t=yt(t,$.textarea),a.oninput=ft,e.onchange=ft,i.onchange=ft,r.onchange=ft,t.oninput=ft,n.oninput=function(t){ft(t),o.value=n.value},n.onchange=function(t){ft(t),n.nextSibling.value=n.value})},At=function(t,e){t.jquery?xt(e,t):_(e,t.toString())},xt=function(t,e){if(t.textContent="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0))},Bt=function(){if(pt())return!1;var t,e=document.createElement("div"),n={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",animation:"animationend"};for(t in n)if(Object.prototype.hasOwnProperty.call(n,t)&&void 0!==e.style[t])return n[t];return!1}();function Pt(t,e,n){st(t,n["show".concat(m(e),"Button")],"inline-block"),_(t,n["".concat(e,"ButtonText")]),t.setAttribute("aria-label",n["".concat(e,"ButtonAriaLabel")]),t.className=$[e],z(t,n,"".concat(e,"Button")),vt(t,n["".concat(e,"ButtonClass")])}function Et(t,e){var n,o,i=k();i&&(o=i,"string"==typeof(n=e.backdrop)?o.style.background=n:n||vt([document.documentElement,document.body],$["no-backdrop"]),!e.backdrop&&e.allowOutsideClick&&W('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),o=i,(n=e.position)in $?vt(o,$[n]):(W('The "position" parameter is not valid, defaulting to "center"'),vt(o,$.center)),n=i,!(o=e.grow)||"string"!=typeof o||(o="grow-".concat(o))in $&&vt(n,$[o]),z(i,e,"container"),(e=document.body.getAttribute("data-swal2-queue-step"))&&(i.setAttribute("data-queue-step",e),document.body.removeAttribute("data-swal2-queue-step")))}function St(t,e){t.placeholder&&!e.inputPlaceholder||(t.placeholder=e.inputPlaceholder)}function Ot(t,e,n){var o,i;n.inputLabel&&(t.id=$.input,o=document.createElement("label"),i=$["input-label"],o.setAttribute("for",t.id),o.className=i,vt(o,n.customClass.inputLabel),o.innerText=n.inputLabel,e.insertAdjacentElement("beforebegin",o))}var Tt={promise:new WeakMap,innerParams:new WeakMap,domCache:new WeakMap},Lt=["input","file","range","select","radio","checkbox","textarea"],qt=function(t){if(!Mt[t.input])return K('Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "'.concat(t.input,'"'));var e=It(t.input),n=Mt[t.input](e,t);rt(n),setTimeout(function(){nt(n)})},Dt=function(t,e){var n=et(E(),t);if(n)for(var o in!function(t){for(var e=0;e<t.attributes.length;e++){var n=t.attributes[e].name;-1===["type","value","style"].indexOf(n)&&t.removeAttribute(n)}}(n),e)"range"===t&&"placeholder"===o||n.setAttribute(o,e[o])},jt=function(t){var e=It(t.input);t.customClass&&vt(e,t.customClass.input)},It=function(t){t=$[t]||$.input;return yt(E(),t)},Mt={};Mt.text=Mt.email=Mt.password=Mt.number=Mt.tel=Mt.url=function(t,e){return"string"==typeof e.inputValue||"number"==typeof e.inputValue?t.value=e.inputValue:w(e.inputValue)||W('Unexpected type of inputValue! Expected "string", "number" or "Promise", got "'.concat(r(e.inputValue),'"')),Ot(t,t,e),St(t,e),t.type=e.input,t},Mt.file=function(t,e){return Ot(t,t,e),St(t,e),t},Mt.range=function(t,e){var n=t.querySelector("input"),o=t.querySelector("output");return n.value=e.inputValue,n.type=e.input,o.value=e.inputValue,Ot(n,t,e),t},Mt.select=function(t,e){var n;return t.textContent="",e.inputPlaceholder&&(n=document.createElement("option"),_(n,e.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,t.appendChild(n)),Ot(t,t,e),t},Mt.radio=function(t){return t.textContent="",t},Mt.checkbox=function(t,e){var n=et(E(),"checkbox");n.value=1,n.id=$.checkbox,n.checked=Boolean(e.inputValue);n=t.querySelector("span");return _(n,e.inputPlaceholder),t},Mt.textarea=function(e,t){e.value=t.inputValue,St(e,t),Ot(e,e,t);function n(t){return parseInt(window.getComputedStyle(t).paddingLeft)+parseInt(window.getComputedStyle(t).paddingRight)}var o;return"MutationObserver"in window&&(o=parseInt(window.getComputedStyle(x()).width),new MutationObserver(function(){var t=e.offsetWidth+n(x())+n(E());x().style.width=o<t?"".concat(t,"px"):null}).observe(e,{attributes:!0,attributeFilter:["style"]})),e};function Ht(t,e){var o,i,r,n=E().querySelector("#".concat($.content));e.html?(mt(e.html,n),rt(n,"block")):e.text?(n.textContent=e.text,rt(n,"block")):at(n),t=t,o=e,i=E(),t=Tt.innerParams.get(t),r=!t||o.input!==t.input,Lt.forEach(function(t){var e=$[t],n=yt(i,e);Dt(t,o.inputAttributes),n.className=e,r&&at(n)}),o.input&&(r&&qt(o),jt(o)),z(E(),e,"content")}function Vt(){return k()&&k().getAttribute("data-queue-step")}function Rt(t,o){var i=O();if(!o.progressSteps||0===o.progressSteps.length)return at(i),0;rt(i),i.textContent="";var r=parseInt(void 0===o.currentProgressStep?Vt():o.currentProgressStep);r>=o.progressSteps.length&&W("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.progressSteps.forEach(function(t,e){var n,t=(n=t,t=document.createElement("li"),vt(t,$["progress-step"]),_(t,n),t);i.appendChild(t),e===r&&vt(t,$["active-progress-step"]),e!==o.progressSteps.length-1&&(t=o,e=document.createElement("li"),vt(e,$["progress-step-line"]),t.progressStepsDistance&&(e.style.width=t.progressStepsDistance),e=e,i.appendChild(e))})}function Nt(t,e){var n=M();z(n,e,"header"),Rt(0,e),n=t,t=e,(n=Tt.innerParams.get(n))&&t.icon===n.icon&&B()?zt(B(),t):(Ft(),t.icon&&(-1!==Object.keys(X).indexOf(t.icon)?(n=A(".".concat($.icon,".").concat(X[t.icon])),rt(n),Kt(n,t),zt(n,t),vt(n,t.showClass.icon)):K('Unknown icon! Expected "success", "error", "warning", "info" or "question", got "'.concat(t.icon,'"')))),function(t){var e=S();if(!t.imageUrl)return at(e);rt(e,""),e.setAttribute("src",t.imageUrl),e.setAttribute("alt",t.imageAlt),it(e,"width",t.imageWidth),it(e,"height",t.imageHeight),e.className=$.image,z(e,t,"image")}(e),n=e,t=P(),st(t,n.title||n.titleText),n.title&&mt(n.title,t),n.titleText&&(t.innerText=n.titleText),z(t,n,"title"),n=e,e=R(),_(e,n.closeButtonHtml),z(e,n,"closeButton"),st(e,n.showCloseButton),e.setAttribute("aria-label",n.closeButtonAriaLabel)}function Ut(t,e){var n,o;o=e,n=x(),it(n,"width",o.width),it(n,"padding",o.padding),o.background&&(n.style.background=o.background),Jt(n,o),Et(0,e),Nt(t,e),Ht(t,e),ht(0,e),o=e,t=H(),st(t,o.footer),o.footer&&mt(o.footer,t),z(t,o,"footer"),"function"==typeof e.didRender?e.didRender(x()):"function"==typeof e.onRender&&e.onRender(x())}function _t(){return L()&&L().click()}var Ft=function(){for(var t=n(),e=0;e<t.length;e++)at(t[e])},zt=function(t,e){Yt(t,e),Wt(),z(t,e,"icon")},Wt=function(){for(var t=x(),e=window.getComputedStyle(t).getPropertyValue("background-color"),n=t.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix"),o=0;o<n.length;o++)n[o].style.backgroundColor=e},Kt=function(t,e){t.textContent="",e.iconHtml?_(t,Zt(e.iconHtml)):"success"===e.icon?_(t,'\n      <div class="swal2-success-circular-line-left"></div>\n      <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>\n      <div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>\n      <div class="swal2-success-circular-line-right"></div>\n    '):"error"===e.icon?_(t,'\n      <span class="swal2-x-mark">\n        <span class="swal2-x-mark-line-left"></span>\n        <span class="swal2-x-mark-line-right"></span>\n      </span>\n    '):_(t,Zt({question:"?",warning:"!",info:"i"}[e.icon]))},Yt=function(t,e){if(e.iconColor){t.style.color=e.iconColor,t.style.borderColor=e.iconColor;for(var n=0,o=[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"];n<o.length;n++)ct(t,o[n],"backgroundColor",e.iconColor);ct(t,".swal2-success-ring","borderColor",e.iconColor)}},Zt=function(t){return'<div class="'.concat($["icon-content"],'">').concat(t,"</div>")},Qt=[],Jt=function(t,e){t.className="".concat($.popup," ").concat(wt(t)?e.showClass.popup:""),e.toast?(vt([document.documentElement,document.body],$["toast-shown"]),vt(t,$.toast)):vt(t,$.modal),z(t,e,"popup"),"string"==typeof e.customClass&&vt(t,e.customClass),e.icon&&vt(t,$["icon-".concat(e.icon)])};function $t(t){var e=x();e||Mn.fire(),e=x();var n=I(),o=D();!t&&wt(L())&&(t=L()),rt(n),t&&(at(t),o.setAttribute("data-button-to-replace",t.className)),o.parentNode.insertBefore(o,t),vt([e,n],$.loading),rt(o),e.setAttribute("data-loading",!0),e.setAttribute("aria-busy",!0),e.focus()}function Xt(){return new Promise(function(t){var e=window.scrollX,n=window.scrollY;ee.restoreFocusTimeout=setTimeout(function(){ee.previousActiveElement&&ee.previousActiveElement.focus?(ee.previousActiveElement.focus(),ee.previousActiveElement=null):document.body&&document.body.focus(),t()},100),void 0!==e&&void 0!==n&&window.scrollTo(e,n)})}function Gt(){if(ee.timeout)return function(){var t=V(),e=parseInt(window.getComputedStyle(t).width);t.style.removeProperty("transition"),t.style.width="100%";var n=parseInt(window.getComputedStyle(t).width),n=parseInt(e/n*100);t.style.removeProperty("transition"),t.style.width="".concat(n,"%")}(),ee.timeout.stop()}function te(){if(ee.timeout){var t=ee.timeout.start();return dt(t),t}}var ee={},ne=!1,oe={};function ie(t){for(var e=t.target;e&&e!==document;e=e.parentNode)for(var n in oe){var o=e.getAttribute(n);if(o)return void oe[n].fire({template:o})}}function re(t){return Object.prototype.hasOwnProperty.call(se,t)}function ae(t){return le[t]}function ce(t){for(var e in t)re(o=e)||W('Unknown parameter "'.concat(o,'"')),t.toast&&(n=e,-1!==de.indexOf(n)&&W('The parameter "'.concat(n,'" is incompatible with toasts'))),ae(n=e)&&v(n,ae(n));var n,o}var se={title:"",titleText:"",text:"",html:"",footer:"",icon:void 0,iconColor:void 0,iconHtml:void 0,template:void 0,toast:!1,animation:!0,showClass:{popup:"swal2-show",backdrop:"swal2-backdrop-show",icon:"swal2-icon-show"},hideClass:{popup:"swal2-hide",backdrop:"swal2-backdrop-hide",icon:"swal2-icon-hide"},customClass:{},target:"body",backdrop:!0,heightAuto:!0,allowOutsideClick:!0,allowEscapeKey:!0,allowEnterKey:!0,stopKeydownPropagation:!0,keydownListenerCapture:!1,showConfirmButton:!0,showDenyButton:!1,showCancelButton:!1,preConfirm:void 0,preDeny:void 0,confirmButtonText:"OK",confirmButtonAriaLabel:"",confirmButtonColor:void 0,denyButtonText:"No",denyButtonAriaLabel:"",denyButtonColor:void 0,cancelButtonText:"Cancel",cancelButtonAriaLabel:"",cancelButtonColor:void 0,buttonsStyling:!0,reverseButtons:!1,focusConfirm:!0,focusDeny:!1,focusCancel:!1,showCloseButton:!1,closeButtonHtml:"&times;",closeButtonAriaLabel:"Close this dialog",loaderHtml:"",showLoaderOnConfirm:!1,imageUrl:void 0,imageWidth:void 0,imageHeight:void 0,imageAlt:"",timer:void 0,timerProgressBar:!1,width:void 0,padding:void 0,background:void 0,input:void 0,inputPlaceholder:"",inputLabel:"",inputValue:"",inputOptions:{},inputAutoTrim:!0,inputAttributes:{},inputValidator:void 0,returnInputValueOnDeny:!1,validationMessage:void 0,grow:!1,position:"center",progressSteps:[],currentProgressStep:void 0,progressStepsDistance:void 0,onBeforeOpen:void 0,onOpen:void 0,willOpen:void 0,didOpen:void 0,onRender:void 0,didRender:void 0,onClose:void 0,onAfterClose:void 0,willClose:void 0,didClose:void 0,onDestroy:void 0,didDestroy:void 0,scrollbarPadding:!0},ue=["allowEscapeKey","allowOutsideClick","background","buttonsStyling","cancelButtonAriaLabel","cancelButtonColor","cancelButtonText","closeButtonAriaLabel","closeButtonHtml","confirmButtonAriaLabel","confirmButtonColor","confirmButtonText","currentProgressStep","customClass","denyButtonAriaLabel","denyButtonColor","denyButtonText","didClose","didDestroy","footer","hideClass","html","icon","iconColor","imageAlt","imageHeight","imageUrl","imageWidth","onAfterClose","onClose","onDestroy","progressSteps","reverseButtons","showCancelButton","showCloseButton","showConfirmButton","showDenyButton","text","title","titleText","willClose"],le={animation:'showClass" and "hideClass',onBeforeOpen:"willOpen",onOpen:"didOpen",onRender:"didRender",onClose:"willClose",onAfterClose:"didClose",onDestroy:"didDestroy"},de=["allowOutsideClick","allowEnterKey","backdrop","focusConfirm","focusDeny","focusCancel","heightAuto","keydownListenerCapture"],pe=Object.freeze({isValidParameter:re,isUpdatableParameter:function(t){return-1!==ue.indexOf(t)},isDeprecatedParameter:ae,argsToParams:function(n){var o={};return"object"!==r(n[0])||C(n[0])?["title","html","icon"].forEach(function(t,e){e=n[e];"string"==typeof e||C(e)?o[t]=e:void 0!==e&&K("Unexpected type of ".concat(t,'! Expected "string" or "Element", got ').concat(r(e)))}):s(o,n[0]),o},isVisible:function(){return wt(x())},clickConfirm:_t,clickDeny:function(){return q()&&q().click()},clickCancel:function(){return j()&&j().click()},getContainer:k,getPopup:x,getTitle:P,getContent:E,getHtmlContainer:function(){return t($["html-container"])},getImage:S,getIcon:B,getIcons:n,getInputLabel:function(){return t($["input-label"])},getCloseButton:R,getActions:I,getConfirmButton:L,getDenyButton:q,getCancelButton:j,getLoader:D,getHeader:M,getFooter:H,getTimerProgressBar:V,getFocusableElements:N,getValidationMessage:T,isLoading:function(){return x().hasAttribute("data-loading")},fire:function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];return i(this,e)},mixin:function(r){return function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&l(t,e)}(i,t);var n,o,e=(n=i,o=d(),function(){var t,e=u(n);return p(this,o?(t=u(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments))});function i(){return a(this,i),e.apply(this,arguments)}return c(i,[{key:"_main",value:function(t,e){return f(u(i.prototype),"_main",this).call(this,t,s({},e,r))}}]),i}(this)},queue:function(t){var r=this;Qt=t;function a(t,e){Qt=[],t(e)}var c=[];return new Promise(function(i){!function e(n,o){n<Qt.length?(document.body.setAttribute("data-swal2-queue-step",n),r.fire(Qt[n]).then(function(t){void 0!==t.value?(c.push(t.value),e(n+1,o)):a(i,{dismiss:t.dismiss})})):a(i,{value:c})}(0)})},getQueueStep:Vt,insertQueueStep:function(t,e){return e&&e<Qt.length?Qt.splice(e,0,t):Qt.push(t)},deleteQueueStep:function(t){void 0!==Qt[t]&&Qt.splice(t,1)},showLoading:$t,enableLoading:$t,getTimerLeft:function(){return ee.timeout&&ee.timeout.getTimerLeft()},stopTimer:Gt,resumeTimer:te,toggleTimer:function(){var t=ee.timeout;return t&&(t.running?Gt:te)()},increaseTimer:function(t){if(ee.timeout){t=ee.timeout.increase(t);return dt(t,!0),t}},isTimerRunning:function(){return ee.timeout&&ee.timeout.isRunning()},bindClickHandler:function(){oe[0<arguments.length&&void 0!==arguments[0]?arguments[0]:"data-swal-template"]=this,ne||(document.body.addEventListener("click",ie),ne=!0)}});function fe(){var t,e;Tt.innerParams.get(this)&&(t=Tt.domCache.get(this),at(t.loader),(e=t.popup.getElementsByClassName(t.loader.getAttribute("data-button-to-replace"))).length?rt(e[0],"inline-block"):wt(L())||wt(q())||wt(j())||at(t.actions),bt([t.popup,t.actions],$.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1)}function me(){null===tt.previousBodyPadding&&document.body.scrollHeight>window.innerHeight&&(tt.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight="".concat(tt.previousBodyPadding+function(){var t=document.createElement("div");t.className=$["scrollbar-measure"],document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}(),"px"))}function he(){return!!window.MSInputMethodContext&&!!document.documentMode}function ge(){var t=k(),e=x();t.style.removeProperty("align-items"),e.offsetTop<0&&(t.style.alignItems="flex-start")}var ve=function(){navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i)||x().scrollHeight>window.innerHeight-44&&(k().style.paddingBottom="".concat(44,"px"))},be=function(){var e,t=k();t.ontouchstart=function(t){e=ye(t)},t.ontouchmove=function(t){e&&(t.preventDefault(),t.stopPropagation())}},ye=function(t){var e=t.target,n=k();return!we(t)&&!Ce(t)&&(e===n||!(ut(n)||"INPUT"===e.tagName||ut(E())&&E().contains(e)))},we=function(t){return t.touches&&t.touches.length&&"stylus"===t.touches[0].touchType},Ce=function(t){return t.touches&&1<t.touches.length},ke={swalPromiseResolve:new WeakMap};function Ae(t,e,n,o){n?Oe(t,o):(Xt().then(function(){return Oe(t,o)}),ee.keydownTarget.removeEventListener("keydown",ee.keydownHandler,{capture:ee.keydownListenerCapture}),ee.keydownHandlerAdded=!1),e.parentNode&&!document.body.getAttribute("data-swal2-queue-step")&&e.parentNode.removeChild(e),U()&&(null!==tt.previousBodyPadding&&(document.body.style.paddingRight="".concat(tt.previousBodyPadding,"px"),tt.previousBodyPadding=null),F(document.body,$.iosfix)&&(e=parseInt(document.body.style.top,10),bt(document.body,$.iosfix),document.body.style.top="",document.body.scrollTop=-1*e),"undefined"!=typeof window&&he()&&window.removeEventListener("resize",ge),g(document.body.children).forEach(function(t){t.hasAttribute("data-previous-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-previous-aria-hidden")),t.removeAttribute("data-previous-aria-hidden")):t.removeAttribute("aria-hidden")})),bt([document.documentElement,document.body],[$.shown,$["height-auto"],$["no-backdrop"],$["toast-shown"],$["toast-column"]])}function xe(t){var e,n,o,i=x();i&&(t=Be(t),(e=Tt.innerParams.get(this))&&!F(i,e.hideClass.popup)&&(n=ke.swalPromiseResolve.get(this),bt(i,e.showClass.popup),vt(i,e.hideClass.popup),o=k(),bt(o,e.showClass.backdrop),vt(o,e.hideClass.backdrop),Pe(this,i,e),n(t)))}function Be(t){return void 0===t?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:s({isConfirmed:!1,isDenied:!1,isDismissed:!1},t)}function Pe(t,e,n){var o=k(),i=Bt&&lt(e),r=n.onClose,a=n.onAfterClose,c=n.willClose,n=n.didClose;Ee(e,c,r),i?Se(t,e,o,n||a):Ae(t,o,G(),n||a)}var Ee=function(t,e,n){null!==e&&"function"==typeof e?e(t):null!==n&&"function"==typeof n&&n(t)},Se=function(t,e,n,o){ee.swalCloseEventFinishedCallback=Ae.bind(null,t,n,G(),o),e.addEventListener(Bt,function(t){t.target===e&&(ee.swalCloseEventFinishedCallback(),delete ee.swalCloseEventFinishedCallback)})},Oe=function(t,e){setTimeout(function(){"function"==typeof e&&e(),t._destroy()})};function Te(t,e,n){var o=Tt.domCache.get(t);e.forEach(function(t){o[t].disabled=n})}function Le(t,e){if(!t)return!1;if("radio"===t.type)for(var n=t.parentNode.parentNode.querySelectorAll("input"),o=0;o<n.length;o++)n[o].disabled=e;else t.disabled=e}var qe=function(){function n(t,e){a(this,n),this.callback=t,this.remaining=e,this.running=!1,this.start()}return c(n,[{key:"start",value:function(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}},{key:"stop",value:function(){return this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date-this.started),this.remaining}},{key:"increase",value:function(t){var e=this.running;return e&&this.stop(),this.remaining+=t,e&&this.start(),this.remaining}},{key:"getTimerLeft",value:function(){return this.running&&(this.stop(),this.start()),this.remaining}},{key:"isRunning",value:function(){return this.running}}]),n}(),De={email:function(t,e){return/^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(t)?Promise.resolve():Promise.resolve(e||"Invalid email address")},url:function(t,e){return/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(t)?Promise.resolve():Promise.resolve(e||"Invalid URL")}};function je(t){var e,n;(e=t).inputValidator||Object.keys(De).forEach(function(t){e.input===t&&(e.inputValidator=De[t])}),t.showLoaderOnConfirm&&!t.preConfirm&&W("showLoaderOnConfirm is set to true, but preConfirm is not defined.\nshowLoaderOnConfirm should be used together with preConfirm, see usage example:\nhttps://sweetalert2.github.io/#ajax-request"),t.animation=Z(t.animation),(n=t).target&&("string"!=typeof n.target||document.querySelector(n.target))&&("string"==typeof n.target||n.target.appendChild)||(W('Target parameter is not valid, defaulting to "body"'),n.target="body"),"string"==typeof t.title&&(t.title=t.title.split("\n").join("<br />")),kt(t)}function Ie(t){var e=k(),n=x();"function"==typeof t.willOpen?t.willOpen(n):"function"==typeof t.onBeforeOpen&&t.onBeforeOpen(n);var o=window.getComputedStyle(document.body).overflowY;$e(e,n,t),setTimeout(function(){Qe(e,n)},10),U()&&(Je(e,t.scrollbarPadding,o),g(document.body.children).forEach(function(t){t===k()||function(t,e){if("function"==typeof t.contains)return t.contains(e)}(t,k())||(t.hasAttribute("aria-hidden")&&t.setAttribute("data-previous-aria-hidden",t.getAttribute("aria-hidden")),t.setAttribute("aria-hidden","true"))})),G()||ee.previousActiveElement||(ee.previousActiveElement=document.activeElement),Ze(n,t),bt(e,$["no-transition"])}function Me(t){var e=x();t.target===e&&(t=k(),e.removeEventListener(Bt,Me),t.style.overflowY="auto")}function He(t,e){t.closePopup({isConfirmed:!0,value:e})}function Ve(t,e,n){var o=N();if(o.length)return(e+=n)===o.length?e=0:-1===e&&(e=o.length-1),o[e].focus();x().focus()}var Re=["swal-title","swal-html","swal-footer"],Ne=function(t){var n={};return g(t.querySelectorAll("swal-param")).forEach(function(t){Ye(t,["name","value"]);var e=t.getAttribute("name"),t=t.getAttribute("value");"boolean"==typeof se[e]&&"false"===t&&(t=!1),"object"===r(se[e])&&(t=JSON.parse(t)),n[e]=t}),n},Ue=function(t){var n={};return g(t.querySelectorAll("swal-button")).forEach(function(t){Ye(t,["type","color","aria-label"]);var e=t.getAttribute("type");n["".concat(e,"ButtonText")]=t.innerHTML,n["show".concat(m(e),"Button")]=!0,t.hasAttribute("color")&&(n["".concat(e,"ButtonColor")]=t.getAttribute("color")),t.hasAttribute("aria-label")&&(n["".concat(e,"ButtonAriaLabel")]=t.getAttribute("aria-label"))}),n},_e=function(t){var e={},t=t.querySelector("swal-image");return t&&(Ye(t,["src","width","height","alt"]),t.hasAttribute("src")&&(e.imageUrl=t.getAttribute("src")),t.hasAttribute("width")&&(e.imageWidth=t.getAttribute("width")),t.hasAttribute("height")&&(e.imageHeight=t.getAttribute("height")),t.hasAttribute("alt")&&(e.imageAlt=t.getAttribute("alt"))),e},Fe=function(t){var e={},t=t.querySelector("swal-icon");return t&&(Ye(t,["type","color"]),t.hasAttribute("type")&&(e.icon=t.getAttribute("type")),t.hasAttribute("color")&&(e.iconColor=t.getAttribute("color")),e.iconHtml=t.innerHTML),e},ze=function(t){var n={},e=t.querySelector("swal-input");e&&(Ye(e,["type","label","placeholder","value"]),n.input=e.getAttribute("type")||"text",e.hasAttribute("label")&&(n.inputLabel=e.getAttribute("label")),e.hasAttribute("placeholder")&&(n.inputPlaceholder=e.getAttribute("placeholder")),e.hasAttribute("value")&&(n.inputValue=e.getAttribute("value")));t=t.querySelectorAll("swal-input-option");return t.length&&(n.inputOptions={},g(t).forEach(function(t){Ye(t,["value"]);var e=t.getAttribute("value"),t=t.innerHTML;n.inputOptions[e]=t})),n},We=function(t,e){var n,o={};for(n in e){var i=e[n],r=t.querySelector(i);r&&(Ye(r,[]),o[i.replace(/^swal-/,"")]=r.innerHTML)}return o},Ke=function(t){var e=Re.concat(["swal-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);g(t.children).forEach(function(t){t=t.tagName.toLowerCase();-1===e.indexOf(t)&&W("Unrecognized element <".concat(t,">"))})},Ye=function(e,n){g(e.attributes).forEach(function(t){-1===n.indexOf(t.name)&&W(['Unrecognized attribute "'.concat(t.name,'" on <').concat(e.tagName.toLowerCase(),">."),"".concat(n.length?"Allowed attributes are: ".concat(n.join(", ")):"To set the value, use HTML within the element.")])})},Ze=function(t,e){"function"==typeof e.didOpen?setTimeout(function(){return e.didOpen(t)}):"function"==typeof e.onOpen&&setTimeout(function(){return e.onOpen(t)})},Qe=function(t,e){Bt&&lt(e)?(t.style.overflowY="hidden",e.addEventListener(Bt,Me)):t.style.overflowY="auto"},Je=function(t,e,n){var o;(/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream||"MacIntel"===navigator.platform&&1<navigator.maxTouchPoints)&&!F(document.body,$.iosfix)&&(o=document.body.scrollTop,document.body.style.top="".concat(-1*o,"px"),vt(document.body,$.iosfix),be(),ve()),"undefined"!=typeof window&&he()&&(ge(),window.addEventListener("resize",ge)),e&&"hidden"!==n&&me(),setTimeout(function(){t.scrollTop=0})},$e=function(t,e,n){vt(t,n.showClass.backdrop),e.style.setProperty("opacity","0","important"),rt(e),setTimeout(function(){vt(e,n.showClass.popup),e.style.removeProperty("opacity")},10),vt([document.documentElement,document.body],$.shown),n.heightAuto&&n.backdrop&&!n.toast&&vt([document.documentElement,document.body],$["height-auto"])},Xe=function(t){return t.checked?1:0},Ge=function(t){return t.checked?t.value:null},tn=function(t){return t.files.length?null!==t.getAttribute("multiple")?t.files:t.files[0]:null},en=function(e,n){function o(t){return on[n.input](i,rn(t),n)}var i=E();b(n.inputOptions)||w(n.inputOptions)?($t(),y(n.inputOptions).then(function(t){e.hideLoading(),o(t)})):"object"===r(n.inputOptions)?o(n.inputOptions):K("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(r(n.inputOptions)))},nn=function(e,n){var o=e.getInput();at(o),y(n.inputValue).then(function(t){o.value="number"===n.input?parseFloat(t)||0:"".concat(t),rt(o),o.focus(),e.hideLoading()}).catch(function(t){K("Error in inputValue promise: ".concat(t)),o.value="",rt(o),o.focus(),e.hideLoading()})},on={select:function(t,e,i){function o(t,e,n){var o=document.createElement("option");o.value=n,_(o,e),o.selected=an(n,i.inputValue),t.appendChild(o)}var r=yt(t,$.select);e.forEach(function(t){var e,n=t[0],t=t[1];Array.isArray(t)?((e=document.createElement("optgroup")).label=n,e.disabled=!1,r.appendChild(e),t.forEach(function(t){return o(e,t[1],t[0])})):o(r,t,n)}),r.focus()},radio:function(t,e,i){var r=yt(t,$.radio);e.forEach(function(t){var e=t[0],n=t[1],o=document.createElement("input"),t=document.createElement("label");o.type="radio",o.name=$.radio,o.value=e,an(e,i.inputValue)&&(o.checked=!0);e=document.createElement("span");_(e,n),e.className=$.label,t.appendChild(o),t.appendChild(e),r.appendChild(t)});e=r.querySelectorAll("input");e.length&&e[0].focus()}},rn=function n(o){var i=[];return"undefined"!=typeof Map&&o instanceof Map?o.forEach(function(t,e){"object"===r(t)&&(t=n(t)),i.push([e,t])}):Object.keys(o).forEach(function(t){var e=o[t];"object"===r(e)&&(e=n(e)),i.push([t,e])}),i},an=function(t,e){return e&&e.toString()===t.toString()},cn=function(t,e,n){var o=function(t,e){var n=t.getInput();if(!n)return null;switch(e.input){case"checkbox":return Xe(n);case"radio":return Ge(n);case"file":return tn(n);default:return e.inputAutoTrim?n.value.trim():n.value}}(t,e);e.inputValidator?sn(t,e,o):t.getInput().checkValidity()?("deny"===n?un:ln)(t,e,o):(t.enableButtons(),t.showValidationMessage(e.validationMessage))},sn=function(e,n,o){e.disableInput(),Promise.resolve().then(function(){return y(n.inputValidator(o,n.validationMessage))}).then(function(t){e.enableButtons(),e.enableInput(),t?e.showValidationMessage(t):ln(e,n,o)})},un=function(e,t,n){t.preDeny?Promise.resolve().then(function(){return y(t.preDeny(n,t.validationMessage))}).then(function(t){!1===t?e.hideLoading():e.closePopup({isDenied:!0,value:void 0===t?n:t})}):e.closePopup({isDenied:!0,value:n})},ln=function(e,t,n){t.showLoaderOnConfirm&&$t(),t.preConfirm?(e.resetValidationMessage(),Promise.resolve().then(function(){return y(t.preConfirm(n,t.validationMessage))}).then(function(t){wt(T())||!1===t?e.hideLoading():He(e,void 0===t?n:t)})):He(e,n)},dn=["ArrowRight","ArrowDown","Right","Down"],pn=["ArrowLeft","ArrowUp","Left","Up"],fn=["Escape","Esc"],mn=function(t,e,n){var o=Tt.innerParams.get(t);o.stopKeydownPropagation&&e.stopPropagation(),"Enter"===e.key?hn(t,e,o):"Tab"===e.key?gn(e,o):-1!==[].concat(dn,pn).indexOf(e.key)?vn(e.key):-1!==fn.indexOf(e.key)&&bn(e,o,n)},hn=function(t,e,n){e.isComposing||e.target&&t.getInput()&&e.target.outerHTML===t.getInput().outerHTML&&-1===["textarea","file"].indexOf(n.input)&&(_t(),e.preventDefault())},gn=function(t,e){for(var n=t.target,o=N(),i=-1,r=0;r<o.length;r++)if(n===o[r]){i=r;break}t.shiftKey?Ve(0,i,-1):Ve(0,i,1),t.stopPropagation(),t.preventDefault()},vn=function(t){-1!==[L(),q(),j()].indexOf(document.activeElement)&&(t=-1!==dn.indexOf(t)?"nextElementSibling":"previousElementSibling",(t=document.activeElement[t])&&t.focus())},bn=function(t,e,n){Z(e.allowEscapeKey)&&(t.preventDefault(),n(Q.esc))},yn=function(e,t,n){t.popup.onclick=function(){var t=Tt.innerParams.get(e);t.showConfirmButton||t.showDenyButton||t.showCancelButton||t.showCloseButton||t.timer||t.input||n(Q.close)}},wn=!1,Cn=function(e){e.popup.onmousedown=function(){e.container.onmouseup=function(t){e.container.onmouseup=void 0,t.target===e.container&&(wn=!0)}}},kn=function(e){e.container.onmousedown=function(){e.popup.onmouseup=function(t){e.popup.onmouseup=void 0,t.target!==e.popup&&!e.popup.contains(t.target)||(wn=!0)}}},An=function(n,o,i){o.container.onclick=function(t){var e=Tt.innerParams.get(n);wn?wn=!1:t.target===o.container&&Z(e.allowOutsideClick)&&i(Q.backdrop)}};function xn(t,e){var n=function(t){t="string"==typeof t.template?document.querySelector(t.template):t.template;if(!t)return{};t=t.content||t;return Ke(t),s(Ne(t),Ue(t),_e(t),Fe(t),ze(t),We(t,Re))}(t),o=s({},se.showClass,e.showClass,n.showClass,t.showClass),i=s({},se.hideClass,e.hideClass,n.hideClass,t.hideClass);return(n=s({},se,e,n,t)).showClass=o,n.hideClass=i,!1===t.animation&&(n.showClass={popup:"swal2-noanimation",backdrop:"swal2-noanimation"},n.hideClass={}),n}function Bn(a,c,s){return new Promise(function(t){function e(t){a.closePopup({isDismissed:!0,dismiss:t})}var n,o,i,r;ke.swalPromiseResolve.set(a,t),c.confirmButton.onclick=function(){return e=s,(t=a).disableButtons(),void(e.input?cn(t,e,"confirm"):ln(t,e,!0));var t,e},c.denyButton.onclick=function(){return e=s,(t=a).disableButtons(),void(e.returnInputValueOnDeny?cn(t,e,"deny"):un(t,e,!1));var t,e},c.cancelButton.onclick=function(){return t=e,a.disableButtons(),void t(Q.cancel);var t},c.closeButton.onclick=function(){return e(Q.close)},n=a,r=c,t=e,Tt.innerParams.get(n).toast?yn(n,r,t):(Cn(r),kn(r),An(n,r,t)),o=a,r=s,i=e,(t=ee).keydownTarget&&t.keydownHandlerAdded&&(t.keydownTarget.removeEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!1),r.toast||(t.keydownHandler=function(t){return mn(o,t,i)},t.keydownTarget=r.keydownListenerCapture?window:x(),t.keydownListenerCapture=r.keydownListenerCapture,t.keydownTarget.addEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!0),(s.toast&&(s.input||s.footer||s.showCloseButton)?vt:bt)(document.body,$["toast-column"]),r=a,"select"===(t=s).input||"radio"===t.input?en(r,t):-1!==["text","email","number","tel","textarea"].indexOf(t.input)&&(b(t.inputValue)||w(t.inputValue))&&nn(r,t),Ie(s),En(ee,s,e),Sn(c,s),setTimeout(function(){c.container.scrollTop=0})})}function Pn(t){var e={popup:x(),container:k(),content:E(),actions:I(),confirmButton:L(),denyButton:q(),cancelButton:j(),loader:D(),closeButton:R(),validationMessage:T(),progressSteps:O()};return Tt.domCache.set(t,e),e}var En=function(t,e,n){var o=V();at(o),e.timer&&(t.timeout=new qe(function(){n("timer"),delete t.timeout},e.timer),e.timerProgressBar&&(rt(o),setTimeout(function(){t.timeout&&t.timeout.running&&dt(e.timer)})))},Sn=function(t,e){if(!e.toast)return Z(e.allowEnterKey)?void(On(t,e)||Ve(0,-1,1)):Tn()},On=function(t,e){return e.focusDeny&&wt(t.denyButton)?(t.denyButton.focus(),!0):e.focusCancel&&wt(t.cancelButton)?(t.cancelButton.focus(),!0):!(!e.focusConfirm||!wt(t.confirmButton))&&(t.confirmButton.focus(),!0)},Tn=function(){document.activeElement&&"function"==typeof document.activeElement.blur&&document.activeElement.blur()};function Ln(t){"function"==typeof t.didDestroy?t.didDestroy():"function"==typeof t.onDestroy&&t.onDestroy()}function qn(t){delete t.params,delete ee.keydownHandler,delete ee.keydownTarget,jn(Tt),jn(ke)}var Dn,jn=function(t){for(var e in t)t[e]=new WeakMap},J=Object.freeze({hideLoading:fe,disableLoading:fe,getInput:function(t){var e=Tt.innerParams.get(t||this);return(t=Tt.domCache.get(t||this))?et(t.content,e.input):null},close:xe,closePopup:xe,closeModal:xe,closeToast:xe,enableButtons:function(){Te(this,["confirmButton","denyButton","cancelButton"],!1)},disableButtons:function(){Te(this,["confirmButton","denyButton","cancelButton"],!0)},enableInput:function(){return Le(this.getInput(),!1)},disableInput:function(){return Le(this.getInput(),!0)},showValidationMessage:function(t){var e=Tt.domCache.get(this),n=Tt.innerParams.get(this);_(e.validationMessage,t),e.validationMessage.className=$["validation-message"],n.customClass&&n.customClass.validationMessage&&vt(e.validationMessage,n.customClass.validationMessage),rt(e.validationMessage),(e=this.getInput())&&(e.setAttribute("aria-invalid",!0),e.setAttribute("aria-describedBy",$["validation-message"]),nt(e),vt(e,$.inputerror))},resetValidationMessage:function(){var t=Tt.domCache.get(this);t.validationMessage&&at(t.validationMessage),(t=this.getInput())&&(t.removeAttribute("aria-invalid"),t.removeAttribute("aria-describedBy"),bt(t,$.inputerror))},getProgressSteps:function(){return Tt.domCache.get(this).progressSteps},_main:function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};return ce(s({},e,t)),ee.currentInstance&&ee.currentInstance._destroy(),ee.currentInstance=this,je(t=xn(t,e)),Object.freeze(t),ee.timeout&&(ee.timeout.stop(),delete ee.timeout),clearTimeout(ee.restoreFocusTimeout),e=Pn(this),Ut(this,t),Tt.innerParams.set(this,t),Bn(this,e,t)},update:function(e){var t=x(),n=Tt.innerParams.get(this);if(!t||F(t,n.hideClass.popup))return W("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");var o={};Object.keys(e).forEach(function(t){Mn.isUpdatableParameter(t)?o[t]=e[t]:W('Invalid parameter to update: "'.concat(t,'". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js\n\nIf you think this parameter should be updatable, request it here: https://github.com/sweetalert2/sweetalert2/issues/new?template=02_feature_request.md'))}),n=s({},n,o),Ut(this,n),Tt.innerParams.set(this,n),Object.defineProperties(this,{params:{value:s({},this.params,e),writable:!1,enumerable:!0}})},_destroy:function(){var t=Tt.domCache.get(this),e=Tt.innerParams.get(this);e&&(t.popup&&ee.swalCloseEventFinishedCallback&&(ee.swalCloseEventFinishedCallback(),delete ee.swalCloseEventFinishedCallback),ee.deferDisposalTimer&&(clearTimeout(ee.deferDisposalTimer),delete ee.deferDisposalTimer),Ln(e),qn(this))}}),In=function(){function i(){if(a(this,i),"undefined"!=typeof window){"undefined"==typeof Promise&&K("This package requires a Promise library, please include a shim to enable it in this browser (See: https://github.com/sweetalert2/sweetalert2/wiki/Migration-from-SweetAlert-to-SweetAlert2#1-ie-support)"),Dn=this;for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var o=Object.freeze(this.constructor.argsToParams(e));Object.defineProperties(this,{params:{value:o,writable:!1,enumerable:!0,configurable:!0}});o=this._main(this.params);Tt.promise.set(this,o)}}return c(i,[{key:"then",value:function(t){return Tt.promise.get(this).then(t)}},{key:"finally",value:function(t){return Tt.promise.get(this).finally(t)}}]),i}();s(In.prototype,J),s(In,pe),Object.keys(J).forEach(function(t){In[t]=function(){if(Dn)return Dn[t].apply(Dn,arguments)}}),In.DismissReason=Q,In.version="10.13.1";var Mn=In;return Mn.default=Mn}),void 0!==this&&this.Sweetalert2&&(this.swal=this.sweetAlert=this.Swal=this.SweetAlert=this.Sweetalert2);
-"undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,".swal2-popup.swal2-toast{flex-direction:row;align-items:center;width:auto;padding:.625em;overflow-y:hidden;background:#fff;box-shadow:0 0 .625em #d9d9d9}.swal2-popup.swal2-toast .swal2-header{flex-direction:row;padding:0}.swal2-popup.swal2-toast .swal2-title{flex-grow:1;justify-content:flex-start;margin:0 .6em;font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{position:static;width:.8em;height:.8em;line-height:.8}.swal2-popup.swal2-toast .swal2-content{justify-content:flex-start;padding:0;font-size:1em}.swal2-popup.swal2-toast .swal2-icon{width:2em;min-width:2em;height:2em;margin:0}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:700}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{font-size:.25em}}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{flex-basis:auto!important;width:auto;height:auto;margin:0 .3125em;padding:0}.swal2-popup.swal2-toast .swal2-styled{margin:.125em .3125em;padding:.3125em .625em;font-size:1em}.swal2-popup.swal2-toast .swal2-styled:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(100,150,200,.5)}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.8em;left:-.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-toast-animate-success-line-tip .75s;animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-toast-animate-success-line-long .75s;animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{-webkit-animation:swal2-toast-show .5s;animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{-webkit-animation:swal2-toast-hide .1s forwards;animation:swal2-toast-hide .1s forwards}.swal2-container{display:flex;position:fixed;z-index:1060;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:0 0!important}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-left,.swal2-container.swal2-top-start{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-left,.swal2-container.swal2-center-start{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-left,.swal2-container.swal2-bottom-start{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-bottom-end>:first-child,.swal2-container.swal2-bottom-left>:first-child,.swal2-container.swal2-bottom-right>:first-child,.swal2-container.swal2-bottom-start>:first-child,.swal2-container.swal2-bottom>:first-child{margin-top:auto}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex!important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-bottom,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-top{align-items:center}.swal2-container.swal2-grow-column.swal2-bottom-left,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-top-start{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-bottom-right,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-top-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-no-transition{transition:none!important}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-container .swal2-modal{margin:0!important}}.swal2-popup{display:none;position:relative;box-sizing:border-box;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border:none;border-radius:5px;background:#fff;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-header{display:flex;flex-direction:column;align-items:center;padding:0 1.8em}.swal2-title{position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;margin:1.25em auto 0;padding:0 1.6em}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;box-shadow:none;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#2778c4;color:#fff;font-size:1.0625em}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#d14529;color:#fff;font-size:1.0625em}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#757575;color:#fff;font-size:1.0625em}.swal2-styled:focus{outline:0;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;height:.25em;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:1.25em auto}.swal2-close{position:absolute;z-index:2;top:0;right:0;align-items:center;justify-content:center;width:1.2em;height:1.2em;padding:0;overflow:hidden;transition:color .1s ease-out;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer}.swal2-close:hover{transform:none;background:0 0;color:#f27474}.swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-content{z-index:1;justify-content:center;margin:0;padding:0 1.6em;color:#545454;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word}.swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em auto}.swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;background:inherit;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);color:inherit;font-size:1.125em}.swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}.swal2-file:-ms-input-placeholder,.swal2-input:-ms-input-placeholder,.swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em auto;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-input[type=number]{max-width:10em}.swal2-file{background:inherit;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:inherit;color:inherit;font-size:1.125em}.swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-checkbox input,.swal2-radio input{margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto}.swal2-validation-message{display:none;align-items:center;justify-content:center;margin:0 -2.7em;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.swal2-validation-message::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:.25em solid transparent;border-radius:50%;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:0 0 1.25em;padding:0;background:inherit;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{right:auto;left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@-webkit-keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@-webkit-keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@-webkit-keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@-webkit-keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@-webkit-keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{top:auto;right:auto;bottom:auto;left:auto;max-width:calc(100% - .625em * 2);background-color:transparent!important}body.swal2-no-backdrop .swal2-container>.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-container.swal2-top{top:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-top-left,body.swal2-no-backdrop .swal2-container.swal2-top-start{top:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-top-end,body.swal2-no-backdrop .swal2-container.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-container.swal2-center{top:50%;left:50%;transform:translate(-50%,-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-left,body.swal2-no-backdrop .swal2-container.swal2-center-start{top:50%;left:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-end,body.swal2-no-backdrop .swal2-container.swal2-center-right{top:50%;right:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom{bottom:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom-left,body.swal2-no-backdrop .swal2-container.swal2-bottom-start{bottom:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-bottom-end,body.swal2-no-backdrop .swal2-container.swal2-bottom-right{right:0;bottom:0}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{background-color:transparent}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}body.swal2-toast-column .swal2-toast{flex-direction:column;align-items:stretch}body.swal2-toast-column .swal2-toast .swal2-actions{flex:1;align-self:stretch;height:2.2em;margin-top:.3125em}body.swal2-toast-column .swal2-toast .swal2-loading{justify-content:center}body.swal2-toast-column .swal2-toast .swal2-input{height:2em;margin:.3125em auto;font-size:1em}body.swal2-toast-column .swal2-toast .swal2-validation-message{font-size:1em}");
\ No newline at end of file
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sweetalert2=e()}(this,function(){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function c(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}function s(){return(s=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function u(t){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function l(t,e){return(l=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function d(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}function i(t,e,n){return(i=d()?Reflect.construct:function(t,e,n){var o=[null];o.push.apply(o,e);o=new(Function.bind.apply(t,o));return n&&l(o,n.prototype),o}).apply(null,arguments)}function p(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function f(t,e,n){return(f="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){t=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=u(t)););return t}(t,e);if(t){e=Object.getOwnPropertyDescriptor(t,e);return e.get?e.get.call(n):e.value}})(t,e,n||t)}function m(t){return t.charAt(0).toUpperCase()+t.slice(1)}function h(e){return Object.keys(e).map(function(t){return e[t]})}function g(t){return Array.prototype.slice.call(t)}function v(t,e){e='"'.concat(t,'" is deprecated and will be removed in the next major release. Please use "').concat(e,'" instead.'),-1===Y.indexOf(e)&&(Y.push(e),W(e))}function b(t){return t&&"function"==typeof t.toPromise}function y(t){return b(t)?t.toPromise():Promise.resolve(t)}function w(t){return t&&Promise.resolve(t)===t}function C(t){return t instanceof Element||"object"===r(t=t)&&t.jquery}function k(){return document.body.querySelector(".".concat($.container))}function A(t){var e=k();return e?e.querySelector(t):null}function t(t){return A(".".concat(t))}function x(){return t($.popup)}function n(){var t=x();return g(t.querySelectorAll(".".concat($.icon)))}function B(){var t=n().filter(function(t){return"none"!==t.style.display});return t.length?t[0]:null}function P(){return t($.title)}function E(){return t($.content)}function O(){return t($.image)}function S(){return t($["progress-steps"])}function T(){return t($["validation-message"])}function L(){return A(".".concat($.actions," .").concat($.confirm))}function q(){return A(".".concat($.actions," .").concat($.deny))}function D(){return A(".".concat($.loader))}function j(){return A(".".concat($.actions," .").concat($.cancel))}function I(){return t($.actions)}function M(){return t($.header)}function H(){return t($.footer)}function V(){return t($["timer-progress-bar"])}function R(){return t($.close)}function N(){var t=g(x().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')).sort(function(t,e){return t=parseInt(t.getAttribute("tabindex")),(e=parseInt(e.getAttribute("tabindex")))<t?1:t<e?-1:0}),e=g(x().querySelectorAll('\n  a[href],\n  area[href],\n  input:not([disabled]),\n  select:not([disabled]),\n  textarea:not([disabled]),\n  button:not([disabled]),\n  iframe,\n  object,\n  embed,\n  [tabindex="0"],\n  [contenteditable],\n  audio[controls],\n  video[controls],\n  summary\n')).filter(function(t){return"-1"!==t.getAttribute("tabindex")});return function(t){for(var e=[],n=0;n<t.length;n++)-1===e.indexOf(t[n])&&e.push(t[n]);return e}(t.concat(e)).filter(function(t){return wt(t)})}function U(){return!G()&&!document.body.classList.contains($["no-backdrop"])}function _(e,t){e.textContent="",t&&(t=(new DOMParser).parseFromString(t,"text/html"),g(t.querySelector("head").childNodes).forEach(function(t){e.appendChild(t)}),g(t.querySelector("body").childNodes).forEach(function(t){e.appendChild(t)}))}function F(t,e){if(e){for(var n=e.split(/\s+/),o=0;o<n.length;o++)if(!t.classList.contains(n[o]))return;return 1}}function z(t,e,n){var o,i;if(i=e,g((o=t).classList).forEach(function(t){-1===h($).indexOf(t)&&-1===h(X).indexOf(t)&&-1===h(i.showClass).indexOf(t)&&o.classList.remove(t)}),e.customClass&&e.customClass[n]){if("string"!=typeof e.customClass[n]&&!e.customClass[n].forEach)return W("Invalid type of customClass.".concat(n,'! Expected string or iterable object, got "').concat(r(e.customClass[n]),'"'));vt(t,e.customClass[n])}}var e="SweetAlert2:",W=function(t){console.warn("".concat(e," ").concat("object"===r(t)?t.join(" "):t))},K=function(t){console.error("".concat(e," ").concat(t))},Y=[],Z=function(t){return"function"==typeof t?t():t},Q=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),J=function(t){var e,n={};for(e in t)n[t[e]]="swal2-"+t[e];return n},$=J(["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","toast-column","show","hide","close","title","header","content","html-container","actions","confirm","deny","cancel","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error"]),X=J(["success","warning","info","question","error"]),G=function(){return document.body.classList.contains($["toast-shown"])},tt={previousBodyPadding:null};function et(t,e){if(!e)return null;switch(e){case"select":case"textarea":case"file":return yt(t,$[e]);case"checkbox":return t.querySelector(".".concat($.checkbox," input"));case"radio":return t.querySelector(".".concat($.radio," input:checked"))||t.querySelector(".".concat($.radio," input:first-child"));case"range":return t.querySelector(".".concat($.range," input"));default:return yt(t,$.input)}}function nt(t){var e;t.focus(),"file"!==t.type&&(e=t.value,t.value="",t.value=e)}function ot(t,e,n){t&&e&&("string"==typeof e&&(e=e.split(/\s+/).filter(Boolean)),e.forEach(function(e){t.forEach?t.forEach(function(t){n?t.classList.add(e):t.classList.remove(e)}):n?t.classList.add(e):t.classList.remove(e)}))}function it(t,e,n){n==="".concat(parseInt(n))&&(n=parseInt(n)),n||0===parseInt(n)?t.style[e]="number"==typeof n?"".concat(n,"px"):n:t.style.removeProperty(e)}function rt(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"flex";t.style.display=e}function at(t){t.style.display="none"}function ct(t,e,n,o){(e=t.querySelector(e))&&(e.style[n]=o)}function st(t,e,n){e?rt(t,n):at(t)}function ut(t){return!!(t.scrollHeight>t.clientHeight)}function lt(t){var e=window.getComputedStyle(t),t=parseFloat(e.getPropertyValue("animation-duration")||"0"),e=parseFloat(e.getPropertyValue("transition-duration")||"0");return 0<t||0<e}function dt(t){var e=1<arguments.length&&void 0!==arguments[1]&&arguments[1],n=V();wt(n)&&(e&&(n.style.transition="none",n.style.width="100%"),setTimeout(function(){n.style.transition="width ".concat(t/1e3,"s linear"),n.style.width="0%"},10))}function pt(){return"undefined"==typeof window||"undefined"==typeof document}function ft(t){Mn.isVisible()&&gt!==t.target.value&&Mn.resetValidationMessage(),gt=t.target.value}function mt(t,e){t instanceof HTMLElement?e.appendChild(t):"object"===r(t)?At(t,e):t&&_(e,t)}function ht(t,e){var n,o,i,r,a=I(),c=D(),s=L(),u=q(),l=j();e.showConfirmButton||e.showDenyButton||e.showCancelButton||at(a),z(a,e,"actions"),Pt(s,"confirm",e),Pt(u,"deny",e),Pt(l,"cancel",e),n=s,o=u,i=l,(r=e).buttonsStyling?(vt([n,o,i],$.styled),r.confirmButtonColor&&(n.style.backgroundColor=r.confirmButtonColor),r.denyButtonColor&&(o.style.backgroundColor=r.denyButtonColor),r.cancelButtonColor&&(i.style.backgroundColor=r.cancelButtonColor)):bt([n,o,i],$.styled),e.reverseButtons&&(a.insertBefore(l,c),a.insertBefore(u,c),a.insertBefore(s,c)),_(c,e.loaderHtml),z(c,e,"loader")}var gt,vt=function(t,e){ot(t,e,!0)},bt=function(t,e){ot(t,e,!1)},yt=function(t,e){for(var n=0;n<t.childNodes.length;n++)if(F(t.childNodes[n],e))return t.childNodes[n]},wt=function(t){return!(!t||!(t.offsetWidth||t.offsetHeight||t.getClientRects().length))},Ct='\n <div aria-labelledby="'.concat($.title,'" aria-describedby="').concat($.content,'" class="').concat($.popup,'" tabindex="-1">\n   <div class="').concat($.header,'">\n     <ul class="').concat($["progress-steps"],'"></ul>\n     <div class="').concat($.icon," ").concat(X.error,'"></div>\n     <div class="').concat($.icon," ").concat(X.question,'"></div>\n     <div class="').concat($.icon," ").concat(X.warning,'"></div>\n     <div class="').concat($.icon," ").concat(X.info,'"></div>\n     <div class="').concat($.icon," ").concat(X.success,'"></div>\n     <img class="').concat($.image,'" />\n     <h2 class="').concat($.title,'" id="').concat($.title,'"></h2>\n     <button type="button" class="').concat($.close,'"></button>\n   </div>\n   <div class="').concat($.content,'">\n     <div id="').concat($.content,'" class="').concat($["html-container"],'"></div>\n     <input class="').concat($.input,'" />\n     <input type="file" class="').concat($.file,'" />\n     <div class="').concat($.range,'">\n       <input type="range" />\n       <output></output>\n     </div>\n     <select class="').concat($.select,'"></select>\n     <div class="').concat($.radio,'"></div>\n     <label for="').concat($.checkbox,'" class="').concat($.checkbox,'">\n       <input type="checkbox" />\n       <span class="').concat($.label,'"></span>\n     </label>\n     <textarea class="').concat($.textarea,'"></textarea>\n     <div class="').concat($["validation-message"],'" id="').concat($["validation-message"],'"></div>\n   </div>\n   <div class="').concat($.actions,'">\n     <div class="').concat($.loader,'"></div>\n     <button type="button" class="').concat($.confirm,'"></button>\n     <button type="button" class="').concat($.deny,'"></button>\n     <button type="button" class="').concat($.cancel,'"></button>\n   </div>\n   <div class="').concat($.footer,'"></div>\n   <div class="').concat($["timer-progress-bar-container"],'">\n     <div class="').concat($["timer-progress-bar"],'"></div>\n   </div>\n </div>\n').replace(/(^|\n)\s*/g,""),kt=function(t){var e,n,o,i,r,a=!!(i=k())&&(i.parentNode.removeChild(i),bt([document.documentElement,document.body],[$["no-backdrop"],$["toast-shown"],$["has-column"]]),!0);pt()?K("SweetAlert2 requires document to initialize"):((r=document.createElement("div")).className=$.container,a&&vt(r,$["no-transition"]),_(r,Ct),(i="string"==typeof(e=t.target)?document.querySelector(e):e).appendChild(r),a=t,(e=x()).setAttribute("role",a.toast?"alert":"dialog"),e.setAttribute("aria-live",a.toast?"polite":"assertive"),a.toast||e.setAttribute("aria-modal","true"),r=i,"rtl"===window.getComputedStyle(r).direction&&vt(k(),$.rtl),t=E(),a=yt(t,$.input),e=yt(t,$.file),n=t.querySelector(".".concat($.range," input")),o=t.querySelector(".".concat($.range," output")),i=yt(t,$.select),r=t.querySelector(".".concat($.checkbox," input")),t=yt(t,$.textarea),a.oninput=ft,e.onchange=ft,i.onchange=ft,r.onchange=ft,t.oninput=ft,n.oninput=function(t){ft(t),o.value=n.value},n.onchange=function(t){ft(t),n.nextSibling.value=n.value})},At=function(t,e){t.jquery?xt(e,t):_(e,t.toString())},xt=function(t,e){if(t.textContent="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0))},Bt=function(){if(pt())return!1;var t,e=document.createElement("div"),n={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",animation:"animationend"};for(t in n)if(Object.prototype.hasOwnProperty.call(n,t)&&void 0!==e.style[t])return n[t];return!1}();function Pt(t,e,n){st(t,n["show".concat(m(e),"Button")],"inline-block"),_(t,n["".concat(e,"ButtonText")]),t.setAttribute("aria-label",n["".concat(e,"ButtonAriaLabel")]),t.className=$[e],z(t,n,"".concat(e,"Button")),vt(t,n["".concat(e,"ButtonClass")])}function Et(t,e){var n,o,i=k();i&&(o=i,"string"==typeof(n=e.backdrop)?o.style.background=n:n||vt([document.documentElement,document.body],$["no-backdrop"]),!e.backdrop&&e.allowOutsideClick&&W('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),o=i,(n=e.position)in $?vt(o,$[n]):(W('The "position" parameter is not valid, defaulting to "center"'),vt(o,$.center)),n=i,!(o=e.grow)||"string"!=typeof o||(o="grow-".concat(o))in $&&vt(n,$[o]),z(i,e,"container"),(e=document.body.getAttribute("data-swal2-queue-step"))&&(i.setAttribute("data-queue-step",e),document.body.removeAttribute("data-swal2-queue-step")))}function Ot(t,e){t.placeholder&&!e.inputPlaceholder||(t.placeholder=e.inputPlaceholder)}function St(t,e,n){var o,i;n.inputLabel&&(t.id=$.input,o=document.createElement("label"),i=$["input-label"],o.setAttribute("for",t.id),o.className=i,vt(o,n.customClass.inputLabel),o.innerText=n.inputLabel,e.insertAdjacentElement("beforebegin",o))}var Tt={promise:new WeakMap,innerParams:new WeakMap,domCache:new WeakMap},Lt=["input","file","range","select","radio","checkbox","textarea"],qt=function(t){if(!Mt[t.input])return K('Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "'.concat(t.input,'"'));var e=It(t.input),n=Mt[t.input](e,t);rt(n),setTimeout(function(){nt(n)})},Dt=function(t,e){var n=et(E(),t);if(n)for(var o in!function(t){for(var e=0;e<t.attributes.length;e++){var n=t.attributes[e].name;-1===["type","value","style"].indexOf(n)&&t.removeAttribute(n)}}(n),e)"range"===t&&"placeholder"===o||n.setAttribute(o,e[o])},jt=function(t){var e=It(t.input);t.customClass&&vt(e,t.customClass.input)},It=function(t){t=$[t]||$.input;return yt(E(),t)},Mt={};Mt.text=Mt.email=Mt.password=Mt.number=Mt.tel=Mt.url=function(t,e){return"string"==typeof e.inputValue||"number"==typeof e.inputValue?t.value=e.inputValue:w(e.inputValue)||W('Unexpected type of inputValue! Expected "string", "number" or "Promise", got "'.concat(r(e.inputValue),'"')),St(t,t,e),Ot(t,e),t.type=e.input,t},Mt.file=function(t,e){return St(t,t,e),Ot(t,e),t},Mt.range=function(t,e){var n=t.querySelector("input"),o=t.querySelector("output");return n.value=e.inputValue,n.type=e.input,o.value=e.inputValue,St(n,t,e),t},Mt.select=function(t,e){var n;return t.textContent="",e.inputPlaceholder&&(n=document.createElement("option"),_(n,e.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,t.appendChild(n)),St(t,t,e),t},Mt.radio=function(t){return t.textContent="",t},Mt.checkbox=function(t,e){var n=et(E(),"checkbox");n.value=1,n.id=$.checkbox,n.checked=Boolean(e.inputValue);n=t.querySelector("span");return _(n,e.inputPlaceholder),t},Mt.textarea=function(e,t){e.value=t.inputValue,Ot(e,t),St(e,e,t);function n(t){return parseInt(window.getComputedStyle(t).paddingLeft)+parseInt(window.getComputedStyle(t).paddingRight)}var o;return"MutationObserver"in window&&(o=parseInt(window.getComputedStyle(x()).width),new MutationObserver(function(){var t=e.offsetWidth+n(x())+n(E());x().style.width=o<t?"".concat(t,"px"):null}).observe(e,{attributes:!0,attributeFilter:["style"]})),e};function Ht(t,e){var o,i,r,n=E().querySelector("#".concat($.content));e.html?(mt(e.html,n),rt(n,"block")):e.text?(n.textContent=e.text,rt(n,"block")):at(n),t=t,o=e,i=E(),t=Tt.innerParams.get(t),r=!t||o.input!==t.input,Lt.forEach(function(t){var e=$[t],n=yt(i,e);Dt(t,o.inputAttributes),n.className=e,r&&at(n)}),o.input&&(r&&qt(o),jt(o)),z(E(),e,"content")}function Vt(){return k()&&k().getAttribute("data-queue-step")}function Rt(t,o){var i=S();if(!o.progressSteps||0===o.progressSteps.length)return at(i),0;rt(i),i.textContent="";var r=parseInt(void 0===o.currentProgressStep?Vt():o.currentProgressStep);r>=o.progressSteps.length&&W("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.progressSteps.forEach(function(t,e){var n,t=(n=t,t=document.createElement("li"),vt(t,$["progress-step"]),_(t,n),t);i.appendChild(t),e===r&&vt(t,$["active-progress-step"]),e!==o.progressSteps.length-1&&(t=o,e=document.createElement("li"),vt(e,$["progress-step-line"]),t.progressStepsDistance&&(e.style.width=t.progressStepsDistance),e=e,i.appendChild(e))})}function Nt(t,e){var n=M();z(n,e,"header"),Rt(0,e),n=t,t=e,(n=Tt.innerParams.get(n))&&t.icon===n.icon&&B()?zt(B(),t):(Ft(),t.icon&&(-1!==Object.keys(X).indexOf(t.icon)?(n=A(".".concat($.icon,".").concat(X[t.icon])),rt(n),Kt(n,t),zt(n,t),vt(n,t.showClass.icon)):K('Unknown icon! Expected "success", "error", "warning", "info" or "question", got "'.concat(t.icon,'"')))),function(t){var e=O();if(!t.imageUrl)return at(e);rt(e,""),e.setAttribute("src",t.imageUrl),e.setAttribute("alt",t.imageAlt),it(e,"width",t.imageWidth),it(e,"height",t.imageHeight),e.className=$.image,z(e,t,"image")}(e),n=e,t=P(),st(t,n.title||n.titleText),n.title&&mt(n.title,t),n.titleText&&(t.innerText=n.titleText),z(t,n,"title"),n=e,e=R(),_(e,n.closeButtonHtml),z(e,n,"closeButton"),st(e,n.showCloseButton),e.setAttribute("aria-label",n.closeButtonAriaLabel)}function Ut(t,e){var n,o;o=e,n=x(),it(n,"width",o.width),it(n,"padding",o.padding),o.background&&(n.style.background=o.background),Jt(n,o),Et(0,e),Nt(t,e),Ht(t,e),ht(0,e),o=e,t=H(),st(t,o.footer),o.footer&&mt(o.footer,t),z(t,o,"footer"),"function"==typeof e.didRender?e.didRender(x()):"function"==typeof e.onRender&&e.onRender(x())}function _t(){return L()&&L().click()}var Ft=function(){for(var t=n(),e=0;e<t.length;e++)at(t[e])},zt=function(t,e){Yt(t,e),Wt(),z(t,e,"icon")},Wt=function(){for(var t=x(),e=window.getComputedStyle(t).getPropertyValue("background-color"),n=t.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix"),o=0;o<n.length;o++)n[o].style.backgroundColor=e},Kt=function(t,e){t.textContent="",e.iconHtml?_(t,Zt(e.iconHtml)):"success"===e.icon?_(t,'\n      <div class="swal2-success-circular-line-left"></div>\n      <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>\n      <div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>\n      <div class="swal2-success-circular-line-right"></div>\n    '):"error"===e.icon?_(t,'\n      <span class="swal2-x-mark">\n        <span class="swal2-x-mark-line-left"></span>\n        <span class="swal2-x-mark-line-right"></span>\n      </span>\n    '):_(t,Zt({question:"?",warning:"!",info:"i"}[e.icon]))},Yt=function(t,e){if(e.iconColor){t.style.color=e.iconColor,t.style.borderColor=e.iconColor;for(var n=0,o=[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"];n<o.length;n++)ct(t,o[n],"backgroundColor",e.iconColor);ct(t,".swal2-success-ring","borderColor",e.iconColor)}},Zt=function(t){return'<div class="'.concat($["icon-content"],'">').concat(t,"</div>")},Qt=[],Jt=function(t,e){t.className="".concat($.popup," ").concat(wt(t)?e.showClass.popup:""),e.toast?(vt([document.documentElement,document.body],$["toast-shown"]),vt(t,$.toast)):vt(t,$.modal),z(t,e,"popup"),"string"==typeof e.customClass&&vt(t,e.customClass),e.icon&&vt(t,$["icon-".concat(e.icon)])};function $t(t){var e=x();e||Mn.fire(),e=x();var n=I(),o=D();!t&&wt(L())&&(t=L()),rt(n),t&&(at(t),o.setAttribute("data-button-to-replace",t.className)),o.parentNode.insertBefore(o,t),vt([e,n],$.loading),rt(o),e.setAttribute("data-loading",!0),e.setAttribute("aria-busy",!0),e.focus()}function Xt(){return new Promise(function(t){var e=window.scrollX,n=window.scrollY;ee.restoreFocusTimeout=setTimeout(function(){ee.previousActiveElement&&ee.previousActiveElement.focus?(ee.previousActiveElement.focus(),ee.previousActiveElement=null):document.body&&document.body.focus(),t()},100),void 0!==e&&void 0!==n&&window.scrollTo(e,n)})}function Gt(){if(ee.timeout)return function(){var t=V(),e=parseInt(window.getComputedStyle(t).width);t.style.removeProperty("transition"),t.style.width="100%";var n=parseInt(window.getComputedStyle(t).width),n=parseInt(e/n*100);t.style.removeProperty("transition"),t.style.width="".concat(n,"%")}(),ee.timeout.stop()}function te(){if(ee.timeout){var t=ee.timeout.start();return dt(t),t}}var ee={},ne=!1,oe={};function ie(t){for(var e=t.target;e&&e!==document;e=e.parentNode)for(var n in oe){var o=e.getAttribute(n);if(o)return void oe[n].fire({template:o})}}function re(t){return Object.prototype.hasOwnProperty.call(se,t)}function ae(t){return le[t]}function ce(t){for(var e in t)re(o=e)||W('Unknown parameter "'.concat(o,'"')),t.toast&&(n=e,-1!==de.indexOf(n)&&W('The parameter "'.concat(n,'" is incompatible with toasts'))),ae(n=e)&&v(n,ae(n));var n,o}var se={title:"",titleText:"",text:"",html:"",footer:"",icon:void 0,iconColor:void 0,iconHtml:void 0,template:void 0,toast:!1,animation:!0,showClass:{popup:"swal2-show",backdrop:"swal2-backdrop-show",icon:"swal2-icon-show"},hideClass:{popup:"swal2-hide",backdrop:"swal2-backdrop-hide",icon:"swal2-icon-hide"},customClass:{},target:"body",backdrop:!0,heightAuto:!0,allowOutsideClick:!0,allowEscapeKey:!0,allowEnterKey:!0,stopKeydownPropagation:!0,keydownListenerCapture:!1,showConfirmButton:!0,showDenyButton:!1,showCancelButton:!1,preConfirm:void 0,preDeny:void 0,confirmButtonText:"OK",confirmButtonAriaLabel:"",confirmButtonColor:void 0,denyButtonText:"No",denyButtonAriaLabel:"",denyButtonColor:void 0,cancelButtonText:"Cancel",cancelButtonAriaLabel:"",cancelButtonColor:void 0,buttonsStyling:!0,reverseButtons:!1,focusConfirm:!0,focusDeny:!1,focusCancel:!1,showCloseButton:!1,closeButtonHtml:"&times;",closeButtonAriaLabel:"Close this dialog",loaderHtml:"",showLoaderOnConfirm:!1,showLoaderOnDeny:!1,imageUrl:void 0,imageWidth:void 0,imageHeight:void 0,imageAlt:"",timer:void 0,timerProgressBar:!1,width:void 0,padding:void 0,background:void 0,input:void 0,inputPlaceholder:"",inputLabel:"",inputValue:"",inputOptions:{},inputAutoTrim:!0,inputAttributes:{},inputValidator:void 0,returnInputValueOnDeny:!1,validationMessage:void 0,grow:!1,position:"center",progressSteps:[],currentProgressStep:void 0,progressStepsDistance:void 0,onBeforeOpen:void 0,onOpen:void 0,willOpen:void 0,didOpen:void 0,onRender:void 0,didRender:void 0,onClose:void 0,onAfterClose:void 0,willClose:void 0,didClose:void 0,onDestroy:void 0,didDestroy:void 0,scrollbarPadding:!0},ue=["allowEscapeKey","allowOutsideClick","background","buttonsStyling","cancelButtonAriaLabel","cancelButtonColor","cancelButtonText","closeButtonAriaLabel","closeButtonHtml","confirmButtonAriaLabel","confirmButtonColor","confirmButtonText","currentProgressStep","customClass","denyButtonAriaLabel","denyButtonColor","denyButtonText","didClose","didDestroy","footer","hideClass","html","icon","iconColor","imageAlt","imageHeight","imageUrl","imageWidth","onAfterClose","onClose","onDestroy","progressSteps","reverseButtons","showCancelButton","showCloseButton","showConfirmButton","showDenyButton","text","title","titleText","willClose"],le={animation:'showClass" and "hideClass',onBeforeOpen:"willOpen",onOpen:"didOpen",onRender:"didRender",onClose:"willClose",onAfterClose:"didClose",onDestroy:"didDestroy"},de=["allowOutsideClick","allowEnterKey","backdrop","focusConfirm","focusDeny","focusCancel","heightAuto","keydownListenerCapture"],pe=Object.freeze({isValidParameter:re,isUpdatableParameter:function(t){return-1!==ue.indexOf(t)},isDeprecatedParameter:ae,argsToParams:function(n){var o={};return"object"!==r(n[0])||C(n[0])?["title","html","icon"].forEach(function(t,e){e=n[e];"string"==typeof e||C(e)?o[t]=e:void 0!==e&&K("Unexpected type of ".concat(t,'! Expected "string" or "Element", got ').concat(r(e)))}):s(o,n[0]),o},isVisible:function(){return wt(x())},clickConfirm:_t,clickDeny:function(){return q()&&q().click()},clickCancel:function(){return j()&&j().click()},getContainer:k,getPopup:x,getTitle:P,getContent:E,getHtmlContainer:function(){return t($["html-container"])},getImage:O,getIcon:B,getIcons:n,getInputLabel:function(){return t($["input-label"])},getCloseButton:R,getActions:I,getConfirmButton:L,getDenyButton:q,getCancelButton:j,getLoader:D,getHeader:M,getFooter:H,getTimerProgressBar:V,getFocusableElements:N,getValidationMessage:T,isLoading:function(){return x().hasAttribute("data-loading")},fire:function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];return i(this,e)},mixin:function(r){return function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&l(t,e)}(i,t);var n,o,e=(n=i,o=d(),function(){var t,e=u(n);return p(this,o?(t=u(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments))});function i(){return a(this,i),e.apply(this,arguments)}return c(i,[{key:"_main",value:function(t,e){return f(u(i.prototype),"_main",this).call(this,t,s({},e,r))}}]),i}(this)},queue:function(t){var r=this;Qt=t;function a(t,e){Qt=[],t(e)}var c=[];return new Promise(function(i){!function e(n,o){n<Qt.length?(document.body.setAttribute("data-swal2-queue-step",n),r.fire(Qt[n]).then(function(t){void 0!==t.value?(c.push(t.value),e(n+1,o)):a(i,{dismiss:t.dismiss})})):a(i,{value:c})}(0)})},getQueueStep:Vt,insertQueueStep:function(t,e){return e&&e<Qt.length?Qt.splice(e,0,t):Qt.push(t)},deleteQueueStep:function(t){void 0!==Qt[t]&&Qt.splice(t,1)},showLoading:$t,enableLoading:$t,getTimerLeft:function(){return ee.timeout&&ee.timeout.getTimerLeft()},stopTimer:Gt,resumeTimer:te,toggleTimer:function(){var t=ee.timeout;return t&&(t.running?Gt:te)()},increaseTimer:function(t){if(ee.timeout){t=ee.timeout.increase(t);return dt(t,!0),t}},isTimerRunning:function(){return ee.timeout&&ee.timeout.isRunning()},bindClickHandler:function(){oe[0<arguments.length&&void 0!==arguments[0]?arguments[0]:"data-swal-template"]=this,ne||(document.body.addEventListener("click",ie),ne=!0)}});function fe(){var t,e;Tt.innerParams.get(this)&&(t=Tt.domCache.get(this),at(t.loader),(e=t.popup.getElementsByClassName(t.loader.getAttribute("data-button-to-replace"))).length?rt(e[0],"inline-block"):wt(L())||wt(q())||wt(j())||at(t.actions),bt([t.popup,t.actions],$.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1)}function me(){null===tt.previousBodyPadding&&document.body.scrollHeight>window.innerHeight&&(tt.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight="".concat(tt.previousBodyPadding+function(){var t=document.createElement("div");t.className=$["scrollbar-measure"],document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}(),"px"))}function he(){return!!window.MSInputMethodContext&&!!document.documentMode}function ge(){var t=k(),e=x();t.style.removeProperty("align-items"),e.offsetTop<0&&(t.style.alignItems="flex-start")}var ve=function(){navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i)||x().scrollHeight>window.innerHeight-44&&(k().style.paddingBottom="".concat(44,"px"))},be=function(){var e,t=k();t.ontouchstart=function(t){e=ye(t)},t.ontouchmove=function(t){e&&(t.preventDefault(),t.stopPropagation())}},ye=function(t){var e=t.target,n=k();return!we(t)&&!Ce(t)&&(e===n||!(ut(n)||"INPUT"===e.tagName||ut(E())&&E().contains(e)))},we=function(t){return t.touches&&t.touches.length&&"stylus"===t.touches[0].touchType},Ce=function(t){return t.touches&&1<t.touches.length},ke={swalPromiseResolve:new WeakMap};function Ae(t,e,n,o){n?Se(t,o):(Xt().then(function(){return Se(t,o)}),ee.keydownTarget.removeEventListener("keydown",ee.keydownHandler,{capture:ee.keydownListenerCapture}),ee.keydownHandlerAdded=!1),e.parentNode&&!document.body.getAttribute("data-swal2-queue-step")&&e.parentNode.removeChild(e),U()&&(null!==tt.previousBodyPadding&&(document.body.style.paddingRight="".concat(tt.previousBodyPadding,"px"),tt.previousBodyPadding=null),F(document.body,$.iosfix)&&(e=parseInt(document.body.style.top,10),bt(document.body,$.iosfix),document.body.style.top="",document.body.scrollTop=-1*e),"undefined"!=typeof window&&he()&&window.removeEventListener("resize",ge),g(document.body.children).forEach(function(t){t.hasAttribute("data-previous-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-previous-aria-hidden")),t.removeAttribute("data-previous-aria-hidden")):t.removeAttribute("aria-hidden")})),bt([document.documentElement,document.body],[$.shown,$["height-auto"],$["no-backdrop"],$["toast-shown"],$["toast-column"]])}function xe(t){var e,n,o,i=x();i&&(t=Be(t),(e=Tt.innerParams.get(this))&&!F(i,e.hideClass.popup)&&(n=ke.swalPromiseResolve.get(this),bt(i,e.showClass.popup),vt(i,e.hideClass.popup),o=k(),bt(o,e.showClass.backdrop),vt(o,e.hideClass.backdrop),Pe(this,i,e),n(t)))}function Be(t){return void 0===t?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:s({isConfirmed:!1,isDenied:!1,isDismissed:!1},t)}function Pe(t,e,n){var o=k(),i=Bt&&lt(e),r=n.onClose,a=n.onAfterClose,c=n.willClose,n=n.didClose;Ee(e,c,r),i?Oe(t,e,o,n||a):Ae(t,o,G(),n||a)}var Ee=function(t,e,n){null!==e&&"function"==typeof e?e(t):null!==n&&"function"==typeof n&&n(t)},Oe=function(t,e,n,o){ee.swalCloseEventFinishedCallback=Ae.bind(null,t,n,G(),o),e.addEventListener(Bt,function(t){t.target===e&&(ee.swalCloseEventFinishedCallback(),delete ee.swalCloseEventFinishedCallback)})},Se=function(t,e){setTimeout(function(){"function"==typeof e&&e(),t._destroy()})};function Te(t,e,n){var o=Tt.domCache.get(t);e.forEach(function(t){o[t].disabled=n})}function Le(t,e){if(!t)return!1;if("radio"===t.type)for(var n=t.parentNode.parentNode.querySelectorAll("input"),o=0;o<n.length;o++)n[o].disabled=e;else t.disabled=e}var qe=function(){function n(t,e){a(this,n),this.callback=t,this.remaining=e,this.running=!1,this.start()}return c(n,[{key:"start",value:function(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}},{key:"stop",value:function(){return this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date-this.started),this.remaining}},{key:"increase",value:function(t){var e=this.running;return e&&this.stop(),this.remaining+=t,e&&this.start(),this.remaining}},{key:"getTimerLeft",value:function(){return this.running&&(this.stop(),this.start()),this.remaining}},{key:"isRunning",value:function(){return this.running}}]),n}(),De={email:function(t,e){return/^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(t)?Promise.resolve():Promise.resolve(e||"Invalid email address")},url:function(t,e){return/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(t)?Promise.resolve():Promise.resolve(e||"Invalid URL")}};function je(t){var e,n;(e=t).inputValidator||Object.keys(De).forEach(function(t){e.input===t&&(e.inputValidator=De[t])}),t.showLoaderOnConfirm&&!t.preConfirm&&W("showLoaderOnConfirm is set to true, but preConfirm is not defined.\nshowLoaderOnConfirm should be used together with preConfirm, see usage example:\nhttps://sweetalert2.github.io/#ajax-request"),t.animation=Z(t.animation),(n=t).target&&("string"!=typeof n.target||document.querySelector(n.target))&&("string"==typeof n.target||n.target.appendChild)||(W('Target parameter is not valid, defaulting to "body"'),n.target="body"),"string"==typeof t.title&&(t.title=t.title.split("\n").join("<br />")),kt(t)}function Ie(t){var e=k(),n=x();"function"==typeof t.willOpen?t.willOpen(n):"function"==typeof t.onBeforeOpen&&t.onBeforeOpen(n);var o=window.getComputedStyle(document.body).overflowY;$e(e,n,t),setTimeout(function(){Qe(e,n)},10),U()&&(Je(e,t.scrollbarPadding,o),g(document.body.children).forEach(function(t){t===k()||function(t,e){if("function"==typeof t.contains)return t.contains(e)}(t,k())||(t.hasAttribute("aria-hidden")&&t.setAttribute("data-previous-aria-hidden",t.getAttribute("aria-hidden")),t.setAttribute("aria-hidden","true"))})),G()||ee.previousActiveElement||(ee.previousActiveElement=document.activeElement),Ze(n,t),bt(e,$["no-transition"])}function Me(t){var e=x();t.target===e&&(t=k(),e.removeEventListener(Bt,Me),t.style.overflowY="auto")}function He(t,e){t.closePopup({isConfirmed:!0,value:e})}function Ve(t,e,n){var o=N();if(o.length)return(e+=n)===o.length?e=0:-1===e&&(e=o.length-1),o[e].focus();x().focus()}var Re=["swal-title","swal-html","swal-footer"],Ne=function(t){var n={};return g(t.querySelectorAll("swal-param")).forEach(function(t){Ye(t,["name","value"]);var e=t.getAttribute("name"),t=t.getAttribute("value");"boolean"==typeof se[e]&&"false"===t&&(t=!1),"object"===r(se[e])&&(t=JSON.parse(t)),n[e]=t}),n},Ue=function(t){var n={};return g(t.querySelectorAll("swal-button")).forEach(function(t){Ye(t,["type","color","aria-label"]);var e=t.getAttribute("type");n["".concat(e,"ButtonText")]=t.innerHTML,n["show".concat(m(e),"Button")]=!0,t.hasAttribute("color")&&(n["".concat(e,"ButtonColor")]=t.getAttribute("color")),t.hasAttribute("aria-label")&&(n["".concat(e,"ButtonAriaLabel")]=t.getAttribute("aria-label"))}),n},_e=function(t){var e={},t=t.querySelector("swal-image");return t&&(Ye(t,["src","width","height","alt"]),t.hasAttribute("src")&&(e.imageUrl=t.getAttribute("src")),t.hasAttribute("width")&&(e.imageWidth=t.getAttribute("width")),t.hasAttribute("height")&&(e.imageHeight=t.getAttribute("height")),t.hasAttribute("alt")&&(e.imageAlt=t.getAttribute("alt"))),e},Fe=function(t){var e={},t=t.querySelector("swal-icon");return t&&(Ye(t,["type","color"]),t.hasAttribute("type")&&(e.icon=t.getAttribute("type")),t.hasAttribute("color")&&(e.iconColor=t.getAttribute("color")),e.iconHtml=t.innerHTML),e},ze=function(t){var n={},e=t.querySelector("swal-input");e&&(Ye(e,["type","label","placeholder","value"]),n.input=e.getAttribute("type")||"text",e.hasAttribute("label")&&(n.inputLabel=e.getAttribute("label")),e.hasAttribute("placeholder")&&(n.inputPlaceholder=e.getAttribute("placeholder")),e.hasAttribute("value")&&(n.inputValue=e.getAttribute("value")));t=t.querySelectorAll("swal-input-option");return t.length&&(n.inputOptions={},g(t).forEach(function(t){Ye(t,["value"]);var e=t.getAttribute("value"),t=t.innerHTML;n.inputOptions[e]=t})),n},We=function(t,e){var n,o={};for(n in e){var i=e[n],r=t.querySelector(i);r&&(Ye(r,[]),o[i.replace(/^swal-/,"")]=r.innerHTML)}return o},Ke=function(e){var n=Re.concat(["swal-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);g(e.querySelectorAll("*")).forEach(function(t){t.parentNode===e&&(t=t.tagName.toLowerCase(),-1===n.indexOf(t)&&W("Unrecognized element <".concat(t,">")))})},Ye=function(e,n){g(e.attributes).forEach(function(t){-1===n.indexOf(t.name)&&W(['Unrecognized attribute "'.concat(t.name,'" on <').concat(e.tagName.toLowerCase(),">."),"".concat(n.length?"Allowed attributes are: ".concat(n.join(", ")):"To set the value, use HTML within the element.")])})},Ze=function(t,e){"function"==typeof e.didOpen?setTimeout(function(){return e.didOpen(t)}):"function"==typeof e.onOpen&&setTimeout(function(){return e.onOpen(t)})},Qe=function(t,e){Bt&&lt(e)?(t.style.overflowY="hidden",e.addEventListener(Bt,Me)):t.style.overflowY="auto"},Je=function(t,e,n){var o;(/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream||"MacIntel"===navigator.platform&&1<navigator.maxTouchPoints)&&!F(document.body,$.iosfix)&&(o=document.body.scrollTop,document.body.style.top="".concat(-1*o,"px"),vt(document.body,$.iosfix),be(),ve()),"undefined"!=typeof window&&he()&&(ge(),window.addEventListener("resize",ge)),e&&"hidden"!==n&&me(),setTimeout(function(){t.scrollTop=0})},$e=function(t,e,n){vt(t,n.showClass.backdrop),e.style.setProperty("opacity","0","important"),rt(e),setTimeout(function(){vt(e,n.showClass.popup),e.style.removeProperty("opacity")},10),vt([document.documentElement,document.body],$.shown),n.heightAuto&&n.backdrop&&!n.toast&&vt([document.documentElement,document.body],$["height-auto"])},Xe=function(t){return t.checked?1:0},Ge=function(t){return t.checked?t.value:null},tn=function(t){return t.files.length?null!==t.getAttribute("multiple")?t.files:t.files[0]:null},en=function(e,n){function o(t){return on[n.input](i,rn(t),n)}var i=E();b(n.inputOptions)||w(n.inputOptions)?($t(),y(n.inputOptions).then(function(t){e.hideLoading(),o(t)})):"object"===r(n.inputOptions)?o(n.inputOptions):K("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(r(n.inputOptions)))},nn=function(e,n){var o=e.getInput();at(o),y(n.inputValue).then(function(t){o.value="number"===n.input?parseFloat(t)||0:"".concat(t),rt(o),o.focus(),e.hideLoading()}).catch(function(t){K("Error in inputValue promise: ".concat(t)),o.value="",rt(o),o.focus(),e.hideLoading()})},on={select:function(t,e,i){function o(t,e,n){var o=document.createElement("option");o.value=n,_(o,e),o.selected=an(n,i.inputValue),t.appendChild(o)}var r=yt(t,$.select);e.forEach(function(t){var e,n=t[0],t=t[1];Array.isArray(t)?((e=document.createElement("optgroup")).label=n,e.disabled=!1,r.appendChild(e),t.forEach(function(t){return o(e,t[1],t[0])})):o(r,t,n)}),r.focus()},radio:function(t,e,i){var r=yt(t,$.radio);e.forEach(function(t){var e=t[0],n=t[1],o=document.createElement("input"),t=document.createElement("label");o.type="radio",o.name=$.radio,o.value=e,an(e,i.inputValue)&&(o.checked=!0);e=document.createElement("span");_(e,n),e.className=$.label,t.appendChild(o),t.appendChild(e),r.appendChild(t)});e=r.querySelectorAll("input");e.length&&e[0].focus()}},rn=function n(o){var i=[];return"undefined"!=typeof Map&&o instanceof Map?o.forEach(function(t,e){"object"===r(t)&&(t=n(t)),i.push([e,t])}):Object.keys(o).forEach(function(t){var e=o[t];"object"===r(e)&&(e=n(e)),i.push([t,e])}),i},an=function(t,e){return e&&e.toString()===t.toString()},cn=function(t,e,n){var o=function(t,e){var n=t.getInput();if(!n)return null;switch(e.input){case"checkbox":return Xe(n);case"radio":return Ge(n);case"file":return tn(n);default:return e.inputAutoTrim?n.value.trim():n.value}}(t,e);e.inputValidator?sn(t,e,o):t.getInput().checkValidity()?("deny"===n?un:ln)(t,e,o):(t.enableButtons(),t.showValidationMessage(e.validationMessage))},sn=function(e,n,o){e.disableInput(),Promise.resolve().then(function(){return y(n.inputValidator(o,n.validationMessage))}).then(function(t){e.enableButtons(),e.enableInput(),t?e.showValidationMessage(t):ln(e,n,o)})},un=function(e,t,n){t.showLoaderOnDeny&&$t(q()),t.preDeny?Promise.resolve().then(function(){return y(t.preDeny(n,t.validationMessage))}).then(function(t){!1===t?e.hideLoading():e.closePopup({isDenied:!0,value:void 0===t?n:t})}):e.closePopup({isDenied:!0,value:n})},ln=function(e,t,n){t.showLoaderOnConfirm&&$t(),t.preConfirm?(e.resetValidationMessage(),Promise.resolve().then(function(){return y(t.preConfirm(n,t.validationMessage))}).then(function(t){wt(T())||!1===t?e.hideLoading():He(e,void 0===t?n:t)})):He(e,n)},dn=["ArrowRight","ArrowDown","Right","Down"],pn=["ArrowLeft","ArrowUp","Left","Up"],fn=["Escape","Esc"],mn=function(t,e,n){var o=Tt.innerParams.get(t);o.stopKeydownPropagation&&e.stopPropagation(),"Enter"===e.key?hn(t,e,o):"Tab"===e.key?gn(e,o):-1!==[].concat(dn,pn).indexOf(e.key)?vn(e.key):-1!==fn.indexOf(e.key)&&bn(e,o,n)},hn=function(t,e,n){e.isComposing||e.target&&t.getInput()&&e.target.outerHTML===t.getInput().outerHTML&&-1===["textarea","file"].indexOf(n.input)&&(_t(),e.preventDefault())},gn=function(t,e){for(var n=t.target,o=N(),i=-1,r=0;r<o.length;r++)if(n===o[r]){i=r;break}t.shiftKey?Ve(0,i,-1):Ve(0,i,1),t.stopPropagation(),t.preventDefault()},vn=function(t){-1!==[L(),q(),j()].indexOf(document.activeElement)&&(t=-1!==dn.indexOf(t)?"nextElementSibling":"previousElementSibling",(t=document.activeElement[t])&&t.focus())},bn=function(t,e,n){Z(e.allowEscapeKey)&&(t.preventDefault(),n(Q.esc))},yn=function(e,t,n){t.popup.onclick=function(){var t=Tt.innerParams.get(e);t.showConfirmButton||t.showDenyButton||t.showCancelButton||t.showCloseButton||t.timer||t.input||n(Q.close)}},wn=!1,Cn=function(e){e.popup.onmousedown=function(){e.container.onmouseup=function(t){e.container.onmouseup=void 0,t.target===e.container&&(wn=!0)}}},kn=function(e){e.container.onmousedown=function(){e.popup.onmouseup=function(t){e.popup.onmouseup=void 0,t.target!==e.popup&&!e.popup.contains(t.target)||(wn=!0)}}},An=function(n,o,i){o.container.onclick=function(t){var e=Tt.innerParams.get(n);wn?wn=!1:t.target===o.container&&Z(e.allowOutsideClick)&&i(Q.backdrop)}};function xn(t,e){var n=function(t){t="string"==typeof t.template?document.querySelector(t.template):t.template;if(!t)return{};t=t.content||t;return Ke(t),s(Ne(t),Ue(t),_e(t),Fe(t),ze(t),We(t,Re))}(t),o=s({},se.showClass,e.showClass,n.showClass,t.showClass),i=s({},se.hideClass,e.hideClass,n.hideClass,t.hideClass);return(n=s({},se,e,n,t)).showClass=o,n.hideClass=i,!1===t.animation&&(n.showClass={popup:"swal2-noanimation",backdrop:"swal2-noanimation"},n.hideClass={}),n}function Bn(a,c,s){return new Promise(function(t){function e(t){a.closePopup({isDismissed:!0,dismiss:t})}var n,o,i,r;ke.swalPromiseResolve.set(a,t),c.confirmButton.onclick=function(){return e=s,(t=a).disableButtons(),void(e.input?cn(t,e,"confirm"):ln(t,e,!0));var t,e},c.denyButton.onclick=function(){return e=s,(t=a).disableButtons(),void(e.returnInputValueOnDeny?cn(t,e,"deny"):un(t,e,!1));var t,e},c.cancelButton.onclick=function(){return t=e,a.disableButtons(),void t(Q.cancel);var t},c.closeButton.onclick=function(){return e(Q.close)},n=a,r=c,t=e,Tt.innerParams.get(n).toast?yn(n,r,t):(Cn(r),kn(r),An(n,r,t)),o=a,r=s,i=e,(t=ee).keydownTarget&&t.keydownHandlerAdded&&(t.keydownTarget.removeEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!1),r.toast||(t.keydownHandler=function(t){return mn(o,t,i)},t.keydownTarget=r.keydownListenerCapture?window:x(),t.keydownListenerCapture=r.keydownListenerCapture,t.keydownTarget.addEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!0),(s.toast&&(s.input||s.footer||s.showCloseButton)?vt:bt)(document.body,$["toast-column"]),r=a,"select"===(t=s).input||"radio"===t.input?en(r,t):-1!==["text","email","number","tel","textarea"].indexOf(t.input)&&(b(t.inputValue)||w(t.inputValue))&&nn(r,t),Ie(s),En(ee,s,e),On(c,s),setTimeout(function(){c.container.scrollTop=0})})}function Pn(t){var e={popup:x(),container:k(),content:E(),actions:I(),confirmButton:L(),denyButton:q(),cancelButton:j(),loader:D(),closeButton:R(),validationMessage:T(),progressSteps:S()};return Tt.domCache.set(t,e),e}var En=function(t,e,n){var o=V();at(o),e.timer&&(t.timeout=new qe(function(){n("timer"),delete t.timeout},e.timer),e.timerProgressBar&&(rt(o),setTimeout(function(){t.timeout&&t.timeout.running&&dt(e.timer)})))},On=function(t,e){if(!e.toast)return Z(e.allowEnterKey)?void(Sn(t,e)||Ve(0,-1,1)):Tn()},Sn=function(t,e){return e.focusDeny&&wt(t.denyButton)?(t.denyButton.focus(),!0):e.focusCancel&&wt(t.cancelButton)?(t.cancelButton.focus(),!0):!(!e.focusConfirm||!wt(t.confirmButton))&&(t.confirmButton.focus(),!0)},Tn=function(){document.activeElement&&"function"==typeof document.activeElement.blur&&document.activeElement.blur()};function Ln(t){"function"==typeof t.didDestroy?t.didDestroy():"function"==typeof t.onDestroy&&t.onDestroy()}function qn(t){delete t.params,delete ee.keydownHandler,delete ee.keydownTarget,jn(Tt),jn(ke)}var Dn,jn=function(t){for(var e in t)t[e]=new WeakMap},J=Object.freeze({hideLoading:fe,disableLoading:fe,getInput:function(t){var e=Tt.innerParams.get(t||this);return(t=Tt.domCache.get(t||this))?et(t.content,e.input):null},close:xe,closePopup:xe,closeModal:xe,closeToast:xe,enableButtons:function(){Te(this,["confirmButton","denyButton","cancelButton"],!1)},disableButtons:function(){Te(this,["confirmButton","denyButton","cancelButton"],!0)},enableInput:function(){return Le(this.getInput(),!1)},disableInput:function(){return Le(this.getInput(),!0)},showValidationMessage:function(t){var e=Tt.domCache.get(this),n=Tt.innerParams.get(this);_(e.validationMessage,t),e.validationMessage.className=$["validation-message"],n.customClass&&n.customClass.validationMessage&&vt(e.validationMessage,n.customClass.validationMessage),rt(e.validationMessage),(e=this.getInput())&&(e.setAttribute("aria-invalid",!0),e.setAttribute("aria-describedBy",$["validation-message"]),nt(e),vt(e,$.inputerror))},resetValidationMessage:function(){var t=Tt.domCache.get(this);t.validationMessage&&at(t.validationMessage),(t=this.getInput())&&(t.removeAttribute("aria-invalid"),t.removeAttribute("aria-describedBy"),bt(t,$.inputerror))},getProgressSteps:function(){return Tt.domCache.get(this).progressSteps},_main:function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};return ce(s({},e,t)),ee.currentInstance&&ee.currentInstance._destroy(),ee.currentInstance=this,je(t=xn(t,e)),Object.freeze(t),ee.timeout&&(ee.timeout.stop(),delete ee.timeout),clearTimeout(ee.restoreFocusTimeout),e=Pn(this),Ut(this,t),Tt.innerParams.set(this,t),Bn(this,e,t)},update:function(e){var t=x(),n=Tt.innerParams.get(this);if(!t||F(t,n.hideClass.popup))return W("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");var o={};Object.keys(e).forEach(function(t){Mn.isUpdatableParameter(t)?o[t]=e[t]:W('Invalid parameter to update: "'.concat(t,'". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js\n\nIf you think this parameter should be updatable, request it here: https://github.com/sweetalert2/sweetalert2/issues/new?template=02_feature_request.md'))}),n=s({},n,o),Ut(this,n),Tt.innerParams.set(this,n),Object.defineProperties(this,{params:{value:s({},this.params,e),writable:!1,enumerable:!0}})},_destroy:function(){var t=Tt.domCache.get(this),e=Tt.innerParams.get(this);e&&(t.popup&&ee.swalCloseEventFinishedCallback&&(ee.swalCloseEventFinishedCallback(),delete ee.swalCloseEventFinishedCallback),ee.deferDisposalTimer&&(clearTimeout(ee.deferDisposalTimer),delete ee.deferDisposalTimer),Ln(e),qn(this))}}),In=function(){function i(){if(a(this,i),"undefined"!=typeof window){"undefined"==typeof Promise&&K("This package requires a Promise library, please include a shim to enable it in this browser (See: https://github.com/sweetalert2/sweetalert2/wiki/Migration-from-SweetAlert-to-SweetAlert2#1-ie-support)"),Dn=this;for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var o=Object.freeze(this.constructor.argsToParams(e));Object.defineProperties(this,{params:{value:o,writable:!1,enumerable:!0,configurable:!0}});o=this._main(this.params);Tt.promise.set(this,o)}}return c(i,[{key:"then",value:function(t){return Tt.promise.get(this).then(t)}},{key:"finally",value:function(t){return Tt.promise.get(this).finally(t)}}]),i}();s(In.prototype,J),s(In,pe),Object.keys(J).forEach(function(t){In[t]=function(){if(Dn)return Dn[t].apply(Dn,arguments)}}),In.DismissReason=Q,In.version="10.14.1";var Mn=In;return Mn.default=Mn}),void 0!==this&&this.Sweetalert2&&(this.swal=this.sweetAlert=this.Swal=this.SweetAlert=this.Sweetalert2);
+"undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,".swal2-popup.swal2-toast{flex-direction:row;align-items:center;width:auto;padding:.625em;overflow-y:hidden;background:#fff;box-shadow:0 0 .625em #d9d9d9}.swal2-popup.swal2-toast .swal2-header{flex-direction:row;padding:0}.swal2-popup.swal2-toast .swal2-title{flex-grow:1;justify-content:flex-start;margin:0 .6em;font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{position:static;width:.8em;height:.8em;line-height:.8}.swal2-popup.swal2-toast .swal2-content{justify-content:flex-start;padding:0;font-size:1em}.swal2-popup.swal2-toast .swal2-icon{width:2em;min-width:2em;height:2em;margin:0}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:700}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{font-size:.25em}}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{flex-basis:auto!important;width:auto;height:auto;margin:0 .3125em;padding:0}.swal2-popup.swal2-toast .swal2-styled{margin:.125em .3125em;padding:.3125em .625em;font-size:1em}.swal2-popup.swal2-toast .swal2-styled:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(100,150,200,.5)}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.8em;left:-.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-toast-animate-success-line-tip .75s;animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-toast-animate-success-line-long .75s;animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{-webkit-animation:swal2-toast-show .5s;animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{-webkit-animation:swal2-toast-hide .1s forwards;animation:swal2-toast-hide .1s forwards}.swal2-container{display:flex;position:fixed;z-index:1060;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:0 0!important}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-left,.swal2-container.swal2-top-start{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-left,.swal2-container.swal2-center-start{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-left,.swal2-container.swal2-bottom-start{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-bottom-end>:first-child,.swal2-container.swal2-bottom-left>:first-child,.swal2-container.swal2-bottom-right>:first-child,.swal2-container.swal2-bottom-start>:first-child,.swal2-container.swal2-bottom>:first-child{margin-top:auto}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex!important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-bottom,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-top{align-items:center}.swal2-container.swal2-grow-column.swal2-bottom-left,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-top-start{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-bottom-right,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-top-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-no-transition{transition:none!important}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-container .swal2-modal{margin:0!important}}.swal2-popup{display:none;position:relative;box-sizing:border-box;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border:none;border-radius:5px;background:#fff;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-header{display:flex;flex-direction:column;align-items:center;padding:0 1.8em}.swal2-title{position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;margin:1.25em auto 0;padding:0 1.6em}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;box-shadow:none;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#2778c4;color:#fff;font-size:1.0625em}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#d14529;color:#fff;font-size:1.0625em}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#757575;color:#fff;font-size:1.0625em}.swal2-styled:focus{outline:0;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;height:.25em;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:1.25em auto}.swal2-close{position:absolute;z-index:2;top:0;right:0;align-items:center;justify-content:center;width:1.2em;height:1.2em;padding:0;overflow:hidden;transition:color .1s ease-out;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer}.swal2-close:hover{transform:none;background:0 0;color:#f27474}.swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-content{z-index:1;justify-content:center;margin:0;padding:0 1.6em;color:#545454;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word}.swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em auto}.swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;background:inherit;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);color:inherit;font-size:1.125em}.swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}.swal2-file:-ms-input-placeholder,.swal2-input:-ms-input-placeholder,.swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em auto;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-input[type=number]{max-width:10em}.swal2-file{background:inherit;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:inherit;color:inherit;font-size:1.125em}.swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-checkbox input,.swal2-radio input{margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto}.swal2-validation-message{display:none;align-items:center;justify-content:center;margin:0 -2.7em;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.swal2-validation-message::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:.25em solid transparent;border-radius:50%;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1;zoom:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;zoom:1;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;zoom:1;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;zoom:1;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;zoom:1;transform:rotate(-45deg)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;zoom:1;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:0 0 1.25em;padding:0;background:inherit;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{right:auto;left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@-webkit-keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@-webkit-keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@-webkit-keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@-webkit-keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@-webkit-keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{top:auto;right:auto;bottom:auto;left:auto;max-width:calc(100% - .625em * 2);background-color:transparent!important}body.swal2-no-backdrop .swal2-container>.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-container.swal2-top{top:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-top-left,body.swal2-no-backdrop .swal2-container.swal2-top-start{top:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-top-end,body.swal2-no-backdrop .swal2-container.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-container.swal2-center{top:50%;left:50%;transform:translate(-50%,-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-left,body.swal2-no-backdrop .swal2-container.swal2-center-start{top:50%;left:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-end,body.swal2-no-backdrop .swal2-container.swal2-center-right{top:50%;right:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom{bottom:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom-left,body.swal2-no-backdrop .swal2-container.swal2-bottom-start{bottom:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-bottom-end,body.swal2-no-backdrop .swal2-container.swal2-bottom-right{right:0;bottom:0}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{background-color:transparent}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}body.swal2-toast-column .swal2-toast{flex-direction:column;align-items:stretch}body.swal2-toast-column .swal2-toast .swal2-actions{flex:1;align-self:stretch;height:2.2em;margin-top:.3125em}body.swal2-toast-column .swal2-toast .swal2-loading{justify-content:center}body.swal2-toast-column .swal2-toast .swal2-input{height:2em;margin:.3125em auto;font-size:1em}body.swal2-toast-column .swal2-toast .swal2-validation-message{font-size:1em}");
\ No newline at end of file
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 9510a2392..30fb8eafc 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -472,7 +472,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
     <!-- ./wrapper -->
 
     <!-- Scripts -->
-    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10.14.1/dist/sweetalert2.all.min.js"></script>
+    <script src="{{ asset('plugins/sweetalert2/sweetalert2.all.min.js') }}"></script>
 
     <script src="{{ asset('plugins/datatables/jquery.dataTables.min.js') }}"></script>
     <!-- Summernote -->

From 0bde32bd2fac84b315506539309d7875ce67a8c9 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 00:17:40 +0200
Subject: [PATCH 100/514] remove encryption to continue working // FIX
 INSTALLER [value] -> [payload]

---
 .../PaymentGateways/Mollie/MollieSettings.php |  7 +------
 ...23_03_26_215801_create_mollie_settings.php |  2 +-
 .../PaymentGateways/PayPal/PayPalSettings.php | 10 +---------
 ...3_03_04_135248_create_pay_pal_settings.php |  8 ++++----
 .../PaymentGateways/Stripe/StripeSettings.php | 10 +---------
 ...23_03_04_181917_create_stripe_settings.php |  8 ++++----
 app/Settings/DiscordSettings.php              |  9 +--------
 app/Settings/GeneralSettings.php              |  8 +-------
 app/Settings/MailSettings.php                 |  7 +------
 app/Settings/PterodactylSettings.php          |  8 +-------
 ...3_02_01_164731_create_general_settings.php |  4 ++--
 ..._01_181334_create_pterodactyl_settings.php |  4 ++--
 ...2023_02_01_181453_create_mail_settings.php |  2 +-
 ...3_02_01_182043_create_discord_settings.php |  6 +++---
 public/install/forms.php                      | 19 ++++++++++---------
 public/install/functions.php                  |  4 ++++
 16 files changed, 38 insertions(+), 78 deletions(-)

diff --git a/app/Extensions/PaymentGateways/Mollie/MollieSettings.php b/app/Extensions/PaymentGateways/Mollie/MollieSettings.php
index d98658f18..a551b4a52 100644
--- a/app/Extensions/PaymentGateways/Mollie/MollieSettings.php
+++ b/app/Extensions/PaymentGateways/Mollie/MollieSettings.php
@@ -15,12 +15,7 @@ public static function group(): string
         return 'mollie';
     }
 
-    public static function encrypted(): array
-    {
-        return [
-            'api_key',
-        ];
-    }
+
 
     public static function getOptionInputData()
     {
diff --git a/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php b/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php
index a3b6bfd04..b32027e30 100644
--- a/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php
+++ b/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php
@@ -6,7 +6,7 @@ class CreateMollieSettings extends SettingsMigration
 {
     public function up(): void
     {
-        $this->migrator->addEncrypted('mollie.api_key', null);
+        $this->migrator->add('mollie.api_key', null);
         $this->migrator->add('mollie.enabled', false);
     }
 
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalSettings.php b/app/Extensions/PaymentGateways/PayPal/PayPalSettings.php
index 1688c011b..9d22dec26 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalSettings.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalSettings.php
@@ -18,15 +18,7 @@ public static function group(): string
     }
 
 
-    public static function encrypted(): array
-    {
-        return [
-            'client_id',
-            'client_secret',
-            'sandbox_client_id',
-            'sandbox_client_secret'
-        ];
-    }
+
 
     /**
      * Summary of optionInputData array
diff --git a/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php b/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
index 5792abec4..9dc4887cf 100644
--- a/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
+++ b/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
@@ -11,10 +11,10 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
 
-        $this->migrator->addEncrypted('paypal.client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') : null);
-        $this->migrator->addEncrypted('paypal.client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SECRET') : null);
-        $this->migrator->addEncrypted('paypal.sandbox_client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') : null);
-        $this->migrator->addEncrypted('paypal.sandbox_client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') : null);
+        $this->migrator->add('paypal.client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') : null);
+        $this->migrator->add('paypal.client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SECRET') : null);
+        $this->migrator->add('paypal.sandbox_client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') : null);
+        $this->migrator->add('paypal.sandbox_client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') : null);
         $this->migrator->add('paypal.enabled', false);
     }
 
diff --git a/app/Extensions/PaymentGateways/Stripe/StripeSettings.php b/app/Extensions/PaymentGateways/Stripe/StripeSettings.php
index c7a2d7bd9..7cf6de5f6 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeSettings.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeSettings.php
@@ -19,15 +19,7 @@ public static function group(): string
         return 'stripe';
     }
 
-    public static function encrypted(): array
-    {
-        return [
-            "secret_key",
-            "endpoint_secret",
-            "test_secret_key",
-            "test_endpoint_secret"
-        ];
-    }
+
 
     public static function getOptionInputData()
     {
diff --git a/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php b/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
index a8145a7c8..c3588d269 100644
--- a/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
+++ b/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
@@ -9,10 +9,10 @@ public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
-        $this->migrator->addEncrypted('stripe.secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:SECRET') : null);
-        $this->migrator->addEncrypted('stripe.endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') : null);
-        $this->migrator->addEncrypted('stripe.test_secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') : null);
-        $this->migrator->addEncrypted('stripe.test_endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET') : null);
+        $this->migrator->add('stripe.secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:SECRET') : null);
+        $this->migrator->add('stripe.endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') : null);
+        $this->migrator->add('stripe.test_secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') : null);
+        $this->migrator->add('stripe.test_endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET') : null);
         $this->migrator->add('stripe.enabled', false);
     }
 
diff --git a/app/Settings/DiscordSettings.php b/app/Settings/DiscordSettings.php
index 8671fa8af..4788ae7eb 100644
--- a/app/Settings/DiscordSettings.php
+++ b/app/Settings/DiscordSettings.php
@@ -18,14 +18,7 @@ public static function group(): string
         return 'discord';
     }
 
-    public static function encrypted(): array
-    {
-        return [
-            'bot_token',
-            'client_id',
-            'client_secret'
-        ];
-    }
+
 
     /**
      * Summary of validations array
diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 02f8767f3..8aa91e222 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -24,13 +24,7 @@ public static function group(): string
         return 'general';
     }
 
-    public static function encrypted(): array
-    {
-        return [
-            'recaptcha_site_key',
-            'recaptcha_secret_key'
-        ];
-    }
+
 
     /**
      * Summary of validations array
diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php
index e94953ceb..cd70a7fa4 100644
--- a/app/Settings/MailSettings.php
+++ b/app/Settings/MailSettings.php
@@ -21,12 +21,7 @@ public static function group(): string
         return 'mail';
     }
 
-    public static function encrypted(): array
-    {
-        return [
-            'mail_password'
-        ];
-    }
+
 
     public function setConfig()
     {
diff --git a/app/Settings/PterodactylSettings.php b/app/Settings/PterodactylSettings.php
index 2267152e7..3e888b937 100644
--- a/app/Settings/PterodactylSettings.php
+++ b/app/Settings/PterodactylSettings.php
@@ -16,13 +16,7 @@ public static function group(): string
         return 'pterodactyl';
     }
 
-    public static function encrypted(): array
-    {
-        return [
-            'admin_token',
-            'user_token'
-        ];
-    }
+
 
     /**
      * Get url with ensured ending backslash
diff --git a/database/settings/2023_02_01_164731_create_general_settings.php b/database/settings/2023_02_01_164731_create_general_settings.php
index 8962889ae..5d1835907 100644
--- a/database/settings/2023_02_01_164731_create_general_settings.php
+++ b/database/settings/2023_02_01_164731_create_general_settings.php
@@ -12,8 +12,8 @@ public function up(): void
         // Get the user-set configuration values from the old table.
         $this->migrator->add('general.store_enabled',  true);
         $this->migrator->add('general.credits_display_name', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') : 'Credits');
-        $this->migrator->addEncrypted('general.recaptcha_site_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SITE_KEY") : env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'));
-        $this->migrator->addEncrypted('general.recaptcha_secret_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SECRET_KEY") : env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'));
+        $this->migrator->add('general.recaptcha_site_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SITE_KEY") : env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'));
+        $this->migrator->add('general.recaptcha_secret_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SECRET_KEY") : env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'));
         $this->migrator->add('general.recaptcha_enabled', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:ENABLED") : true);
         $this->migrator->add('general.phpmyadmin_url', $table_exists ? $this->getOldValue("SETTINGS::MISC:PHPMYADMIN:URL") : env('PHPMYADMIN_URL', ''));
         $this->migrator->add('general.alert_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_ENABLED") : false);
diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index f3b5b37d2..3de541759 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -10,8 +10,8 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
-        $this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
+        $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
+        $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
         $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL') : env('PTERODACTYL_URL', ''));
         $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT') : 200);
     }
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index 98fe06d0e..7a1717320 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -13,7 +13,7 @@ public function up(): void
         $this->migrator->add('mail.mail_host', $table_exists ? $this->getOldValue('SETTINGS::MAIL:HOST') : env('MAIL_HOST', 'localhost'));
         $this->migrator->add('mail.mail_port', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PORT') : env('MAIL_PORT', 25));
         $this->migrator->add('mail.mail_username', $table_exists ? $this->getOldValue('SETTINGS::MAIL:USERNAME') : env('MAIL_USERNAME', ''));
-        $this->migrator->addEncrypted('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
+        $this->migrator->add('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
         $this->migrator->add('mail.mail_encryption', $table_exists ? $this->getOldValue('SETTINGS::MAIL:ENCRYPTION') : env('MAIL_ENCRYPTION', 'tls'));
         $this->migrator->add('mail.mail_from_address', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_ADDRESS') : env('MAIL_FROM_ADDRESS', 'example@example.com'));
         $this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'ControlPanel.gg'));
diff --git a/database/settings/2023_02_01_182043_create_discord_settings.php b/database/settings/2023_02_01_182043_create_discord_settings.php
index 1f4335aa4..60e450b90 100644
--- a/database/settings/2023_02_01_182043_create_discord_settings.php
+++ b/database/settings/2023_02_01_182043_create_discord_settings.php
@@ -10,9 +10,9 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->addEncrypted('discord.bot_token', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:BOT_TOKEN') : '');
-        $this->migrator->addEncrypted('discord.client_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_ID') : '');
-        $this->migrator->addEncrypted('discord.client_secret', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_SECRET') : '');
+        $this->migrator->add('discord.bot_token', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:BOT_TOKEN') : '');
+        $this->migrator->add('discord.client_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_ID') : '');
+        $this->migrator->add('discord.client_secret', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_SECRET') : '');
         $this->migrator->add('discord.guild_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:GUILD_ID') : '');
         $this->migrator->add('discord.invite_url', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:INVITE_URL') : '');
         $this->migrator->add('discord.role_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:ROLE_ID') : '');
diff --git a/public/install/forms.php b/public/install/forms.php
index 9a772a57b..762222c6d 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -1,5 +1,6 @@
 <?php
 
+
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\PHPMailer;
 
@@ -32,7 +33,7 @@
         header('LOCATION: index.php?step=2&message=' . $e->getMessage());
         exit();
     }
-    
+
 
     foreach ($values as $key => $value) {
         $param = $_POST[$value];
@@ -131,7 +132,7 @@
         'mail_host' => $_POST['host'],
         'mail_port' => $_POST['port'],
         'mail_username' => $_POST['user'],
-        'mail_password' => encryptSettingsValue($_POST['pass']),
+        'mail_password' => $_POST['pass'],
         'mail_encryption' => $_POST['encryption'],
         'mail_from_address' => $_POST['user'],
     ];
@@ -196,8 +197,8 @@
         wh_log('Pterodactyl Settings are correct', 'debug');
         wh_log('Updating Database', 'debug');
 
-        $key = encryptSettingsValue($key);
-        $clientkey = encryptSettingsValue($clientkey);
+        $key = $key;
+        $clientkey = $clientkey;
 
         $query1 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($url) . "' WHERE (`name` = 'panel_url' AND `group` = 'pterodactyl')";
         $query2 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($key) . "' WHERE (`name` = 'admin_token' AND `group` = 'pterodactyl')";
@@ -234,10 +235,10 @@
     $repass = $_POST['repass'];
 
     $key = $db->query('SELECT `payload` FROM `' . getenv('DB_DATABASE') . "`.`settings` WHERE `name` = 'admin_token' AND `group` = 'pterodactyl'")->fetch_assoc();
-    $key = encryptSettingsValue($key['value']);
+    $key = removeQuotes($key['payload']);
     $pterobaseurl = $db->query('SELECT `payload` FROM `' . getenv('DB_DATABASE') . "`.`settings` WHERE `name` = 'panel_url' AND `group` = 'pterodactyl'")->fetch_assoc();
 
-    $pteroURL = $pterobaseurl['value'] . '/api/application/users/' . $pteroID;
+    $pteroURL = removeQuotes($pterobaseurl['payload']) . '/api/application/users/' . $pteroID;
     $ch = curl_init();
 
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
@@ -264,7 +265,7 @@
     $name = $result['attributes']['username'];
     $pass = password_hash($pass, PASSWORD_DEFAULT);
 
-    $pteroURL = $pterobaseurl['value'] . '/api/application/users/' . $pteroID;
+    $pteroURL = removeQuotes($pterobaseurl['payload']) . '/api/application/users/' . $pteroID;
     $ch = curl_init();
 
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
@@ -272,7 +273,7 @@
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer ' . $key['value'],
+        'Authorization: Bearer ' . $key,
     ]);
     curl_setopt($ch, CURLOPT_POSTFIELDS, [
         'email' => $mail,
@@ -300,4 +301,4 @@
         wh_log($db->error, 'error');
         header('LOCATION: index.php?step=6&message=Something went wrong when communicating with the Database');
     }
-}
\ No newline at end of file
+}
diff --git a/public/install/functions.php b/public/install/functions.php
index a7952046e..ebba003b1 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -150,6 +150,10 @@ function checkExtensions(): array
     return $not_ok;
 }
 
+function removeQuotes($string){
+    return str_replace('"', "", $string);
+}
+
 /**
  * Sets the environment variable into the env file
  * @param string $envKey The environment key to set or modify

From 50d0e9a37d3371fa4685acfa8de31c83b11efef5 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 00:31:32 +0200
Subject: [PATCH 101/514] replace controlpanel.gg -> ctrlpanel.gg

---
 .env.example                                              | 4 ++--
 LICENSE                                                   | 2 +-
 README.md                                                 | 2 +-
 app/Extensions/PaymentGateways/PayPal/PayPalExtension.php | 2 +-
 app/Http/Controllers/HomeController.php                   | 2 +-
 config/app.php                                            | 2 +-
 .../settings/2023_02_01_181453_create_mail_settings.php   | 2 +-
 .../2023_02_01_182158_create_website_settings.php         | 4 ++--
 lang/de.json                                              | 2 +-
 lang/en.json                                              | 4 ++--
 public/install/index.php                                  | 6 +++---
 themes/BlueInfinity/views/layouts/main.blade.php          | 4 ++--
 themes/default/views/admin/activitylogs/index.blade.php   | 2 +-
 themes/default/views/admin/overview/index.blade.php       | 8 ++++----
 themes/default/views/auth/login.blade.php                 | 4 ++--
 themes/default/views/layouts/main.blade.php               | 4 ++--
 16 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/.env.example b/.env.example
index a025f65df..98f9662bd 100644
--- a/.env.example
+++ b/.env.example
@@ -1,5 +1,5 @@
 ### --- App Settings --- ###
-APP_NAME=Controlpanel.gg
+APP_NAME=CtrlPanel.gg
 APP_ENV=production
 APP_KEY=
 APP_DEBUG=false
@@ -64,4 +64,4 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
 
 # Settings Cache
-SETTINGS_CACHE_ENABLED=true
\ No newline at end of file
+SETTINGS_CACHE_ENABLED=true
diff --git a/LICENSE b/LICENSE
index 0ee0d65c7..00e2a0b66 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2021 ControlPanel.gg
+Copyright (c) 2021 CtrlPanel.gg
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 2d2c062ad..f78d81a7f 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@
 
 ControlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that credits users hourly for each server they have and suspends them if they run out of credits.
 
-This dashboard offers an easy to use and free billing solution for all starting and experienced hosting providers. This dashboard has many customisation options and added discord Oauth verification to offer a solid link between your discord server and your dashboard. You can check our [Demo here](https://demo.controlpanel.gg "Demo").
+This dashboard offers an easy to use and free billing solution for all starting and experienced hosting providers. This dashboard has many customisation options and added discord Oauth verification to offer a solid link between your discord server and your dashboard. You can check our [Demo here](https://demo.CtrlPanel.gg "Demo").
 
 ### [Installation](https://ctrlpanel.gg/docs/intro "Installation")
 
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index af4cc6059..6b1c335e8 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -87,7 +87,7 @@ static function PaypalPay(Request $request): void
             "application_context" => [
                 "cancel_url" => route('payment.Cancel'),
                 "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id]),
-                'brand_name' =>  config('app.name', 'Controlpanel.GG'),
+                'brand_name' =>  config('app.name', 'CtrlPanel.GG'),
                 'shipping_preference'  => 'NO_SHIPPING'
             ]
 
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 5162eebb4..11e597f1d 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -34,7 +34,7 @@ public function callHome()
         if (Storage::exists('callHome')) {
             return;
         }
-        Http::asForm()->post('https://market.controlpanel.gg/callhome.php', [
+        Http::asForm()->post('https://market.CtrlPanel.gg/callhome.php', [
             'id' => Hash::make(URL::current()),
         ]);
         Storage::put('callHome', 'This is only used to count the installations of cpgg.');
diff --git a/config/app.php b/config/app.php
index 045c3604a..534fafe3c 100644
--- a/config/app.php
+++ b/config/app.php
@@ -17,7 +17,7 @@
     |
     */
 
-    'name' => env('APP_NAME', 'Controlpanel.gg'),
+    'name' => env('APP_NAME', 'CtrlPanel.gg'),
 
     /*
     |--------------------------------------------------------------------------
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index 7a1717320..cc609b44a 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -16,7 +16,7 @@ public function up(): void
         $this->migrator->add('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
         $this->migrator->add('mail.mail_encryption', $table_exists ? $this->getOldValue('SETTINGS::MAIL:ENCRYPTION') : env('MAIL_ENCRYPTION', 'tls'));
         $this->migrator->add('mail.mail_from_address', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_ADDRESS') : env('MAIL_FROM_ADDRESS', 'example@example.com'));
-        $this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'ControlPanel.gg'));
+        $this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'CtrlPanel.gg'));
         $this->migrator->add('mail.mail_mailer', $table_exists ? $this->getOldValue('SETTINGS::MAIL:MAILER') : env('MAIL_MAILER', 'smtp'));
         $this->migrator->add('mail.mail_enabled', true);
     }
diff --git a/database/settings/2023_02_01_182158_create_website_settings.php b/database/settings/2023_02_01_182158_create_website_settings.php
index 176052db3..9aeb90364 100644
--- a/database/settings/2023_02_01_182158_create_website_settings.php
+++ b/database/settings/2023_02_01_182158_create_website_settings.php
@@ -14,7 +14,7 @@ public function up(): void
         $this->migrator->add(
             'website.motd_message',
             $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_MESSAGE") :
-                '<h1 style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://controlpanel.gg/img/controlpanel.png" alt="" width="200" height="200"><span style="font-size: 36pt;">Controlpanel.gg</span></h1>
+                '<h1 style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://ctrlpanel.gg/img/controlpanel.png" alt="" width="200" height="200"><span style="font-size: 36pt;">CtrlPanel.gg</span></h1>
             <p><span style="font-size: 18pt;">Thank you for using our Software</span></p>
             <p><span style="font-size: 18pt;">If you have any questions, make sure to join our <a href="https://discord.com/invite/4Y6HjD2uyU" target="_blank" rel="noopener">Discord</a></span></p>
             <p><span style="font-size: 10pt;">(you can change this message in the <a href="admin/settings#system">Settings</a> )</span></p>'
@@ -23,7 +23,7 @@ public function up(): void
         $this->migrator->add('website.show_privacy', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_PRIVACY") : false);
         $this->migrator->add('website.show_tos', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_TOS") : false);
         $this->migrator->add('website.useful_links_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:USEFULLINKS_ENABLED") : true);
-        $this->migrator->add('website.seo_title', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SEO_TITLE") : 'ControlPanel.gg');
+        $this->migrator->add('website.seo_title', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SEO_TITLE") : 'CtrlPanel.gg');
         $this->migrator->add('website.seo_description', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SEO_DESCRIPTION") : 'Billing software for Pterodactyl Panel.');
         $this->migrator->add('website.enable_login_logo', true);
     }
diff --git a/lang/de.json b/lang/de.json
index 9107634ba..638ede32d 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -126,7 +126,7 @@
     "Support server": "Discord Server",
     "Documentation": "Dokumentation",
     "Github": "Github",
-    "Support ControlPanel": "Unterstütze Controlpanel.gg",
+    "Support ControlPanel": "Unterstütze CtrlPanel.gg",
     "Servers": "Server",
     "Total": "Gesamt",
     "Payments": "Zahlungen",
diff --git a/lang/en.json b/lang/en.json
index c0aa64314..af1126bdd 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -177,7 +177,7 @@
     "Title": "Title",
     "User": "User",
     "Last updated": "Last updated",
-    "Controlpanel.gg": "Controlpanel.gg",
+    "CtrlPanel.gg": "CtrlPanel.gg",
     "Version": "Version",
     "Individual nodes": "Individual nodes",
     "You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.": "You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.",
@@ -654,4 +654,4 @@
     "sv": "Swedish",
     "sk": "Slovakish",
     "hu": "Hungarian"
-}
\ No newline at end of file
+}
diff --git a/public/install/index.php b/public/install/index.php
index 54eb254d5..3a05e2b00 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -9,7 +9,7 @@ function cardStart($title, $subtitle = null)
 {
     return "
     <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
-        <h1 class='text-center font-bold text-3xl'>ControlPanel.gg Installation</h1>
+        <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
         <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
             <h2 class='text-xl text-center mb-2'>$title</h2>"
         . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
@@ -19,7 +19,7 @@ function cardStart($title, $subtitle = null)
 <html>
 
 <head>
-    <title>Controlpanel.gg installer Script</title>
+    <title>CtrlPanel.gg installer Script</title>
 
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <link href="/install/styles.css" rel="stylesheet">
@@ -68,7 +68,7 @@ function cardStart($title, $subtitle = null)
     // Getting started
     if (!isset($_GET['step']) || $_GET['step'] == 1) {
     ?>
-        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of Controlpanel.gg's setup"); ?>
+        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
 
         <ul class="list-none mb-2">
 
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index f5d888d5a..f965da56a 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -199,7 +199,7 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                  src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
                  alt="{{ config('app.name', 'Laravel') }} Logo" class="brand-image img-circle"
                  style="opacity: .8">
-            <span class="brand-text font-weight-light">{{ config('app.name', 'Controlpanel.gg') }}</span>
+            <span class="brand-text font-weight-light">{{ config('app.name', 'CtrlPanel.gg') }}</span>
         </a>
 
         <!-- Sidebar -->
@@ -441,7 +441,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
         <strong>Copyright &copy; 2021-{{ date('Y') }} <a
                 href="{{ url('/') }}">{{ env('APP_NAME', 'Laravel') }}</a>.</strong>
         All rights
-        reserved. Powered by <a href="https://controlpanel.gg">ControlPanel</a>. | Theme by <a href="https://2icecube.de/cpgg">2IceCube</a>
+        reserved. Powered by <a href="https://CtrlPanel.gg">ControlPanel</a>. | Theme by <a href="https://2icecube.de/cpgg">2IceCube</a>
         @if (!str_contains(config('BRANCHNAME'), 'main') && !str_contains(config('BRANCHNAME'), 'unknown'))
             Version <b>{{ config('app')['version'] }} - {{ config('BRANCHNAME') }}</b>
         @endif
diff --git a/themes/default/views/admin/activitylogs/index.blade.php b/themes/default/views/admin/activitylogs/index.blade.php
index 822b06d68..fda21cf8e 100644
--- a/themes/default/views/admin/activitylogs/index.blade.php
+++ b/themes/default/views/admin/activitylogs/index.blade.php
@@ -33,7 +33,7 @@
                     @else
                         <div class="callout callout-danger">
                             <h4>{{ __('No recent activity from cronjobs')}}</h4>
-                            <p>{{ __('Are cronjobs running?')}} <a class="text-primary" target="_blank" href="https://controlpanel.gg/docs/Installation/getting-started#crontab-configuration">{{ __('Check the docs for it here')}}</a></p>
+                            <p>{{ __('Are cronjobs running?')}} <a class="text-primary" target="_blank" href="https://CtrlPanel.gg/docs/Installation/getting-started#crontab-configuration">{{ __('Check the docs for it here')}}</a></p>
                         </div>
                     @endif
 
diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index d801656e2..a092ed5f4 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -23,7 +23,7 @@
                 <b><i class="fas fa-shield-alt"></i> {{__("Version Outdated:")}}</b></br>
                 {{__("You are running on")}} v{{config("app.version")}}-{{config("BRANCHNAME")}}.
                     {{__("The latest Version is")}} v{{Storage::get('latestVersion')}}</br>
-                <a href="https://controlpanel.gg/docs/Installation/updating">{{__("Consider updating now")}}</a>
+                <a href="https://CtrlPanel.gg/docs/Installation/updating">{{__("Consider updating now")}}</a>
             </div>
         @endif
     </section>
@@ -39,7 +39,7 @@
                             class="fab fa-discord mr-2"></i> {{__('Support server')}}</a>
                 </div>
                 <div class="col-md-3">
-                    <a href="https://controlpanel.gg/docs/intro" class="btn btn-dark btn-block px-3"><i
+                    <a href="https://CtrlPanel.gg/docs/intro" class="btn btn-dark btn-block px-3"><i
                             class="fas fa-link mr-2"></i> {{__('Documentation')}}</a>
                 </div>
                 <div class="col-md-3">
@@ -47,7 +47,7 @@ class="fas fa-link mr-2"></i> {{__('Documentation')}}</a>
                             class="fab fa-github mr-2"></i> {{__('Github')}}</a>
                 </div>
                 <div class="col-md-3">
-                    <a href="https://controlpanel.gg/docs/Contributing/donating" class="btn btn-dark btn-block px-3"><i
+                    <a href="https://CtrlPanel.gg/docs/Contributing/donating" class="btn btn-dark btn-block px-3"><i
                             class="fas fa-money-bill mr-2"></i> {{__('Support ControlPanel')}}</a>
                 </div>
             </div>
@@ -199,7 +199,7 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-server mr-2"></i>{{__('Controlpanel.gg')}}</span>
+                                    <span><i class="fas fa-server mr-2"></i>{{__('CtrlPanel.gg')}}</span>
                                 </div>
                             </div>
                             <div class="card-body py-1">
diff --git a/themes/default/views/auth/login.blade.php b/themes/default/views/auth/login.blade.php
index 720effd5d..8c3cbb786 100644
--- a/themes/default/views/auth/login.blade.php
+++ b/themes/default/views/auth/login.blade.php
@@ -9,9 +9,9 @@
                 <div class="card-header text-center">
                     <a href="{{ route('welcome') }}" class="h1 mb-2"><b
                             class="mr-1">{{ config('app.name', 'Laravel') }}</b></a>
-                    @if ($website_settings->enable_login_logo) 
+                    @if ($website_settings->enable_login_logo)
                         <img src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
-                            alt="{{ config('app.name', 'Controlpanel.gg') }} Logo" style="opacity: .8; max-width:100%; height: 150px; margin-top: 10px;">
+                            alt="{{ config('app.name', 'CtrlPanel.gg') }} Logo" style="opacity: .8; max-width:100%; height: 150px; margin-top: 10px;">
                     @endif
                 </div>
                 <div class="card-body pt-0">
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 30fb8eafc..0683b8757 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -204,7 +204,7 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                     src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
                     alt="{{ config('app.name', 'Laravel') }} Logo" class="brand-image img-circle"
                     style="opacity: .8">
-                <span class="brand-text font-weight-light">{{ config('app.name', 'Controlpanel.gg') }}</span>
+                <span class="brand-text font-weight-light">{{ config('app.name', 'CtrlPanel.gg') }}</span>
             </a>
 
             <!-- Sidebar -->
@@ -443,7 +443,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
             <strong>Copyright &copy; 2021-{{ date('Y') }} <a
                     href="{{ url('/') }}">{{ env('APP_NAME', 'Laravel') }}</a>.</strong>
             All rights
-            reserved. Powered by <a href="https://controlpanel.gg">ControlPanel</a>.
+            reserved. Powered by <a href="https://CtrlPanel.gg">ControlPanel</a>.
             @if (!str_contains(config('BRANCHNAME'), 'main') && !str_contains(config('BRANCHNAME'), 'unknown'))
                 Version <b>{{ config('app')['version'] }} - {{ config('BRANCHNAME') }}</b>
             @endif

From bcf238d6b74fd97dff2b09e434662d26831747cd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 00:38:47 +0200
Subject: [PATCH 102/514] rename controlpanel -> ctrlpanel

---
 .github/ISSUE_TEMPLATE/config.yml                         | 2 +-
 README.md                                                 | 8 ++++----
 app/Console/Commands/GetGithubVersion.php                 | 2 +-
 config/mail.php                                           | 2 +-
 themes/default/views/admin/overview/index.blade.php       | 4 ++--
 themes/default/views/admin/servers/edit.blade.php         | 4 ++--
 .../default/views/information/privacy-content.blade.php   | 4 ++--
 themes/default/views/layouts/main.blade.php               | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 7b1652eaa..34e1506be 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -5,4 +5,4 @@ contact_links:
     about: Please visit our Discord for help with your installation.
   - name: ❓ General Question
     url: https://discord.gg/4Y6HjD2uyU
-    about: Please visit our Discord for general questions about the ControlPanel.
+    about: Please visit our Discord for general questions about the CtrlPanel.
diff --git a/README.md b/README.md
index f78d81a7f..aecde0b58 100644
--- a/README.md
+++ b/README.md
@@ -17,17 +17,17 @@
 -   Theme Support
 -   and so much more!
 
-# ControlPanel-gg
+# CtrlPanel-gg
 
-![controlpanel](https://user-images.githubusercontent.com/67899387/214684708-739c1d21-06e8-4dec-a4f1-81533a46cc7e.png)
+![ctrlpanel](https://user-images.githubusercontent.com/67899387/214684708-739c1d21-06e8-4dec-a4f1-81533a46cc7e.png)
 
 
 ![](https://img.shields.io/endpoint?label=v0.9%20Installations&url=https%3A%2F%2Fmarket.ctrlpanel.gg%2Fcallhome.php%3Fgetinstalls)
 ![](https://img.shields.io/badge/Overall%20Installations-5000%2B-green)
-![](https://img.shields.io/github/stars/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/forks/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/tag/ControlPanel-gg/dashboard) [![Crowdin](https://badges.crowdin.net/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/license/ControlPanel-gg/dashboard) ![](https://img.shields.io/discord/787829714483019826)
+![](https://img.shields.io/github/stars/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/forks/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/tag/ctrlpanel-gg/dashboard) [![Crowdin](https://badges.crowdin.net/ctrlpanel/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/license/ctrlpanel-gg/panel) ![](https://img.shields.io/discord/787829714483019826)
 ## About
 
-ControlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that credits users hourly for each server they have and suspends them if they run out of credits.
+CtrlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that credits users hourly for each server they have and suspends them if they run out of credits.
 
 This dashboard offers an easy to use and free billing solution for all starting and experienced hosting providers. This dashboard has many customisation options and added discord Oauth verification to offer a solid link between your discord server and your dashboard. You can check our [Demo here](https://demo.CtrlPanel.gg "Demo").
 
diff --git a/app/Console/Commands/GetGithubVersion.php b/app/Console/Commands/GetGithubVersion.php
index 31e936252..99ee7e5b9 100644
--- a/app/Console/Commands/GetGithubVersion.php
+++ b/app/Console/Commands/GetGithubVersion.php
@@ -32,7 +32,7 @@ class GetGithubVersion extends Command
     public function handle()
     {
         try{
-            $latestVersion = Http::get('https://api.github.com/repos/controlpanel-gg/dashboard/tags')->json()[0]['name'];
+            $latestVersion = Http::get('https://api.github.com/repos/ctrlpanel-gg/panel/tags')->json()[0]['name'];
             Storage::disk('local')->put('latestVersion', $latestVersion);
         } catch (Exception $e) {
             Storage::disk('local')->put('latestVersion', "unknown");
diff --git a/config/mail.php b/config/mail.php
index 2974614ee..867155b50 100644
--- a/config/mail.php
+++ b/config/mail.php
@@ -93,7 +93,7 @@
 
     'from' => [
         'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
-        'name' => env('MAIL_FROM_NAME', 'ControlPanel'),
+        'name' => env('MAIL_FROM_NAME', 'CtrlPanel'),
     ],
 
     /*
diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index a092ed5f4..d5b8d5a8e 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -48,7 +48,7 @@ class="fab fa-github mr-2"></i> {{__('Github')}}</a>
                 </div>
                 <div class="col-md-3">
                     <a href="https://CtrlPanel.gg/docs/Contributing/donating" class="btn btn-dark btn-block px-3"><i
-                            class="fas fa-money-bill mr-2"></i> {{__('Support ControlPanel')}}</a>
+                            class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
                 </div>
             </div>
 
@@ -227,7 +227,7 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
                                     <p class="mb-2">
                                         {{ __('You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.') }}<br>
                                         {{ __('You can do that in settings.') }}<br><br>
-                                        {{ __('Note') }}: {{ __('If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel. Try clicking the button below.') }}
+                                        {{ __('Note') }}: {{ __('If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on CtrlPanel. Try clicking the button below.') }}
                                     </p>
                                     <a href="{{route('admin.servers.sync')}}" class="btn btn-primary btn-md"><i
                                         class="fas fa-sync mr-2"></i>{{__('Sync servers')}}</a>
diff --git a/themes/default/views/admin/servers/edit.blade.php b/themes/default/views/admin/servers/edit.blade.php
index e3b9854f0..f9afd2b28 100644
--- a/themes/default/views/admin/servers/edit.blade.php
+++ b/themes/default/views/admin/servers/edit.blade.php
@@ -43,7 +43,7 @@
                                 <div class="form-group">
                                     <label for="identifier">{{ __('Server identifier') }}
                                         <i data-toggle="popover" data-trigger="hover"
-                                            data-content="{{ __('Change the server identifier on controlpanel to match a pterodactyl server.') }}"
+                                            data-content="{{ __('Change the server identifier on CtrlPanel to match a pterodactyl server.') }}"
                                             class="fas fa-info-circle"></i>
                                     </label>
                                     <input value="{{ $server->identifier }}" id="identifier" name="identifier"
@@ -59,7 +59,7 @@ class="fas fa-info-circle"></i>
                                 <div class="form-group">
                                     <label for="user_id">{{ __('Server owner') }}
                                         <i data-toggle="popover" data-trigger="hover"
-                                            data-content="{{ __('Change the current server owner on controlpanel and pterodactyl.') }}"
+                                            data-content="{{ __('Change the current server owner on CtrlPanel and pterodactyl.') }}"
                                             class="fas fa-info-circle"></i>
                                     </label>
                                     <select name="user_id" id="user_id" class="form-control">
diff --git a/themes/default/views/information/privacy-content.blade.php b/themes/default/views/information/privacy-content.blade.php
index af4144858..5f465e829 100644
--- a/themes/default/views/information/privacy-content.blade.php
+++ b/themes/default/views/information/privacy-content.blade.php
@@ -18,7 +18,7 @@
     </li>
     <li>
         <p><strong>Company</strong> (referred to as either &quot;the Company&quot;, &quot;We&quot;, &quot;Us&quot; or
-            &quot;Our&quot; in this Agreement) refers to controlpanel.</p>
+            &quot;Our&quot; in this Agreement) refers to CtrlPanel.</p>
     </li>
     <li>
         <p><strong>Cookies</strong> are small files that are placed on Your computer, mobile device or any other device
@@ -49,7 +49,7 @@
             Service or from the Service infrastructure itself (for example, the duration of a page visit).</p>
     </li>
     <li>
-        <p><strong>Website</strong> refers to controlpanel, accessible from <a href="controlpanel"
+        <p><strong>Website</strong> refers to CtrlPanel, accessible from <a href="controlpanel"
                 rel="external nofollow noopener" target="_blank">controlpanel</a></p>
     </li>
     <li>
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 0683b8757..6e1f6f01e 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -443,7 +443,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
             <strong>Copyright &copy; 2021-{{ date('Y') }} <a
                     href="{{ url('/') }}">{{ env('APP_NAME', 'Laravel') }}</a>.</strong>
             All rights
-            reserved. Powered by <a href="https://CtrlPanel.gg">ControlPanel</a>.
+            reserved. Powered by <a href="https://CtrlPanel.gg">CtrlPanel</a>.
             @if (!str_contains(config('BRANCHNAME'), 'main') && !str_contains(config('BRANCHNAME'), 'unknown'))
                 Version <b>{{ config('app')['version'] }} - {{ config('BRANCHNAME') }}</b>
             @endif

From 797d871b6304afda198e04fb8f93eac9198e1c67 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 00:39:57 +0200
Subject: [PATCH 103/514] fix double useful links?

---
 themes/default/views/home.blade.php | 21 +++------------------
 1 file changed, 3 insertions(+), 18 deletions(-)

diff --git a/themes/default/views/home.blade.php b/themes/default/views/home.blade.php
index 29d129266..8f106c949 100644
--- a/themes/default/views/home.blade.php
+++ b/themes/default/views/home.blade.php
@@ -135,12 +135,12 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                         </div>
                         <!-- /.card-header -->
                         <div class="card-body">
-                            @foreach ($useful_links as $useful_link)
+                            @foreach ($useful_links_dashboard as $useful_link)
                                 <div class="alert alert-dismissible">
                                     <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                                     <h5>
                                         <a class="alert-link text-decoration-none" target="__blank"
-                                            href="{{ $useful_link->link }}">
+                                           href="{{ $useful_link->link }}">
                                             <i class="{{ $useful_link->icon }} mr-2"></i>{{ $useful_link->title }}
                                         </a>
                                     </h5>
@@ -150,22 +150,7 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                         </div>
                         <!-- /.card-body -->
                     </div>
-                    <!-- /.card-header -->
-                    <div class="card-body">
-                        @foreach ($useful_links_dashboard as $useful_link)
-                            <div class="alert alert-dismissible">
-                                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
-                                <h5>
-                                    <a class="alert-link text-decoration-none" target="__blank"
-                                        href="{{ $useful_link->link }}">
-                                        <i class="{{ $useful_link->icon }} mr-2"></i>{{ $useful_link->title }}
-                                    </a>
-                                </h5>
-                                {!! $useful_link->description !!}
-                            </div>
-                        @endforeach
-                    </div>
-                    <!-- /.card-body -->
+
             </div>
             @endif
 

From fe2020f81760d5a2d0b4f4940151099948f0a413 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 00:47:15 +0200
Subject: [PATCH 104/514] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index aecde0b58..4e6591b4d 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
 
 ![](https://img.shields.io/endpoint?label=v0.9%20Installations&url=https%3A%2F%2Fmarket.ctrlpanel.gg%2Fcallhome.php%3Fgetinstalls)
 ![](https://img.shields.io/badge/Overall%20Installations-5000%2B-green)
-![](https://img.shields.io/github/stars/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/forks/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/tag/ctrlpanel-gg/dashboard) [![Crowdin](https://badges.crowdin.net/ctrlpanel/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/license/ctrlpanel-gg/panel) ![](https://img.shields.io/discord/787829714483019826)
+![](https://img.shields.io/github/stars/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/forks/ctrlpanel-gg/panel) ![](https://img.shields.io/github/tag/ctrlpanel-gg/panel) [![Crowdin](https://badges.crowdin.com/project/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ctrlpanel-gg/panel) ![](https://img.shields.io/github/license/ctrlpanel-gg/panel) ![](https://img.shields.io/discord/787829714483019826)
 ## About
 
 CtrlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that credits users hourly for each server they have and suspends them if they run out of credits.

From bfda91516af2357ab98a641fc0b53be608487f45 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 01:00:45 +0200
Subject: [PATCH 105/514] add recaptcha to tickets and preview to settings

---
 app/Http/Controllers/TicketsController.php    |  1 +
 .../views/admin/settings/index.blade.php      | 22 +++++++++++++++++++
 themes/default/views/ticket/create.blade.php  | 11 ++++++++++
 3 files changed, 34 insertions(+)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index 8cd988149..754241edd 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -39,6 +39,7 @@ public function store(Request $request, TicketSettings $ticket_settings)
                 'ticketcategory' => 'required',
                 'priority' => 'required',
                 'message' => 'required',
+                'g-recaptcha-response' => ['required', 'recaptcha'],
             ]
         );
         $ticket = new Ticket(
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 8b0c36126..89249eac9 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -159,6 +159,28 @@ class="custom-select w-100" name="{{ $key }}"
                                                     </div>
                                                 </div>
                                             @endforeach
+                                            <div class="row">
+                                                <div class="col-4 d-flex align-items-center">
+                                                    <label for="recaptcha_preview">{{__("ReCAPTCHA Preview")}}</label>
+                                                </div>
+
+                                                <div class="col-8">
+
+                                                        <div class="w-100">
+                                                <div class="input-group mb-3">
+                                                    {!! htmlScriptTagJsApi() !!}
+                                                    {!! htmlFormSnippet() !!}
+                                                    @error('g-recaptcha-response')
+                                                    <span class="text-danger" role="alert">
+                                                                                <small><strong>{{ $message }}</strong></small>
+                                                                                </span>
+                                                    @enderror
+                                                </div>
+                                                        </div>
+                                                </div>
+                                            </div>
+
+
                                             <div class="row">
                                                 <div class="col-12 d-flex align-items-center justify-content-end">
                                                     <button type="submit"
diff --git a/themes/default/views/ticket/create.blade.php b/themes/default/views/ticket/create.blade.php
index 7da409cfa..f9d35ad4d 100644
--- a/themes/default/views/ticket/create.blade.php
+++ b/themes/default/views/ticket/create.blade.php
@@ -90,6 +90,17 @@
                                     </span>
                                     @endif
                                 </div>
+                                @if (app(App\Settings\GeneralSettings::class)->recaptcha_enabled)
+                                    <div class="input-group mb-3">
+                                        {!! htmlScriptTagJsApi() !!}
+                                        {!! htmlFormSnippet() !!}
+                                        @error('g-recaptcha-response')
+                                        <span class="text-danger" role="alert">
+                                            <small><strong>{{ $message }}</strong></small>
+                                        </span>
+                                        @enderror
+                                    </div>
+                                @endif
                             </div>
                             <div class="card-footer">
                                 <button type="submit" class="btn btn-primary ticket-once">

From 02798b2c30981e16625e23ec32c5e9c9cab1ceaf Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 01:12:49 +0200
Subject: [PATCH 106/514] installer fix

---
 .../2023_02_01_182158_create_website_settings.php         | 8 ++++----
 public/install/index.php                                  | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/database/settings/2023_02_01_182158_create_website_settings.php b/database/settings/2023_02_01_182158_create_website_settings.php
index 9aeb90364..013c85f87 100644
--- a/database/settings/2023_02_01_182158_create_website_settings.php
+++ b/database/settings/2023_02_01_182158_create_website_settings.php
@@ -14,10 +14,10 @@ public function up(): void
         $this->migrator->add(
             'website.motd_message',
             $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_MESSAGE") :
-                '<h1 style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://ctrlpanel.gg/img/controlpanel.png" alt="" width="200" height="200"><span style="font-size: 36pt;">CtrlPanel.gg</span></h1>
-            <p><span style="font-size: 18pt;">Thank you for using our Software</span></p>
-            <p><span style="font-size: 18pt;">If you have any questions, make sure to join our <a href="https://discord.com/invite/4Y6HjD2uyU" target="_blank" rel="noopener">Discord</a></span></p>
-            <p><span style="font-size: 10pt;">(you can change this message in the <a href="admin/settings#system">Settings</a> )</span></p>'
+                '<h1 style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://ctrlpanel.gg/img/controlpanel.png" alt="" width="200" height="200"><span style="font-size: 36pt;">Controlpanel.gg</span></h1>
+ <p><span style="font-size: 18pt;">Thank you for using our Software</span></p>
+ <p><span style="font-size: 18pt;">If you have any questions, make sure to join our <a href="https://discord.com/invite/4Y6HjD2uyU" target="_blank" rel="noopener">Discord</a></span></p>
+ <p><span style="font-size: 10pt;">(you can change this message in the <a href="admin/settings#system">Settings</a> )</span></p>'
         );
         $this->migrator->add('website.show_imprint', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_IMPRINT") : false);
         $this->migrator->add('website.show_privacy', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_PRIVACY") : false);
diff --git a/public/install/index.php b/public/install/index.php
index 3a05e2b00..6afd2e70c 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -327,7 +327,7 @@ function cardStart($title, $subtitle = null)
                             <div class="flex flex-col mb-3">
 
                                 <label for="url">Pterodactyl URL</label>
-                                <input id="url" name="url" type="text" required value="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                             </div>
                         </div>
                         <div class="form-group">

From 0ffceb535d0385dccdf15b94a3697c2441c24329 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 02:22:59 +0200
Subject: [PATCH 107/514] simple starting permissions. only admin

---
 app/Http/Controllers/Admin/RoleController.php | 190 ++++++++++++++++++
 app/Http/Controllers/Admin/UserController.php |   2 +-
 app/Http/Controllers/Controller.php           |  32 +++
 app/Http/Controllers/ProfileController.php    |   2 +-
 app/Http/Kernel.php                           |   5 +
 app/Http/Middleware/isAdmin.php               |   2 +-
 app/Http/Middleware/isMod.php                 |   2 +-
 app/Models/User.php                           |   3 +-
 composer.json                                 |   1 +
 composer.lock                                 |  84 +++++++-
 config/permission.php                         | 161 +++++++++++++++
 config/permissions_web.php                    |  92 +++++++++
 ..._04_29_232942_create_permission_tables.php | 142 +++++++++++++
 .../2023_04_29_233120_drop_roles.php          |  51 +++++
 database/seeders/PermissionsSeeder.php        |  74 +++++++
 public/install/forms.php                      |   6 +-
 routes/web.php                                |   5 +-
 .../BlueInfinity/views/layouts/main.blade.php |   4 +-
 .../default/views/admin/roles/edit.blade.php  |  54 +++++
 .../default/views/admin/roles/index.blade.php |  58 ++++++
 .../default/views/admin/users/edit.blade.php  |  22 +-
 .../default/views/admin/users/show.blade.php  |   2 +-
 themes/default/views/home.blade.php           |   2 +-
 themes/default/views/layouts/main.blade.php   |  11 +-
 .../views/moderator/ticket/show.blade.php     |   4 +-
 themes/default/views/servers/create.blade.php |   2 +-
 themes/default/views/ticket/show.blade.php    |   4 +-
 27 files changed, 980 insertions(+), 37 deletions(-)
 create mode 100644 app/Http/Controllers/Admin/RoleController.php
 create mode 100644 config/permission.php
 create mode 100644 config/permissions_web.php
 create mode 100644 database/migrations/2023_04_29_232942_create_permission_tables.php
 create mode 100644 database/migrations/2023_04_29_233120_drop_roles.php
 create mode 100644 database/seeders/PermissionsSeeder.php
 create mode 100644 themes/default/views/admin/roles/edit.blade.php
 create mode 100644 themes/default/views/admin/roles/index.blade.php

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
new file mode 100644
index 000000000..22a8c113f
--- /dev/null
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -0,0 +1,190 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Http\Controllers\Controller;
+use Exception;
+use Illuminate\Contracts\Foundation\Application;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\Contracts\View\View;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Spatie\Permission\Models\Permission;
+use Spatie\Permission\Models\Role;
+
+class RoleController extends Controller
+{
+
+    /**
+     * Display a listing of the resource.
+     *
+     * @param Request $request
+     * @return mixed
+     * @throws Exception
+     */
+    public function index(Request $request)
+    {
+
+
+        //datatables
+        if ($request->ajax()) {
+            return $this->dataTableQuery();
+        }
+
+        $html = $this->dataTable();
+        return view('admin.roles.index', compact('html'));
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return Application|Factory|View
+     */
+    public function create()
+    {
+
+        $permissions = Permission::all();
+
+        return view('admin.roles.edit', compact('permissions'));
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @return RedirectResponse
+     */
+    public function store(Request $request): RedirectResponse
+    {
+        $role = Role::create([
+            'name' => $request->name,
+            'color' => $request->color
+        ]);
+
+        if ($request->permissions) {
+            $role->givePermissionTo($request->permissions);
+        }
+
+        return redirect()
+            ->route('admin.roles.index')
+            ->with('success', __('Role saved'));
+    }
+
+    /**
+     * Display the specified resource.
+     */
+    public function show()
+    {
+        abort(404);
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param Role $role
+     * @return Application|Factory|View
+     */
+    public function edit(Role $role)
+    {
+
+        $permissions = Permission::all();
+
+        return view('admin.roles.edit', compact('role', 'permissions'));
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param Role $role
+     * @return RedirectResponse
+     */
+    public function update(Request $request, Role $role)
+    {
+        if ($request->permissions) {
+            if($role->id != 1){ //disable admin permissions change
+                $role->syncPermissions($request->permissions);
+            }
+        }
+
+        if($role->id == 3 || $role->id == 1 || $role->id == 4){ //dont let the user change the names of these roles
+            $role->update([
+                'color' => $request->color
+            ]);
+        }else{
+            $role->update([
+                'name' => $request->name,
+                'color' => $request->color
+            ]);
+        }
+
+        if($role->id == 1){
+            return redirect()->route('admin.roles.index')->with('success', __('Role updated. Name and Permissions of this Role cannot be changed'));
+        }elseif($role->id == 4 || $role->id == 3){
+            return redirect()->route('admin.roles.index')->with('success', __('Role updated. Name of this Role cannot be changed'));
+        }else{
+            return redirect()
+                ->route('admin.roles.index')
+                ->with('success', __('Role saved'));
+        }
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @return RedirectResponse
+     */
+    public function destroy(Role $role)
+    {
+
+        if($role->id == 3 || $role->id == 1 || $role->id == 2){ //cannot delete the hard coded roles
+            return back()->with("error","You cannot delete that role");
+        }
+
+        $users = User::role($role)->get();
+
+        foreach($users as $user){
+            $user->syncRoles(['Member']);
+        }
+
+        $role->delete();
+
+        return redirect()
+            ->route('admin.roles.index')
+            ->with('success', __('Role removed'));
+    }
+
+    /**
+     * @return mixed
+     * @throws Exception
+     */
+    public function dataTable()
+    {
+        $query = Role::query()->withCount(['users', 'permissions']);
+
+
+        return datatables($query)
+            ->addColumn('actions', function (Role $role) {
+                return '
+                            <a title="Edit" href="'.route("admin.roles.edit", $role).'" class="btn btn-sm btn-info"><i
+                                    class="fa fas fa-edit"></i></a>
+                            <form class="d-inline" method="post" action="'.route("admin.roles.destroy", $role).'">
+                            ' . csrf_field() . '
+                            ' . method_field("DELETE") . '
+                                <button title="Delete" type="submit" class="btn btn-sm btn-danger confirm"><i
+                                        class="fa fas fa-trash"></i></button>
+                            </form>
+                ';
+            })
+
+            ->editColumn('name', function (Role $role) {
+                return "<span style=\"color: $role->color\">$role->name</span>";
+            })
+            ->editColumn('usercount', function ($query) {
+                return $query->users_count;
+            })
+            ->editColumn('permissionscount', function ($query){
+                return $query->permissions_count;
+            })
+            ->rawColumns(['actions', 'name'])
+            ->make(true);
+    }
+}
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 4dfcb219f..a7e494a9c 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -166,7 +166,7 @@ public function update(Request $request, User $user)
      */
     public function destroy(User $user)
     {
-        if ($user->role === 'admin' && User::query()->where('role', 'admin')->count() === 1) {
+        if ($user->hasRole("Admin") && User::query()->where('role', 'admin')->count() === 1) {
             return redirect()->back()->with('error', __('You can not delete the last admin!'));
         }
 
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index a0a2a8a34..49d020497 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -2,12 +2,44 @@
 
 namespace App\Http\Controllers;
 
+use App\Models\User;
 use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 use Illuminate\Foundation\Bus\DispatchesJobs;
 use Illuminate\Foundation\Validation\ValidatesRequests;
 use Illuminate\Routing\Controller as BaseController;
+use Illuminate\Support\Facades\Auth;
 
 class Controller extends BaseController
 {
     use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
+    /**
+     * Check if user has permissions
+     * Abort 403 if the user doesn't have the required permission
+     *
+     * @param string $permission
+     * @return void
+     */
+    public function checkPermission(string $permission)
+    {
+        /** @var User $user */
+        $user = Auth::user();
+
+        if (!$user->can($permission)) {
+            abort(403, __('User does not have the right permissions.'));
+        }
+    }
+
+    /**
+     * Check if user has permissions
+     *
+     * @param string $permission
+     * @return bool
+     */
+    public function can(string $permission): bool
+    {
+        /** @var User $user */
+        $user = Auth::user();
+
+        return $user->can($permission);
+    }
 }
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index b3156f96e..5c4293aed 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -57,7 +57,7 @@ public function index(UserSettings $user_settings, DiscordSettings $discord_sett
     public function selfDestroyUser()
     {
         $user = Auth::user();
-        if ($user->role == "admin") return back()->with("error", "You cannot delete yourself as an admin!");
+        if ($user->hasRole("Admin")) return back()->with("error", "You cannot delete yourself as an admin!");
 
         $user->delete();
 
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 3e372e091..a6fb149b0 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -27,6 +27,7 @@ class Kernel extends HttpKernel
         \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
         \App\Http\Middleware\TrimStrings::class,
         \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+
     ];
 
     /**
@@ -76,5 +77,9 @@ class Kernel extends HttpKernel
         'moderator' => isMod::class,
         'api.token' => ApiAuthToken::class,
         'checkSuspended' => CheckSuspended::class,
+        'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
+        'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
+        'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
     ];
+
 }
diff --git a/app/Http/Middleware/isAdmin.php b/app/Http/Middleware/isAdmin.php
index 3dbb49574..1bf4f55af 100644
--- a/app/Http/Middleware/isAdmin.php
+++ b/app/Http/Middleware/isAdmin.php
@@ -18,7 +18,7 @@ class isAdmin
      */
     public function handle(Request $request, Closure $next)
     {
-        if (Auth::user() && Auth::user()->role == 'admin') {
+        if (Auth::user() && Auth::user()->hasRole("Admin")) {
             return $next($request);
         }
 
diff --git a/app/Http/Middleware/isMod.php b/app/Http/Middleware/isMod.php
index c9120719c..8c5453a24 100644
--- a/app/Http/Middleware/isMod.php
+++ b/app/Http/Middleware/isMod.php
@@ -18,7 +18,7 @@ class isMod
      */
     public function handle(Request $request, Closure $next)
     {
-        if (Auth::user() && Auth::user()->role == 'moderator' || Auth::user() && Auth::user()->role == 'admin') {
+        if (Auth::user() && Auth::user()->role == 'moderator' || Auth::user() && Auth::user()->hasRole("Admin")) {
             return $next($request);
         }
 
diff --git a/app/Models/User.php b/app/Models/User.php
index 9584bd3db..d25a71009 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -18,13 +18,14 @@
 use Spatie\Activitylog\LogOptions;
 use Spatie\Activitylog\Traits\CausesActivity;
 use Spatie\Activitylog\Traits\LogsActivity;
+use Spatie\Permission\Traits\HasRoles;
 
 /**
  * Class User
  */
 class User extends Authenticatable implements MustVerifyEmail
 {
-    use HasFactory, Notifiable, LogsActivity, CausesActivity;
+    use HasFactory, Notifiable, LogsActivity, CausesActivity, HasRoles;
 
     private PterodactylClient $pterodactyl;
 
diff --git a/composer.json b/composer.json
index 7a4a1e643..b316eec10 100644
--- a/composer.json
+++ b/composer.json
@@ -26,6 +26,7 @@
         "qirolab/laravel-themer": "^2.0.2",
         "socialiteproviders/discord": "^4.1.2",
         "spatie/laravel-activitylog": "^4.7.3",
+        "spatie/laravel-permission": "^5.10",
         "spatie/laravel-query-builder": "^5.1.2",
         "spatie/laravel-settings": "^2.7",
         "spatie/laravel-validation-rules": "^3.2.2",
diff --git a/composer.lock b/composer.lock
index 96825a92c..3f224c0c4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "0d007fe2e018692a9ff3d50fcbebabc5",
+    "content-hash": "8a9b4a3cda2a919fa33f41527b679dce",
     "packages": [
         {
             "name": "aws/aws-crt-php",
@@ -5160,6 +5160,88 @@
             ],
             "time": "2023-04-27T08:09:01+00:00"
         },
+        {
+            "name": "spatie/laravel-permission",
+            "version": "5.10.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/laravel-permission.git",
+                "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/d08b3ffc5870cce4a47a39f22174947b33c191ae",
+                "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/auth": "^7.0|^8.0|^9.0|^10.0",
+                "illuminate/container": "^7.0|^8.0|^9.0|^10.0",
+                "illuminate/contracts": "^7.0|^8.0|^9.0|^10.0",
+                "illuminate/database": "^7.0|^8.0|^9.0|^10.0",
+                "php": "^7.3|^8.0"
+            },
+            "require-dev": {
+                "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0",
+                "phpunit/phpunit": "^9.4",
+                "predis/predis": "^1.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "5.x-dev",
+                    "dev-master": "5.x-dev"
+                },
+                "laravel": {
+                    "providers": [
+                        "Spatie\\Permission\\PermissionServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/helpers.php"
+                ],
+                "psr-4": {
+                    "Spatie\\Permission\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Permission handling for Laravel 6.0 and up",
+            "homepage": "https://github.com/spatie/laravel-permission",
+            "keywords": [
+                "acl",
+                "laravel",
+                "permission",
+                "permissions",
+                "rbac",
+                "roles",
+                "security",
+                "spatie"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/laravel-permission/issues",
+                "source": "https://github.com/spatie/laravel-permission/tree/5.10.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2023-04-12T17:08:32+00:00"
+        },
         {
             "name": "spatie/laravel-query-builder",
             "version": "5.2.0",
diff --git a/config/permission.php b/config/permission.php
new file mode 100644
index 000000000..5b6e184c3
--- /dev/null
+++ b/config/permission.php
@@ -0,0 +1,161 @@
+<?php
+
+return [
+
+    'models' => [
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * Eloquent model should be used to retrieve your permissions. Of course, it
+         * is often just the "Permission" model but you may use whatever you like.
+         *
+         * The model you want to use as a Permission model needs to implement the
+         * `Spatie\Permission\Contracts\Permission` contract.
+         */
+
+        'permission' => Spatie\Permission\Models\Permission::class,
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * Eloquent model should be used to retrieve your roles. Of course, it
+         * is often just the "Role" model but you may use whatever you like.
+         *
+         * The model you want to use as a Role model needs to implement the
+         * `Spatie\Permission\Contracts\Role` contract.
+         */
+
+        'role' => Spatie\Permission\Models\Role::class,
+
+    ],
+
+    'table_names' => [
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your roles. We have chosen a basic
+         * default value but you may easily change it to any table you like.
+         */
+
+        'roles' => 'roles',
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * table should be used to retrieve your permissions. We have chosen a basic
+         * default value but you may easily change it to any table you like.
+         */
+
+        'permissions' => 'permissions',
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * table should be used to retrieve your models permissions. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'model_has_permissions' => 'model_has_permissions',
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your models roles. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'model_has_roles' => 'model_has_roles',
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your roles permissions. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'role_has_permissions' => 'role_has_permissions',
+    ],
+
+    'column_names' => [
+        /*
+         * Change this if you want to name the related pivots other than defaults
+         */
+        'role_pivot_key' => null, //default 'role_id',
+        'permission_pivot_key' => null, //default 'permission_id',
+
+        /*
+         * Change this if you want to name the related model primary key other than
+         * `model_id`.
+         *
+         * For example, this would be nice if your primary keys are all UUIDs. In
+         * that case, name this `model_uuid`.
+         */
+
+        'model_morph_key' => 'model_id',
+
+        /*
+         * Change this if you want to use the teams feature and your related model's
+         * foreign key is other than `team_id`.
+         */
+
+        'team_foreign_key' => 'team_id',
+    ],
+
+    /*
+     * When set to true, the method for checking permissions will be registered on the gate.
+     * Set this to false, if you want to implement custom logic for checking permissions.
+     */
+
+    'register_permission_check_method' => true,
+
+    /*
+     * When set to true the package implements teams using the 'team_foreign_key'. If you want
+     * the migrations to register the 'team_foreign_key', you must set this to true
+     * before doing the migration. If you already did the migration then you must make a new
+     * migration to also add 'team_foreign_key' to 'roles', 'model_has_roles', and
+     * 'model_has_permissions'(view the latest version of package's migration file)
+     */
+
+    'teams' => false,
+
+    /*
+     * When set to true, the required permission names are added to the exception
+     * message. This could be considered an information leak in some contexts, so
+     * the default setting is false here for optimum safety.
+     */
+
+    'display_permission_in_exception' => false,
+
+    /*
+     * When set to true, the required role names are added to the exception
+     * message. This could be considered an information leak in some contexts, so
+     * the default setting is false here for optimum safety.
+     */
+
+    'display_role_in_exception' => false,
+
+    /*
+     * By default wildcard permission lookups are disabled.
+     */
+
+    'enable_wildcard_permission' => false,
+
+    'cache' => [
+
+        /*
+         * By default all permissions are cached for 24 hours to speed up performance.
+         * When permissions or roles are updated the cache is flushed automatically.
+         */
+
+        'expiration_time' => \DateInterval::createFromDateString('24 hours'),
+
+        /*
+         * The cache key used to store all permissions.
+         */
+
+        'key' => 'spatie.permission.cache',
+
+        /*
+         * You may optionally indicate a specific cache driver to use for permission and
+         * role caching using any of the `store` drivers listed in the cache.php config
+         * file. Using 'default' here means to use the `default` set in cache.php.
+         */
+
+        'store' => 'default',
+    ],
+];
diff --git a/config/permissions_web.php b/config/permissions_web.php
new file mode 100644
index 000000000..accbd07a0
--- /dev/null
+++ b/config/permissions_web.php
@@ -0,0 +1,92 @@
+<?php
+
+return [
+    '*',
+
+    /*
+        * Permissions for admin
+        */
+    'admin.sidebar.read',
+
+    'admin.roles.read',
+    'admin.roles.write',
+
+
+    'admin.ticket.read',
+
+    'admin.ticket_blacklist.read',
+    'admin.ticket_blacklist.write',
+
+    'admin.overview.read',
+    'admin.overview.sync',
+
+    'admin.api.read',
+    'admin.api.write',
+
+    'admin.users.read',
+    'admin.users.write',
+    'admin.users.suspend',
+    'admin.users.write.credits',
+    'admin.users.write.username',
+    'admin.users.write.password',
+    'admin.users.write.role',
+    'admin.users.write.referal',
+    'admin.users.write.pterodactyl',
+
+    'admin.servers.read',
+    'admin.servers.write',
+    'admin.servers.suspend',
+    'admin.server.write.owner',
+    'admin.server.write.identifier',
+    'admin.server.delete',
+
+    'admin.products.read',
+    'admin.products.create',
+    'admin.products.edit',
+    'admin.products.delete',
+
+    'admin.store.read',
+    'admin.store.write',
+    'admin.store.disable',
+
+    'admin.voucher.read',
+    'admin.voucher.write',
+
+    'admin.useful_links.read',
+    'admin.useful_links.write',
+
+    'admin.legal.read',
+    'admin.legal.write',
+
+    'admin.logs.read',
+
+    /*
+     * Permissions for settings
+     */
+    'settings.sidebar.read',
+
+    'settings.invoices.read',
+    'settings.invoices.write',
+
+    'settings.language.read',
+    'settings.language.write',
+
+    'settings.misc.read',
+    'settings.misc.write',
+
+    'settings.payment.read',
+    'settings.payment.write',
+
+    'settings.system.read',
+    'settings.system.write',
+
+    /*
+    * Permissions for users
+    */
+    'user.server.create',
+    'user.server.upgrade',
+    'user.shop.buy',
+    'user.ticket.read',
+    'user.ticket.write',
+    'user.referral',
+];
diff --git a/database/migrations/2023_04_29_232942_create_permission_tables.php b/database/migrations/2023_04_29_232942_create_permission_tables.php
new file mode 100644
index 000000000..01f845157
--- /dev/null
+++ b/database/migrations/2023_04_29_232942_create_permission_tables.php
@@ -0,0 +1,142 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+use Spatie\Permission\PermissionRegistrar;
+
+class CreatePermissionTables extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        $tableNames = config('permission.table_names');
+        $columnNames = config('permission.column_names');
+        $teams = config('permission.teams');
+
+        if (empty($tableNames)) {
+            throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
+        }
+        if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
+            throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
+        }
+
+        Schema::create($tableNames['permissions'], function (Blueprint $table) {
+            $table->bigIncrements('id'); // permission id
+            $table->string('name');       // For MySQL 8.0 use string('name', 125);
+            $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
+            $table->timestamps();
+
+            $table->unique(['name', 'guard_name']);
+        });
+
+        Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
+            $table->bigIncrements('id'); // role id
+            if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
+                $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
+                $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
+            }
+            $table->string('name');       // For MySQL 8.0 use string('name', 125);
+            $table->string('color')->nullable()->default('#485460');       // For MySQL 8.0 use string('name', 125);
+            $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
+            $table->timestamps();
+            if ($teams || config('permission.testing')) {
+                $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
+            } else {
+                $table->unique(['name', 'guard_name']);
+            }
+        });
+
+        Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
+            $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission);
+
+            $table->string('model_type');
+            $table->unsignedBigInteger($columnNames['model_morph_key']);
+            $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
+
+            $table->foreign(PermissionRegistrar::$pivotPermission)
+                ->references('id') // permission id
+                ->on($tableNames['permissions'])
+                ->onDelete('cascade');
+            if ($teams) {
+                $table->unsignedBigInteger($columnNames['team_foreign_key']);
+                $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
+
+                $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_permissions_permission_model_type_primary');
+            } else {
+                $table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_permissions_permission_model_type_primary');
+            }
+
+        });
+
+        Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
+            $table->unsignedBigInteger(PermissionRegistrar::$pivotRole);
+
+            $table->string('model_type');
+            $table->unsignedBigInteger($columnNames['model_morph_key']);
+            $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
+
+            $table->foreign(PermissionRegistrar::$pivotRole)
+                ->references('id') // role id
+                ->on($tableNames['roles'])
+                ->onDelete('cascade');
+            if ($teams) {
+                $table->unsignedBigInteger($columnNames['team_foreign_key']);
+                $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
+
+                $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_roles_role_model_type_primary');
+            } else {
+                $table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_roles_role_model_type_primary');
+            }
+        });
+
+        Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
+            $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission);
+            $table->unsignedBigInteger(PermissionRegistrar::$pivotRole);
+
+            $table->foreign(PermissionRegistrar::$pivotPermission)
+                ->references('id') // permission id
+                ->on($tableNames['permissions'])
+                ->onDelete('cascade');
+
+            $table->foreign(PermissionRegistrar::$pivotRole)
+                ->references('id') // role id
+                ->on($tableNames['roles'])
+                ->onDelete('cascade');
+
+            $table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary');
+        });
+
+        app('cache')
+            ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
+            ->forget(config('permission.cache.key'));
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        $tableNames = config('permission.table_names');
+
+        if (empty($tableNames)) {
+            throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
+        }
+
+        Schema::drop($tableNames['role_has_permissions']);
+        Schema::drop($tableNames['model_has_roles']);
+        Schema::drop($tableNames['model_has_permissions']);
+        Schema::drop($tableNames['roles']);
+        Schema::drop($tableNames['permissions']);
+    }
+}
diff --git a/database/migrations/2023_04_29_233120_drop_roles.php b/database/migrations/2023_04_29_233120_drop_roles.php
new file mode 100644
index 000000000..3f3657077
--- /dev/null
+++ b/database/migrations/2023_04_29_233120_drop_roles.php
@@ -0,0 +1,51 @@
+<?php
+
+use App\Models\User;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Artisan;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Artisan::call('db:seed', [
+            '--class' => 'PermissionsSeeder',
+        ]);
+
+        Schema::table('users', function ($table) {
+            $table->dropColumn('role');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function($table) {
+            $table->string('role')->default('member');
+        });
+
+        $users = User::with('roles')->get();
+        foreach($users as $user){
+            if($user->hasRole(1)){
+                $user->role = "admin";
+            }elseif ($user->hasRole(3)){
+                $user->role = "client";
+            }else{
+                $user->role = "member";
+            }
+            $user->save();
+        }
+
+    }
+};
diff --git a/database/seeders/PermissionsSeeder.php b/database/seeders/PermissionsSeeder.php
new file mode 100644
index 000000000..7d6ebc062
--- /dev/null
+++ b/database/seeders/PermissionsSeeder.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\User;
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Spatie\Permission\Models\Permission;
+use Spatie\Permission\Models\Role;
+
+class PermissionsSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     *
+     * @return void
+     */
+    public function run()
+    {
+
+        $this->createPermissions();
+        $this->createRoles();
+
+
+        $users = User::all();
+        foreach($users as $user){
+            $user->assignRole(4);
+        }
+
+        $admins = User::where("role","admin")->get();
+        foreach($admins as $admin) {
+            $admin->syncRoles(1);
+        }
+
+        $admins = User::where("role","client")->get();
+        foreach($admins as $admin) {
+            $admin->syncRoles(3);
+        }
+
+
+
+
+    }
+
+    public function createPermissions()
+    {
+        foreach (config('permissions_web') as $name) {
+            Permission::findOrCreate($name);
+        }
+    }
+
+    //TODO run only once
+    public function createRoles()
+    {
+        $userPermissions=[
+            'user.server.create',
+            'user.server.upgrade',
+            'user.shop.buy',
+            'user.ticket.read',
+            'user.ticket.write',
+            'user.referral',
+        ];
+        /** @var Role $adminRole */
+        $adminRole = Role::updateOrCreate(["name"=>"Admin","color"=>"#fa0000"]);
+        $supportRole = Role::updateOrCreate(["name"=>"Support-Team","color"=>"#00b0b3"]);
+        $clientRole = Role::updateOrCreate(["name"=>"Client","color"=>"#008009"]);
+        $userRole =  Role::updateOrCreate(["name"=>"User","color"=>"#0052a3"]);
+
+        $adminRole->givePermissionTo(Permission::findByName('*'));
+
+        $userRole->syncPermissions($userPermissions);
+        $clientRole->syncPermissions($userPermissions);
+    }
+}
diff --git a/public/install/forms.php b/public/install/forms.php
index 762222c6d..d6d72b92c 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -292,9 +292,9 @@
     }
 
     $random = generateRandomString();
-    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
-
-    if ($db->query($query1)) {
+    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
+    $query2 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\Models\User', '1')";
+    if ($db->query($query1) && $db->query($query2)) {
         wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID, 'info');
         header('LOCATION: index.php?step=7');
     } else {
diff --git a/routes/web.php b/routes/web.php
index 438b4dd5c..f13a33a99 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -13,6 +13,7 @@
 use App\Http\Controllers\Admin\PartnerController;
 use App\Http\Controllers\Admin\PaymentController;
 use App\Http\Controllers\Admin\ProductController;
+use App\Http\Controllers\Admin\RoleController;
 use App\Http\Controllers\Admin\ServerController as AdminServerController;
 use App\Http\Controllers\Admin\SettingsController;
 use App\Http\Controllers\Admin\ShopProductController;
@@ -117,7 +118,9 @@
 
     //admin
     Route::prefix('admin')->name('admin.')->middleware('admin')->group(function () {
-
+        //Roles
+        Route::get('roles/datatable', [RoleController::class, 'datatable'])->name('roles.datatable');
+        Route::resource('roles', RoleController::class);
         //overview
         Route::get('legal', [OverViewController::class, 'index'])->name('overview.index');
 
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index f965da56a..a5c13de11 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -253,7 +253,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                         </li>
                     @endif
 
-                    @if ((Auth::user()->role == 'admin' || Auth::user()->role == 'moderator') && config('SETTINGS::TICKET:ENABLED'))
+                    @if ((Auth::user()->hasRole("Admin") || Auth::user()->role == 'moderator') && config('SETTINGS::TICKET:ENABLED'))
                         <li class="nav-header">{{ __('Moderation') }}</li>
 
                         <li class="nav-item">
@@ -272,7 +272,7 @@ class="nav-link @if (Request::routeIs('moderator.ticket.blacklist')) active @end
                         </li>
                     @endif
 
-                    @if (Auth::user()->role == 'admin')
+                    @if (Auth::user()->hasRole("Admin"))
                         <li class="nav-header">{{ __('Administration') }}</li>
 
                         <li class="nav-item">
diff --git a/themes/default/views/admin/roles/edit.blade.php b/themes/default/views/admin/roles/edit.blade.php
new file mode 100644
index 000000000..2abbe8087
--- /dev/null
+++ b/themes/default/views/admin/roles/edit.blade.php
@@ -0,0 +1,54 @@
+@extends('layouts.main')
+
+@section('content')
+    <div class="main py-4">
+
+        <div class="card card-body border-0 shadow table-wrapper table-responsive">
+            <h2 class="mb-4 h5">{{ isset($role) ?  __('Edit role') : __('Create role') }}</h2>
+
+            <form method="post"
+                  action="{{isset($role) ? route('admin.roles.update', $role->id) : route('admin.roles.store')}}">
+                @csrf
+                @isset($role)
+                    @method('PATCH')
+                @endisset
+
+                <div class="row">
+                    <div class="col-lg-6">
+
+                        <x-input.text label="{{(__('Name'))}}"
+                                      name="name"
+                                      value="{{ isset($role) ? $role->name : null}}"/>
+
+                        <x-input.text label="{{(__('Badge color'))}}"
+                                      type="color"
+                                      name="color"
+                                      value="{{ isset($role) ? $role->color : null}}"/>
+
+                    </div>
+
+                    <div class="col-lg-6">
+
+                        <x-input.select
+                            label="{{(__('Permissions'))}}"
+                            name="permissions"
+                            style="height: 200px"
+                            multiple>
+                            @foreach($permissions as $permission)
+                                <option @if(isset($role) && $role->permissions->contains($permission)) selected
+                                        @endif value="{{$permission->id}}">{{$permission->name}}</option>
+                            @endforeach
+                        </x-input.select>
+
+                    </div>
+                </div>
+
+                <div class="form-group d-flex justify-content-end mt-3">
+                    <button name="submit" type="submit" class="btn btn-primary">{{__('Submit')}}</button>
+                </div>
+            </form>
+
+        </div>
+
+    </div>
+@endsection
diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
new file mode 100644
index 000000000..71c88d92f
--- /dev/null
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -0,0 +1,58 @@
+@extends('layouts.main')
+
+@section('content')
+    <div class="main py-4">
+
+        @can('admin.roles.write')
+            <div class="d-flex justify-content-end my-3">
+                <a href="{{route('admin.roles.create')}}" class="btn btn-primary"><i
+                        class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
+            </div>
+        @endcan
+
+        <div class="card card-body border-0 shadow table-wrapper table-responsive">
+            <h2 class="mb-4 h5">{{ __('Roles') }}</h2>
+
+            <div class="card-body table-responsive">
+
+                <table id="datatable" class="table table-striped">
+                    <thead>
+                    <tr>
+                        <th>{{__("Name")}}</th>
+                        <th>{{__("User count")}}</th>
+                        <th>{{__("Permissions count")}}</th>
+                        <th>{{__("Actions")}}</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    </tbody>
+                </table>
+
+            </div>
+        </div>
+    </div>
+@endsection
+<script>
+
+    document.addEventListener("DOMContentLoaded", function () {
+        $('#datatable').DataTable({
+            language: {
+                url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
+            },
+            processing: true,
+            serverSide: false, //increases loading times too much? change back to "true" if it does
+            stateSave: true,
+            ajax: "{{route('admin.roles.datatable')}}",
+            columns: [
+                {data: 'name'},
+                {data: 'usercount'},
+                {data: 'permissionscount'},
+                {data: 'actions' , sortable : false},
+            ],
+            fnDrawCallback: function( oSettings ) {
+                $('[data-toggle="popover"]').popover();
+            }
+        });
+    });
+</script>
+
diff --git a/themes/default/views/admin/users/edit.blade.php b/themes/default/views/admin/users/edit.blade.php
index 94c157857..b4c840bfc 100644
--- a/themes/default/views/admin/users/edit.blade.php
+++ b/themes/default/views/admin/users/edit.blade.php
@@ -97,24 +97,14 @@ class="form-control @error('server_limit') is-invalid @enderror"
                                 <div class="form-group">
                                     <label for="role">{{__('Role')}}</label>
                                     <div>
-                                        <select id="role" name="role"
+                                        <select id="roles" name="roles"
                                                 class="custom-select @error('role') is-invalid @enderror"
                                                 required="required">
-                                            <option @if($user->role == 'admin') selected @endif class="text-danger"
-                                                    value="admin">
-                                        {{__(' Administrator')}}
-                                     </option>
-                                     <option @if($user->role == 'moderator') selected @endif class="text-info" value="moderator">
-                                        {{__('Moderator')}}
-                                     </option>
-                                     <option @if($user->role == 'client') selected @endif class="text-success"
-                                             value="client">
-                                        {{__('Client')}}
-                                    </option>
-                                    <option @if($user->role == 'member') selected @endif class="text-secondary"
-                                            value="member">
-                                        {{__('Member')}}
-                                    </option>
+                                            @foreach($roles as $role)
+                                                <option style="color: {{$role->color}}"
+                                                        @if(isset($user) && $user->roles->contains($role)) selected
+                                                        @endif value="{{$role->id}}">{{$role->name}}</option>
+                                            @endforeach
                                 </select>
                             </div>
                                 </div>
diff --git a/themes/default/views/admin/users/show.blade.php b/themes/default/views/admin/users/show.blade.php
index e02baef32..5d2da4120 100644
--- a/themes/default/views/admin/users/show.blade.php
+++ b/themes/default/views/admin/users/show.blade.php
@@ -76,7 +76,7 @@
                                 <div class="col-lg-8">
                                     <span style="max-width: 250px;"
                                         class="d-inline-block text-truncate badge
-                                        @if ($user->role == 'admin') badge-danger
+                                        @if ($user->hasRole("Admin")) badge-danger
                                         @elseif ($user->role == 'moderator')
                                             badge-info
                                         @elseif ($user->role == 'client')
diff --git a/themes/default/views/home.blade.php b/themes/default/views/home.blade.php
index 8f106c949..119c50ffe 100644
--- a/themes/default/views/home.blade.php
+++ b/themes/default/views/home.blade.php
@@ -18,7 +18,7 @@
     </section>
     <!-- END CONTENT HEADER -->
 
-    @if (!file_exists(base_path() . '/install.lock') && Auth::User()->role == 'admin')
+    @if (!file_exists(base_path() . '/install.lock') && Auth::User()->hasRole("Admin"))
         <div class="callout callout-danger">
             <h4>{{ __('The installer is not locked!') }}</h4>
             <p>{{ __('please create a file called "install.lock" in your dashboard Root directory. Otherwise no settings will be loaded!') }}
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 6e1f6f01e..607a692c6 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -255,7 +255,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                             </li>
                         @endif
 
-                        @if ((Auth::user()->role == 'admin' || Auth::user()->role == 'moderator') && $ticket_enabled)
+                        @if ((Auth::user()->hasRole("Admin") || Auth::user()->role == 'moderator') && $ticket_enabled)
                             <li class="nav-header">{{ __('Moderation') }}</li>
 
                             <li class="nav-item">
@@ -274,7 +274,7 @@ class="nav-link @if (Request::routeIs('moderator.ticket.blacklist')) active @end
                             </li>
                         @endif
 
-                        @if (Auth::user()->role == 'admin')
+                        @if (Auth::user()->hasRole("Admin"))
                             <li class="nav-header">{{ __('Administration') }}</li>
 
                             <li class="nav-item">
@@ -285,6 +285,13 @@ class="nav-link @if (Request::routeIs('admin.overview.*')) active @endif">
                                 </a>
                             </li>
 
+                            <li class="nav-item">
+                                <a href="{{ route('admin.roles.index') }}"
+                                   class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
+                                    <i class="nav-icon fa fa-user-check"></i>
+                                    <p>{{ __('Role Management') }}</p>
+                                </a>
+                            </li>
 
                             <li class="nav-item">
                                 <a href="{{ route('admin.settings.index') }}"
diff --git a/themes/default/views/moderator/ticket/show.blade.php b/themes/default/views/moderator/ticket/show.blade.php
index b7d992b52..18c69e2fc 100644
--- a/themes/default/views/moderator/ticket/show.blade.php
+++ b/themes/default/views/moderator/ticket/show.blade.php
@@ -118,7 +118,7 @@ class="user-image" alt="User Image">
                                             <span class="badge badge-success"> Client </span>
                                         @elseif ($ticket->user->role === "moderator")
                                             <span class="badge badge-info"> Moderator </span>
-                                        @elseif ($ticket->user->role === "admin")
+                                        @elseif ($ticket->user->hasRole("Admin"))
                                             <span class="badge badge-danger"> Admin </span>
                                         @endif
                                     </h5>
@@ -141,7 +141,7 @@ class="user-image" alt="User Image">
                                             <span class="badge badge-success"> Client </span>
                                         @elseif ($ticketcomment->user->role === "moderator")
                                             <span class="badge badge-info"> Moderator </span>
-                                        @elseif ($ticketcomment->user->role === "admin")
+                                        @elseif ($ticketcomment->user->hasRole("Admin"))
                                             <span class="badge badge-danger"> Admin </span>
                                         @endif
                                     </h5>
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 5f5a03147..f8e9a5d40 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -45,7 +45,7 @@ class="row justify-content-center">
                             <div class="alert alert-danger p-2 m-2">
                                 <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Error!') }}</h5>
                                 <p class="pl-4">
-                                    @if (Auth::user()->role == 'admin')
+                                    @if (Auth::user()->hasRole("Admin"))
                                         {{ __('Make sure to link your products to nodes and eggs.') }} <br>
                                         {{ __('There has to be at least 1 valid product for server creation') }}
                                         <a href="{{ route('admin.overview.sync') }}">{{ __('Sync now') }}</a>
diff --git a/themes/default/views/ticket/show.blade.php b/themes/default/views/ticket/show.blade.php
index cac0070df..663b25f32 100644
--- a/themes/default/views/ticket/show.blade.php
+++ b/themes/default/views/ticket/show.blade.php
@@ -118,7 +118,7 @@ class="user-image" alt="User Image">
                                                 <span class="badge badge-success"> Client </span>
                                             @elseif ($ticket->user->role === "moderator")
                                                 <span class="badge badge-info"> Moderator </span>
-                                            @elseif ($ticket->user->role === "admin")
+                                            @elseif ($ticket->user->hasRole("Admin"))
                                                 <span class="badge badge-danger"> Admin </span>
                                             @endif
                                         </h5>
@@ -142,7 +142,7 @@ class="user-image" alt="User Image">
                                                     <span class="badge badge-success"> Client </span>
                                                 @elseif ($ticketcomment->user->role === "moderator")
                                                     <span class="badge badge-info"> Moderator </span>
-                                                @elseif ($ticketcomment->user->role === "admin")
+                                                @elseif ($ticketcomment->user->hasRole("Admin"))
                                                     <span class="badge badge-danger"> Admin </span>
                                                 @endif
                                             </h5>

From 490bc64f414d4d58ba39f3017af1b661e2dcbe76 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 02:34:11 +0200
Subject: [PATCH 108/514] basic roles

---
 app/Http/Controllers/Admin/UserController.php | 29 +++++++++----------
 app/Http/Controllers/ProfileController.php    | 15 ----------
 .../default/views/admin/users/edit.blade.php  |  2 +-
 themes/default/views/profile/index.blade.php  |  6 ++--
 4 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index a7e494a9c..caf8fafd4 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -26,6 +26,7 @@
 use Illuminate\Validation\Rule;
 use Illuminate\Validation\ValidationException;
 use Spatie\QueryBuilder\QueryBuilder;
+use Spatie\Permission\Models\Role;
 
 class UserController extends Controller
 {
@@ -108,9 +109,11 @@ public function json(Request $request)
      */
     public function edit(User $user, GeneralSettings $general_settings)
     {
+        $roles = Role::all();
         return view('admin.users.edit')->with([
             'user' => $user,
-            'credits_display_name' => $general_settings->credits_display_name
+            'credits_display_name' => $general_settings->credits_display_name,
+            'roles' => $roles
         ]);
     }
 
@@ -135,6 +138,11 @@ public function update(Request $request, User $user)
             'referral_code' => "required|string|min:2|max:32|unique:users,referral_code,{$user->id}",
         ]);
 
+        //update roles
+        if ($request->roles) {
+            $user->syncRoles($request->roles);
+        }
+
         if (isset($this->pterodactyl->getUser($request->input('pterodactyl_id'))['errors'])) {
             throw ValidationException::withMessages([
                 'pterodactyl_id' => [__("User does not exists on pterodactyl's panel")],
@@ -329,22 +337,13 @@ public function dataTable(Request $request)
                 ';
             })
             ->editColumn('role', function (User $user) {
-                switch ($user->role) {
-                    case 'admin':
-                        $badgeColor = 'badge-danger';
-                        break;
-                    case 'moderator':
-                        $badgeColor = 'badge-info';
-                        break;
-                    case 'client':
-                        $badgeColor = 'badge-success';
-                        break;
-                    default:
-                        $badgeColor = 'badge-secondary';
-                        break;
+                $html = '';
+
+                foreach ($user->roles as $role) {
+                    $html .= "<span style='background-color: $role->color' class='badge'>$role->name</span>";
                 }
 
-                return '<span class="badge ' . $badgeColor . '">' . $user->role . '</span>';
+                return $html;
             })
             ->editColumn('last_seen', function (User $user) {
                 return $user->last_seen ? $user->last_seen->diffForHumans() : __('Never');
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 5c4293aed..8a0425016 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -26,27 +26,12 @@ public function __construct(PterodactylSettings $ptero_settings)
     /** Display a listing of the resource. */
     public function index(UserSettings $user_settings, DiscordSettings $discord_settings, ReferralSettings $referral_settings)
     {
-        switch (Auth::user()->role) {
-            case 'admin':
-                $badgeColor = 'badge-danger';
-                break;
-            case 'mod':
-                $badgeColor = 'badge-info';
-                break;
-            case 'client':
-                $badgeColor = 'badge-success';
-                break;
-            default:
-                $badgeColor = 'badge-secondary';
-                break;
-        }
 
         return view('profile.index')->with([
             'user' => Auth::user(),
             'credits_reward_after_verify_discord' => $user_settings->credits_reward_after_verify_discord,
             'force_email_verification' => $user_settings->force_email_verification,
             'force_discord_verification' => $user_settings->force_discord_verification,
-            'badgeColor' => $badgeColor,
             'discord_client_id' => $discord_settings->client_id,
             'discord_client_secret' => $discord_settings->client_secret,
             'referral_enabled' => $referral_settings->enabled,
diff --git a/themes/default/views/admin/users/edit.blade.php b/themes/default/views/admin/users/edit.blade.php
index b4c840bfc..221571918 100644
--- a/themes/default/views/admin/users/edit.blade.php
+++ b/themes/default/views/admin/users/edit.blade.php
@@ -105,7 +105,7 @@ class="custom-select @error('role') is-invalid @enderror"
                                                         @if(isset($user) && $user->roles->contains($role)) selected
                                                         @endif value="{{$role->id}}">{{$role->name}}</option>
                                             @endforeach
-                                </select>
+                                        </select>
                             </div>
                                 </div>
                                     <div class="form-group">
diff --git a/themes/default/views/profile/index.blade.php b/themes/default/views/profile/index.blade.php
index 82d09e145..6fe0208b6 100644
--- a/themes/default/views/profile/index.blade.php
+++ b/themes/default/views/profile/index.blade.php
@@ -118,8 +118,10 @@ class="fa fa-user-check mr-2"></i>
                                         @endif
                                         </div>
 
-                                        <div class="text-center text-sm-right"><span
-                                                class="badge {{$badgeColor}}">{{ $user->role }}</span>
+                                        <div class="text-center text-sm-right">
+                                            @foreach ($user->roles as $role)
+                                                <span style='background-color: {{$role->color}}' class='badge'>{{$role->name}}</span>
+                                            @endforeach
                                             <div class="text-muted">
                                                 <small>{{ $user->created_at->isoFormat('LL') }}</small>
                                             </div>

From 83d7590b600ad77c6305126b923c6c2ef03c4673 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 12:13:01 +0200
Subject: [PATCH 109/514] fix installer, new users get role

---
 .../Controllers/Auth/RegisterController.php   |  2 +
 .../2023_04_03_231829_update_users_table.php  |  2 +-
 .../2023_04_29_233120_drop_roles.php          | 51 -------------------
 database/seeders/PermissionsSeeder.php        | 11 ++--
 public/install/forms.php                      | 10 ++--
 5 files changed, 18 insertions(+), 58 deletions(-)
 delete mode 100644 database/migrations/2023_04_29_233120_drop_roles.php

diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php
index 29a4b6e0a..9f1e8019b 100644
--- a/app/Http/Controllers/Auth/RegisterController.php
+++ b/app/Http/Controllers/Auth/RegisterController.php
@@ -139,6 +139,8 @@ protected function create(array $data)
 
         ]);
 
+        $user->syncRoles(4);
+
         $response = $this->pterodactyl->application->post('/application/users', [
             'external_id' => $user->pterodactyl_id,
             'username' => $user->name,
diff --git a/database/migrations/2023_04_03_231829_update_users_table.php b/database/migrations/2023_04_03_231829_update_users_table.php
index 3caf98aa0..df2497417 100644
--- a/database/migrations/2023_04_03_231829_update_users_table.php
+++ b/database/migrations/2023_04_03_231829_update_users_table.php
@@ -26,7 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->integer('pterodactyl_id')->nullable->change();
+            $table->integer('pterodactyl_id')->nullable()->change();
         });
     }
 };
diff --git a/database/migrations/2023_04_29_233120_drop_roles.php b/database/migrations/2023_04_29_233120_drop_roles.php
deleted file mode 100644
index 3f3657077..000000000
--- a/database/migrations/2023_04_29_233120_drop_roles.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-use App\Models\User;
-use Illuminate\Database\Migrations\Migration;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Support\Facades\Artisan;
-use Illuminate\Support\Facades\Schema;
-
-return new class extends Migration
-{
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        Artisan::call('db:seed', [
-            '--class' => 'PermissionsSeeder',
-        ]);
-
-        Schema::table('users', function ($table) {
-            $table->dropColumn('role');
-        });
-    }
-
-    /**
-     * Reverse the migrations.
-     *
-     * @return void
-     */
-    public function down()
-    {
-        Schema::table('users', function($table) {
-            $table->string('role')->default('member');
-        });
-
-        $users = User::with('roles')->get();
-        foreach($users as $user){
-            if($user->hasRole(1)){
-                $user->role = "admin";
-            }elseif ($user->hasRole(3)){
-                $user->role = "client";
-            }else{
-                $user->role = "member";
-            }
-            $user->save();
-        }
-
-    }
-};
diff --git a/database/seeders/PermissionsSeeder.php b/database/seeders/PermissionsSeeder.php
index 7d6ebc062..e688bdf07 100644
--- a/database/seeders/PermissionsSeeder.php
+++ b/database/seeders/PermissionsSeeder.php
@@ -32,9 +32,14 @@ public function run()
             $admin->syncRoles(1);
         }
 
-        $admins = User::where("role","client")->get();
-        foreach($admins as $admin) {
-            $admin->syncRoles(3);
+        $mods = User::where("role","moderator")->get();
+        foreach($mods as $mod) {
+            $mod->syncRoles(2);
+        }
+
+        $clients = User::where("role","client")->get();
+        foreach($clients as $client) {
+            $client->syncRoles(3);
         }
 
 
diff --git a/public/install/forms.php b/public/install/forms.php
index d6d72b92c..726e22ec3 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -1,5 +1,7 @@
 <?php
-
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
+error_reporting(E_ALL);
 
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\PHPMailer;
@@ -77,6 +79,7 @@
     $logs .= run_console('php artisan storage:link');
     $logs .= run_console('php artisan migrate --seed --force');
     $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
+    $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
 
     wh_log($logs, 'debug');
 
@@ -292,8 +295,9 @@
     }
 
     $random = generateRandomString();
-    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
-    $query2 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\Models\User', '1')";
+
+    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
+    $query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
     if ($db->query($query1) && $db->query($query2)) {
         wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID, 'info');
         header('LOCATION: index.php?step=7');

From fd2e65f8b318fbc0250e8ab19f426653ec18224c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 12:15:42 +0200
Subject: [PATCH 110/514] fix rolecontroller

---
 app/Http/Controllers/Admin/RoleController.php | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 22a8c113f..4962b2658 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -3,6 +3,7 @@
 namespace App\Http\Controllers\Admin;
 
 use App\Http\Controllers\Controller;
+use App\Models\User;
 use Exception;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\View\Factory;
@@ -105,7 +106,7 @@ public function update(Request $request, Role $role)
             }
         }
 
-        if($role->id == 3 || $role->id == 1 || $role->id == 4){ //dont let the user change the names of these roles
+        if($role->id == 1 || $role->id == 3 || $role->id == 4){ //dont let the user change the names of these roles
             $role->update([
                 'color' => $request->color
             ]);
@@ -135,14 +136,15 @@ public function update(Request $request, Role $role)
     public function destroy(Role $role)
     {
 
-        if($role->id == 3 || $role->id == 1 || $role->id == 2){ //cannot delete the hard coded roles
+        if($role->id == 1 || $role->id == 3 || $role->id == 4){ //cannot delete the hard coded roles
             return back()->with("error","You cannot delete that role");
         }
 
         $users = User::role($role)->get();
 
         foreach($users as $user){
-            $user->syncRoles(['Member']);
+            //$user->syncRoles(['Member']);
+            $user->syncRoles(4);
         }
 
         $role->delete();

From c9c991d16406ab580befbe0a0a0e5fa02b87c1d5 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 12:17:02 +0200
Subject: [PATCH 111/514] allow editing name of member and admin. should be
 fine. we are using IDs

---
 app/Http/Controllers/Admin/RoleController.php | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 4962b2658..d5d474af8 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -106,26 +106,26 @@ public function update(Request $request, Role $role)
             }
         }
 
-        if($role->id == 1 || $role->id == 3 || $role->id == 4){ //dont let the user change the names of these roles
-            $role->update([
-                'color' => $request->color
-            ]);
-        }else{
+        //if($role->id == 1 || $role->id == 3 || $role->id == 4){ //dont let the user change the names of these roles
+        //    $role->update([
+        //        'color' => $request->color
+        //    ]);
+        //}else{
             $role->update([
                 'name' => $request->name,
                 'color' => $request->color
             ]);
-        }
+        //}
 
-        if($role->id == 1){
-            return redirect()->route('admin.roles.index')->with('success', __('Role updated. Name and Permissions of this Role cannot be changed'));
-        }elseif($role->id == 4 || $role->id == 3){
-            return redirect()->route('admin.roles.index')->with('success', __('Role updated. Name of this Role cannot be changed'));
-        }else{
+        //if($role->id == 1){
+        //    return redirect()->route('admin.roles.index')->with('success', __('Role updated. Name and Permissions of this Role cannot be changed'));
+        //}elseif($role->id == 4 || $role->id == 3){
+        //    return redirect()->route('admin.roles.index')->with('success', __('Role updated. Name of this Role cannot be changed'));
+       // }else{
             return redirect()
                 ->route('admin.roles.index')
                 ->with('success', __('Role saved'));
-        }
+        //}
     }
 
     /**

From e8c8d1c68d5910b1bf9ee5694c6a4f4928e06ec2 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 30 Apr 2023 12:21:01 +0200
Subject: [PATCH 112/514] Use IDs instead of Role Names

---
 app/Http/Middleware/isAdmin.php             | 3 ++-
 themes/default/views/layouts/main.blade.php | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/app/Http/Middleware/isAdmin.php b/app/Http/Middleware/isAdmin.php
index 1bf4f55af..6e8202a43 100644
--- a/app/Http/Middleware/isAdmin.php
+++ b/app/Http/Middleware/isAdmin.php
@@ -18,7 +18,8 @@ class isAdmin
      */
     public function handle(Request $request, Closure $next)
     {
-        if (Auth::user() && Auth::user()->hasRole("Admin")) {
+        //if (Auth::user() && Auth::user()->hasRole("Admin")) {
+        if (Auth::user() && Auth::user()->hasRole(1)) {
             return $next($request);
         }
 
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 607a692c6..6925c9366 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -255,7 +255,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                             </li>
                         @endif
 
-                        @if ((Auth::user()->hasRole("Admin") || Auth::user()->role == 'moderator') && $ticket_enabled)
+                        @if ((Auth::user()->hasRole(1) || Auth::user()->role == 'moderator') && $ticket_enabled)
                             <li class="nav-header">{{ __('Moderation') }}</li>
 
                             <li class="nav-item">
@@ -274,7 +274,7 @@ class="nav-link @if (Request::routeIs('moderator.ticket.blacklist')) active @end
                             </li>
                         @endif
 
-                        @if (Auth::user()->hasRole("Admin"))
+                        @if (Auth::user()->hasRole(1))
                             <li class="nav-header">{{ __('Administration') }}</li>
 
                             <li class="nav-item">

From eb3afbfaaba9660b1de264e2b68d801e72a13191 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 3 May 2023 09:53:41 +0200
Subject: [PATCH 113/514] full user permissions

---
 app/Http/Controllers/Admin/PaymentController.php |  3 +++
 app/Http/Controllers/Admin/RoleController.php    |  3 +++
 app/Http/Controllers/ServerController.php        |  8 ++++++++
 app/Http/Controllers/TicketsController.php       |  4 ++++
 config/permission.php                            |  2 +-
 themes/default/views/admin/roles/index.blade.php |  4 +++-
 .../default/views/admin/settings/index.blade.php |  4 ++++
 themes/default/views/layouts/main.blade.php      |  2 ++
 themes/default/views/profile/index.blade.php     |  6 +++---
 themes/default/views/servers/index.blade.php     | 16 ++++++++--------
 themes/default/views/servers/settings.blade.php  |  2 +-
 themes/default/views/store/index.blade.php       |  2 +-
 themes/default/views/ticket/index.blade.php      |  4 ++--
 13 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 25d2c9ceb..02d91bde9 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -23,6 +23,7 @@
 
 class PaymentController extends Controller
 {
+    const BUY_PERMISSION = 'user.shop.buy';
     /**
      * @return Application|Factory|View
      */
@@ -41,6 +42,8 @@ public function index(LocaleSettings $locale_settings)
      */
     public function checkOut(ShopProduct $shopProduct, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::BUY_PERMISSION);
+
         $discount = PartnerDiscount::getDiscount();
         $price = $shopProduct->price - ($shopProduct->price * $discount / 100);
 
diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index d5d474af8..ed4194bee 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -164,6 +164,9 @@ public function dataTable()
 
 
         return datatables($query)
+            ->editColumn('id', function (Role $role) {
+                return $role->id;
+            })
             ->addColumn('actions', function (Role $role) {
                 return '
                             <a title="Edit" href="'.route("admin.roles.edit", $role).'" class="btn btn-sm btn-info"><i
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 9683e2b3e..acd4392e3 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -15,6 +15,7 @@
 use App\Classes\PterodactylClient;
 use App\Settings\GeneralSettings;
 use Exception;
+use GuzzleHttp\Promise\Create;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Client\Response;
 use Illuminate\Http\RedirectResponse;
@@ -24,6 +25,9 @@
 
 class ServerController extends Controller
 {
+    const CREATE_PERMISSION = 'user.server.create';
+    const UPGRADE_PERMISSION = 'user.server.upgrade';
+
     private $pterodactyl;
 
     public function __construct(PterodactylSettings $ptero_settings)
@@ -81,6 +85,8 @@ public function index(GeneralSettings $general_settings, PterodactylSettings $pt
     /** Show the form for creating a new resource. */
     public function create(UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::CREATE_PERMISSION);
+
         $validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings);
 
         if (!is_null($validate_configuration)) {
@@ -316,6 +322,8 @@ public function show(Server $server, ServerSettings $server_settings, GeneralSet
 
     public function upgrade(Server $server, Request $request)
     {
+        $this->checkPermission(self::UPGRADE_PERMISSION);
+
         if ($server->user_id != Auth::user()->id) {
             return redirect()->route('servers.index');
         }
diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index 754241edd..d5912e435 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -21,6 +21,8 @@
 
 class TicketsController extends Controller
 {
+    const READ_PERMISSION = 'user.ticket.read';
+    const WRITE_PERMISSION = 'user.ticket.write';
     public function index(LocaleSettings $locale_settings)
     {
         return view('ticket.index', [
@@ -74,6 +76,7 @@ public function store(Request $request, TicketSettings $ticket_settings)
 
     public function show($ticket_id, PterodactylSettings $ptero_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
         try {
             $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
         } catch (Exception $e) {
@@ -118,6 +121,7 @@ public function reply(Request $request)
 
     public function create()
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         //check in blacklist
         $check = TicketBlacklist::where('user_id', Auth::user()->id)->first();
         if ($check && $check->status == 'True') {
diff --git a/config/permission.php b/config/permission.php
index 5b6e184c3..5aeaab7c8 100644
--- a/config/permission.php
+++ b/config/permission.php
@@ -133,7 +133,7 @@
      * By default wildcard permission lookups are disabled.
      */
 
-    'enable_wildcard_permission' => false,
+    'enable_wildcard_permission' => true,
 
     'cache' => [
 
diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
index 71c88d92f..0bc9d3a2e 100644
--- a/themes/default/views/admin/roles/index.blade.php
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -18,6 +18,7 @@ class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
                 <table id="datatable" class="table table-striped">
                     <thead>
                     <tr>
+                        <th>{{__("ID")}}</th>
                         <th>{{__("Name")}}</th>
                         <th>{{__("User count")}}</th>
                         <th>{{__("Permissions count")}}</th>
@@ -40,10 +41,11 @@ class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
                 url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
             },
             processing: true,
-            serverSide: false, //increases loading times too much? change back to "true" if it does
+            serverSide: true, //increases loading times too much? change back to "true" if it does
             stateSave: true,
             ajax: "{{route('admin.roles.datatable')}}",
             columns: [
+                {data: 'id'},
                 {data: 'name'},
                 {data: 'usercount'},
                 {data: 'permissionscount'},
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 89249eac9..134e0a959 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -159,6 +159,9 @@ class="custom-select w-100" name="{{ $key }}"
                                                     </div>
                                                 </div>
                                             @endforeach
+
+                                            <!-- TODO: Display this only on the General tab
+
                                             <div class="row">
                                                 <div class="col-4 d-flex align-items-center">
                                                     <label for="recaptcha_preview">{{__("ReCAPTCHA Preview")}}</label>
@@ -179,6 +182,7 @@ class="custom-select w-100" name="{{ $key }}"
                                                         </div>
                                                 </div>
                                             </div>
+                                               -->
 
 
                                             <div class="row">
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 6925c9366..c72187bd9 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -246,6 +246,7 @@ class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')
                         @endif
                         @php($ticket_enabled = app(App\Settings\TicketSettings::class)->enabled)
                         @if ($ticket_enabled)
+                            @canany(["user.ticket.read", "user.ticket.write"])
                             <li class="nav-item">
                                 <a href="{{ route('ticket.index') }}"
                                     class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
@@ -253,6 +254,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                                     <p>{{ __('Support Ticket') }}</p>
                                 </a>
                             </li>
+                                @endcanany
                         @endif
 
                         @if ((Auth::user()->hasRole(1) || Auth::user()->role == 'moderator') && $ticket_enabled)
diff --git a/themes/default/views/profile/index.blade.php b/themes/default/views/profile/index.blade.php
index 6fe0208b6..459384379 100644
--- a/themes/default/views/profile/index.blade.php
+++ b/themes/default/views/profile/index.blade.php
@@ -101,7 +101,7 @@ class="fa fa-coins mr-2"></i>{{ $user->Credits() }}</span>
                                         </div>
 
                                     @if($referral_enabled)
-                                        @if(($referral_allowed === "client" && $user->role != "member") || $referral_allowed === "everyone")
+                                        @can("user.referral")
                                             <div class="mt-1">
                                                     <span class="badge badge-success"><i
                                                             class="fa fa-user-check mr-2"></i>
@@ -112,8 +112,8 @@ class="fa fa-user-check mr-2"></i>
                                                 @else
                                                     <span class="badge badge-warning"><i
                                                             class="fa fa-user-check mr-2"></i>
-                                                        {{_("Make a purchase to reveal your referral-URL")}}</span>
-                                        @endif
+                                                        {{_("You can not see your Referral Code")}}</span>
+                                        @endcan
                                             </div>
                                         @endif
                                         </div>
diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index 4b9b7df1e..df47ae53f 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -27,17 +27,17 @@
 
             <!-- CUSTOM CONTENT -->
             <div class="d-flex justify-content-md-start justify-content-center mb-3 ">
-                <a @if (Auth::user()->Servers->count() >= Auth::user()->server_limit)
-                    disabled="disabled" title="Server limit reached!"
-                    @endif href="{{ route('servers.create') }}"
-                    class="btn
-                    @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled
-                    @endif btn-primary"><i
-                        class="fa fa-plus mr-2"></i>
+                <a @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled="disabled" title="Server limit reached!" @endif
+                   @cannot("user.server.create") disabled="disabled" title="No Permission!" @endcannot
+                    href="{{ route('servers.create') }}" class="btn
+                    @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled @endif
+                    @cannot("user.server.create") disabled @endcannot
+                    btn-primary">
+                    <i class="fa fa-plus mr-2"></i>
                     {{ __('Create Server') }}
                 </a>
                 @if (Auth::user()->Servers->count() > 0 && !empty($phpmyadmin_url))
-                    <a 
+                    <a
                         href="{{ $phpmyadmin_url }}" target="_blank"
                         class="btn btn-secondary ml-2"><i title="manage"
                         class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span>
diff --git a/themes/default/views/servers/settings.blade.php b/themes/default/views/servers/settings.blade.php
index 2ec6bb279..4ef717443 100644
--- a/themes/default/views/servers/settings.blade.php
+++ b/themes/default/views/servers/settings.blade.php
@@ -222,7 +222,7 @@
                 <div class="card-footer">
                     <div class="col-md-12 text-center">
                         <!-- Upgrade Button trigger modal -->
-                        @if($server_enable_upgrade)
+                        @if($server_enable_upgrade && Auth::user()->can("user.server.upgrade"))
                             <button type="button" data-toggle="modal" data-target="#UpgradeModal{{ $server->id }}" target="__blank"
                                 class="btn btn-info btn-md">
                                 <i class="fas fa-upload mr-2"></i>
diff --git a/themes/default/views/store/index.blade.php b/themes/default/views/store/index.blade.php
index 31393c199..8fd58f5fd 100644
--- a/themes/default/views/store/index.blade.php
+++ b/themes/default/views/store/index.blade.php
@@ -61,7 +61,7 @@
                                             {{ $product->display }}
                                         </td>
                                         <td><a href="{{ route('checkout', $product->id) }}"
-                                                class="btn btn-info">{{ __('Purchase') }}</a>
+                                                class="btn btn-info @cannot('user.shop.buy') disabled @endcannot">{{ __('Purchase') }}</a>
                                         </td>
                                     </tr>
                                 @endforeach
diff --git a/themes/default/views/ticket/index.blade.php b/themes/default/views/ticket/index.blade.php
index d2e66c80b..0c1d40988 100644
--- a/themes/default/views/ticket/index.blade.php
+++ b/themes/default/views/ticket/index.blade.php
@@ -30,8 +30,8 @@
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <h5 class="card-title"><i class="fas fa-ticket-alt mr-2"></i>{{__('My Ticket')}}</h5>
-                                <a href="{{route('ticket.new')}}" class="btn btn-sm btn-primary"><i
-                                        class="fas fa-plus mr-1"></i>{{__('New Ticket')}}</a>
+                                <a href="{{route('ticket.new')}}" class="btn btn-sm btn-primary @cannot("user.ticket.write")) disabled @endcannot">
+                                    <i class="fas fa-plus mr-1"></i>{{__('New Ticket')}}</a>
                             </div>
                         </div>
                         <div class="card-body table-responsive">

From 7d93d45197baa4fc5afdd1132c0319f397a876f2 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 3 May 2023 14:52:34 +0200
Subject: [PATCH 114/514] Update 2023_02_01_182158_create_website_settings.php

---
 .../settings/2023_02_01_182158_create_website_settings.php   | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/database/settings/2023_02_01_182158_create_website_settings.php b/database/settings/2023_02_01_182158_create_website_settings.php
index 013c85f87..c7e8fa515 100644
--- a/database/settings/2023_02_01_182158_create_website_settings.php
+++ b/database/settings/2023_02_01_182158_create_website_settings.php
@@ -14,10 +14,7 @@ public function up(): void
         $this->migrator->add(
             'website.motd_message',
             $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_MESSAGE") :
-                '<h1 style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://ctrlpanel.gg/img/controlpanel.png" alt="" width="200" height="200"><span style="font-size: 36pt;">Controlpanel.gg</span></h1>
- <p><span style="font-size: 18pt;">Thank you for using our Software</span></p>
- <p><span style="font-size: 18pt;">If you have any questions, make sure to join our <a href="https://discord.com/invite/4Y6HjD2uyU" target="_blank" rel="noopener">Discord</a></span></p>
- <p><span style="font-size: 10pt;">(you can change this message in the <a href="admin/settings#system">Settings</a> )</span></p>'
+                '<h1 style=\"text-align: center;\"><img style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/ctrlpanel.gg\/img\/controlpanel.png\" alt=\"\" width=\"200\" height=\"200\"><span style=\"font-size: 36pt;\">Controlpanel.gg<\/span><\/h1>\r\n<p><span style=\"font-size: 18pt;\">Thank you for using our Software<\/span><\/p>\r\n<p><span style=\"font-size: 18pt;\">If you have any questions, make sure to join our <a href=\"https:\/\/discord.com\/invite\/4Y6HjD2uyU\" target=\"_blank\" rel=\"noopener\">Discord<\/a><\/span><\/p>\r\n<p><span style=\"font-size: 10pt;\">(you can change this message in the <a href=\"admin\/settings#system\">Settings<\/a> )<\/span><\/p>'
         );
         $this->migrator->add('website.show_imprint', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_IMPRINT") : false);
         $this->migrator->add('website.show_privacy', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_PRIVACY") : false);

From a4280a6fba9937d9adab40c80e769e6df751b31e Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Wed, 3 May 2023 15:17:13 +0200
Subject: [PATCH 115/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Path=20seperator?=
 =?UTF-8?q?=20replacement=20->=20be=20filesystem=20aware?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Helpers/ExtensionHelper.php | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/app/Helpers/ExtensionHelper.php b/app/Helpers/ExtensionHelper.php
index 6b59c1e4d..117e54e34 100644
--- a/app/Helpers/ExtensionHelper.php
+++ b/app/Helpers/ExtensionHelper.php
@@ -18,8 +18,9 @@ public static function getAllExtensions()
         foreach ($extensionNamespaces as $extensionNamespace) {
             $extensions = array_merge($extensions, glob($extensionNamespace . '/*', GLOB_ONLYDIR));
         }
+
         // remove base path from every extension but keep app/Extensions/...
-        $extensions = array_map(fn ($item) => str_replace('/', '\\', str_replace(app_path() . '/', 'App/', $item)), $extensions);
+        $extensions = array_map(fn ($item) => str_replace(app_path() . '/', 'App/', $item), $extensions);
 
         return $extensions;
     }
@@ -33,7 +34,7 @@ public static function getAllExtensionsByNamespace(string $namespace)
     {
         $extensions = glob(app_path() . '/Extensions/' . $namespace . '/*', GLOB_ONLYDIR);
         // remove base path from every extension but keep app/Extensions/...
-        $extensions = array_map(fn ($item) => str_replace('/', '\\', str_replace(app_path() . '/', 'App/', $item)), $extensions);
+        $extensions = array_map(fn ($item) => str_replace(app_path() . '/', 'App/', $item), $extensions);
 
         return $extensions;
     }
@@ -60,6 +61,9 @@ public static function getExtension(string $extensionName)
     public static function getAllExtensionClasses()
     {
         $extensions = self::getAllExtensions();
+
+        // replace all slashes with backslashes
+        $extensions = array_map(fn ($item) => str_replace('/', '\\', $item), $extensions);
         // add the ExtensionClass to the end of the namespace 
         $extensions = array_map(fn ($item) => $item . '\\' . basename($item) . 'Extension', $extensions);
         // filter out non existing extension classes
@@ -76,6 +80,9 @@ public static function getAllExtensionClasses()
     public static function getAllExtensionClassesByNamespace(string $namespace)
     {
         $extensions = self::getAllExtensionsByNamespace($namespace);
+
+        // replace all slashes with backslashes
+        $extensions = array_map(fn ($item) => str_replace('/', '\\', $item), $extensions);
         // add the ExtensionClass to the end of the namespace
         $extensions = array_map(fn ($item) => $item . '\\' . basename($item) . 'Extension', $extensions);
         // filter out non existing extension classes
@@ -177,10 +184,13 @@ public static function getAllExtensionSettingsClasses()
     {
         $extensions = self::getAllExtensions();
 
+
         $settings = [];
         foreach ($extensions as $extension) {
-
             $extensionName = basename($extension);
+
+            // replace all slashes with backslashes
+            $extension = str_replace('/', '\\', $extension);
             $settingsClass = $extension . '\\' . $extensionName . 'Settings';
             if (class_exists($settingsClass)) {
                 $settings[] = $settingsClass;
@@ -193,6 +203,9 @@ public static function getAllExtensionSettingsClasses()
     public static function getExtensionSettings(string $extensionName)
     {
         $extension = self::getExtension($extensionName);
+        // replace all slashes with backslashes
+        $extension = str_replace('/', '\\', $extension);
+
         $settingClass = $extension . '\\' . $extensionName . 'Settings';
 
         if (class_exists($settingClass)) {
@@ -207,6 +220,6 @@ public static function getExtensionSettings(string $extensionName)
      */
     private static function extensionNameToPath(string $extensionName)
     {
-        return app_path() . '/' . str_replace('\\', '/', str_replace('App\\', '', $extensionName));
+        return app_path() . '/' .  str_replace('App/', '', $extensionName);
     }
 }

From 7754041532ca55f534ba17dd92bdff6519ce0b3c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Wed, 3 May 2023 15:17:35 +0200
Subject: [PATCH 116/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20hotfix=20migratio?=
 =?UTF-8?q?ns?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../migrations/2023_03_04_135248_create_pay_pal_settings.php  | 4 ++++
 .../migrations/2023_03_04_181917_create_stripe_settings.php   | 4 ++++
 database/migrations/2023_04_03_231829_update_users_table.php  | 3 ++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php b/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
index 5792abec4..db7d0bdd5 100644
--- a/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
+++ b/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
@@ -77,6 +77,10 @@ public function getOldValue(string $key)
         // Always get the first value of the key.
         $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
 
+        if (is_null($old_value)) {
+            return null;
+        }
+
         // Handle the old values to return without it being a string in all cases.
         if ($old_value->type === "string" || $old_value->type === "text") {
             if (is_null($old_value->value)) {
diff --git a/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php b/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
index a8145a7c8..0ed72922c 100644
--- a/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
+++ b/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
@@ -75,6 +75,10 @@ public function getOldValue(string $key)
         // Always get the first value of the key.
         $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
 
+        if (is_null($old_value)) {
+            return null;
+        }
+
         // Handle the old values to return without it being a string in all cases.
         if ($old_value->type === "string" || $old_value->type === "text") {
             if (is_null($old_value->value)) {
diff --git a/database/migrations/2023_04_03_231829_update_users_table.php b/database/migrations/2023_04_03_231829_update_users_table.php
index 3caf98aa0..20ca26078 100644
--- a/database/migrations/2023_04_03_231829_update_users_table.php
+++ b/database/migrations/2023_04_03_231829_update_users_table.php
@@ -26,7 +26,8 @@ public function up()
     public function down()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->integer('pterodactyl_id')->nullable->change();
+            // make the column nullable again
+            $table->integer('pterodactyl_id')->nullable()->change();
         });
     }
 };

From 04a4f2ab96b310cae7be61da0538b3aa1ff410f3 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 3 May 2023 15:44:22 +0200
Subject: [PATCH 117/514] disable invoices by default

---
 app/Helpers/ExtensionHelper.php                               | 4 ++--
 .../settings/2023_02_01_182021_create_invoice_settings.php    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Helpers/ExtensionHelper.php b/app/Helpers/ExtensionHelper.php
index 117e54e34..f465078b0 100644
--- a/app/Helpers/ExtensionHelper.php
+++ b/app/Helpers/ExtensionHelper.php
@@ -64,7 +64,7 @@ public static function getAllExtensionClasses()
 
         // replace all slashes with backslashes
         $extensions = array_map(fn ($item) => str_replace('/', '\\', $item), $extensions);
-        // add the ExtensionClass to the end of the namespace 
+        // add the ExtensionClass to the end of the namespace
         $extensions = array_map(fn ($item) => $item . '\\' . basename($item) . 'Extension', $extensions);
         // filter out non existing extension classes
         $extensions = array_filter($extensions, fn ($item) => class_exists($item));
@@ -104,7 +104,7 @@ public static function getExtensionClass(string $extensionName)
             if (!(basename($extension) ==  $extensionName)) {
                 continue;
             }
-
+            $extension = str_replace('/', '\\', $extension);
             $extensionClass = $extension . '\\' . $extensionName . 'Extension';
             return $extensionClass;
         }
diff --git a/database/settings/2023_02_01_182021_create_invoice_settings.php b/database/settings/2023_02_01_182021_create_invoice_settings.php
index 3fb835379..8569c3ff4 100644
--- a/database/settings/2023_02_01_182021_create_invoice_settings.php
+++ b/database/settings/2023_02_01_182021_create_invoice_settings.php
@@ -16,7 +16,7 @@ public function up(): void
         $this->migrator->add('invoice.company_phone', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_PHONE') : '');
         $this->migrator->add('invoice.company_vat', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_VAT') : '');
         $this->migrator->add('invoice.company_website', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_WEBSITE') : '');
-        $this->migrator->add('invoice.enabled', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:ENABLED') : true);
+        $this->migrator->add('invoice.enabled', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:ENABLED') : false);
         $this->migrator->add('invoice.prefix', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:PREFIX') : 'INV');
     }
 

From 5d288cd07078f9fbfc873f22af47e146b1601775 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 3 May 2023 16:05:55 +0200
Subject: [PATCH 118/514] Update UserPayment.php

---
 app/Listeners/UserPayment.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Listeners/UserPayment.php b/app/Listeners/UserPayment.php
index 4fbe9ba80..3417a7ce2 100644
--- a/app/Listeners/UserPayment.php
+++ b/app/Listeners/UserPayment.php
@@ -35,7 +35,7 @@ public function __construct(UserSettings $user_settings, ReferralSettings $refer
         $this->referral_always_give_commission = $referral_settings->always_give_commission;
         $this->credits_display_name = $general_settings->credits_display_name;
     }
-    
+
     /**
      * Handle the event.
      *
@@ -79,8 +79,8 @@ public function handle(PaymentEvent $event)
             }
         }
         //update role give Referral-reward
-        if ($user->role == 'member') {
-            $user->update(['role' => 'client']);
+        if ($user->hasRole(4)) {
+            $user->syncRoles(3);
 
             //give referral commission only on first purchase
             if (($this->referral_mode === "commission" || $this->referral_mode === "both") && $shopProduct->type == "Credits" && !$this->referral_always_give_commission) {

From 804a800d4f49f0f833bbaaef6d1add568f2a85bc Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 3 May 2023 16:16:50 +0200
Subject: [PATCH 119/514] full frontend perms showing roles

---
 app/Console/Commands/MakeUserCommand.php      |  2 ++
 app/Http/Middleware/isMod.php                 |  2 +-
 routes/web.php                                |  2 +-
 .../default/views/admin/users/show.blade.php  | 15 +++---------
 .../views/moderator/ticket/show.blade.php     | 24 +++++--------------
 themes/default/views/ticket/show.blade.php    | 24 +++++--------------
 6 files changed, 19 insertions(+), 50 deletions(-)

diff --git a/app/Console/Commands/MakeUserCommand.php b/app/Console/Commands/MakeUserCommand.php
index 0932f9f27..fb1366fe7 100644
--- a/app/Console/Commands/MakeUserCommand.php
+++ b/app/Console/Commands/MakeUserCommand.php
@@ -101,6 +101,8 @@ public function handle(PterodactylSettings $ptero_settings)
             ['Referral code', $user->referral_code],
         ]);
 
+        $user->syncRoles(1);
+
         return 1;
     }
 }
diff --git a/app/Http/Middleware/isMod.php b/app/Http/Middleware/isMod.php
index 8c5453a24..51d6db851 100644
--- a/app/Http/Middleware/isMod.php
+++ b/app/Http/Middleware/isMod.php
@@ -18,7 +18,7 @@ class isMod
      */
     public function handle(Request $request, Closure $next)
     {
-        if (Auth::user() && Auth::user()->role == 'moderator' || Auth::user() && Auth::user()->hasRole("Admin")) {
+        if (Auth::user() && Auth::user()->role == 'moderator' || Auth::user() && Auth::user()->hasRole(1)) {
             return $next($request);
         }
 
diff --git a/routes/web.php b/routes/web.php
index f13a33a99..c7c6a9de1 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -113,7 +113,7 @@
     Route::post('ticket/new', [TicketsController::class, 'store'])->middleware(['throttle:ticket-new'])->name('ticket.new.store');
     Route::get('ticket/show/{ticket_id}', [TicketsController::class, 'show'])->name('ticket.show');
     Route::post('ticket/reply', [TicketsController::class, 'reply'])->middleware(['throttle:ticket-reply'])->name('ticket.reply');
-    Route::post('ticket/close/{ticket_id}', [TicketsController::class, 'close'])->name('ticket.close');
+    Route::post('ticket/status/{ticket_id}', [TicketsController::class, 'changeStatus'])->name('ticket.changeStatus');
 
 
     //admin
diff --git a/themes/default/views/admin/users/show.blade.php b/themes/default/views/admin/users/show.blade.php
index 5d2da4120..3ab0d62ee 100644
--- a/themes/default/views/admin/users/show.blade.php
+++ b/themes/default/views/admin/users/show.blade.php
@@ -74,18 +74,9 @@
                                     <label>{{ __('Role') }}</label>
                                 </div>
                                 <div class="col-lg-8">
-                                    <span style="max-width: 250px;"
-                                        class="d-inline-block text-truncate badge
-                                        @if ($user->hasRole("Admin")) badge-danger
-                                        @elseif ($user->role == 'moderator')
-                                            badge-info
-                                        @elseif ($user->role == 'client')
-                                            badge-success
-                                        @else
-                                            badge-secondary @endif
-                                        ">
-                                        {{ $user->role }}
-                                    </span>
+                                    @foreach ($user->roles as $role)
+                                        <span style='background-color: {{$role->color}}' class='badge'>{{$role->name}}</span>
+                                    @endforeach
                                 </div>
                             </div>
                         </div>
diff --git a/themes/default/views/moderator/ticket/show.blade.php b/themes/default/views/moderator/ticket/show.blade.php
index 18c69e2fc..3bec1feba 100644
--- a/themes/default/views/moderator/ticket/show.blade.php
+++ b/themes/default/views/moderator/ticket/show.blade.php
@@ -112,15 +112,9 @@ class="fas fa-times"></i>{{__("Close")}}</button>
                                             src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticket->user->email)) }}?s=25"
                                             class="user-image" alt="User Image">
                                         <a href="/admin/users/{{$ticket->user->id}}">{{ $ticket->user->name }}</a>
-                                        @if($ticket->user->role === "member")
-                                            <span class="badge badge-secondary"> Member </span>
-                                        @elseif ($ticket->user->role === "client")
-                                            <span class="badge badge-success"> Client </span>
-                                        @elseif ($ticket->user->role === "moderator")
-                                            <span class="badge badge-info"> Moderator </span>
-                                        @elseif ($ticket->user->hasRole("Admin"))
-                                            <span class="badge badge-danger"> Admin </span>
-                                        @endif
+                                            @foreach ($ticket->user->roles as $role)
+                                                <span style='background-color: {{$role->color}}' class='badge'>{{$role->name}}</span>
+                                            @endforeach
                                     </h5>
                                         <span class="badge badge-primary">{{ $ticket->created_at->diffForHumans() }}</span>
                                     </div>
@@ -135,15 +129,9 @@ class="user-image" alt="User Image">
                                             src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticketcomment->user->email)) }}?s=25"
                                             class="user-image" alt="User Image">
                                         <a href="/admin/users/{{$ticketcomment->user->id}}">{{ $ticketcomment->user->name }}</a>
-                                        @if($ticketcomment->user->role === "member")
-                                            <span class="badge badge-secondary"> Member </span>
-                                        @elseif ($ticketcomment->user->role === "client")
-                                            <span class="badge badge-success"> Client </span>
-                                        @elseif ($ticketcomment->user->role === "moderator")
-                                            <span class="badge badge-info"> Moderator </span>
-                                        @elseif ($ticketcomment->user->hasRole("Admin"))
-                                            <span class="badge badge-danger"> Admin </span>
-                                        @endif
+                                            @foreach ($ticketcomment->user->roles as $role)
+                                                <span style='background-color: {{$role->color}}' class='badge'>{{$role->name}}</span>
+                                            @endforeach
                                     </h5>
                                         <span class="badge badge-primary">{{ $ticketcomment->created_at->diffForHumans() }}</span>
                                     </div>
diff --git a/themes/default/views/ticket/show.blade.php b/themes/default/views/ticket/show.blade.php
index 663b25f32..5a936afa9 100644
--- a/themes/default/views/ticket/show.blade.php
+++ b/themes/default/views/ticket/show.blade.php
@@ -112,15 +112,9 @@ class="fas fa-times"></i>{{__("Close")}}</button>
                                                 src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticket->user->email)) }}?s=25"
                                                 class="user-image" alt="User Image">
                                             <a href="/admin/users/{{$ticket->user->id}}">{{ $ticket->user->name }} </a>
-                                            @if($ticket->user->role === "member")
-                                                <span class="badge badge-secondary"> Member </span>
-                                            @elseif ($ticket->user->role === "client")
-                                                <span class="badge badge-success"> Client </span>
-                                            @elseif ($ticket->user->role === "moderator")
-                                                <span class="badge badge-info"> Moderator </span>
-                                            @elseif ($ticket->user->hasRole("Admin"))
-                                                <span class="badge badge-danger"> Admin </span>
-                                            @endif
+                                            @foreach ($ticket->user->roles as $role)
+                                                <span style='background-color: {{$role->color}}' class='badge'>{{$role->name}}</span>
+                                            @endforeach
                                         </h5>
                                         <span
                                             class="badge badge-primary">{{ $ticket->created_at->diffForHumans() }}</span>
@@ -136,15 +130,9 @@ class="badge badge-primary">{{ $ticket->created_at->diffForHumans() }}</span>
                                                     src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticketcomment->user->email)) }}?s=25"
                                                     class="user-image" alt="User Image">
                                                 <a href="/admin/users/{{$ticketcomment->user->id}}">{{ $ticketcomment->user->name }}</a>
-                                                @if($ticketcomment->user->role === "member")
-                                                    <span class="badge badge-secondary"> Member </span>
-                                                @elseif ($ticketcomment->user->role === "client")
-                                                    <span class="badge badge-success"> Client </span>
-                                                @elseif ($ticketcomment->user->role === "moderator")
-                                                    <span class="badge badge-info"> Moderator </span>
-                                                @elseif ($ticketcomment->user->hasRole("Admin"))
-                                                    <span class="badge badge-danger"> Admin </span>
-                                                @endif
+                                                @foreach ($ticketcomment->user->roles as $role)
+                                                    <span style='background-color: {{$role->color}}' class='badge'>{{$role->name}}</span>
+                                                @endforeach
                                             </h5>
                                             <span
                                                 class="badge badge-primary">{{ $ticketcomment->created_at->diffForHumans() }}</span>

From 4c780deb0293db147544a2353e233058cd4dee7b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 01:11:55 +0200
Subject: [PATCH 120/514] All permissions except Settings

---
 .../Admin/ActivityLogController.php           |   4 +
 .../Admin/ApplicationApiController.php        |   9 ++
 .../Controllers/Admin/LegalController.php     |   6 +
 .../Controllers/Admin/OverViewController.php  |   8 +-
 .../Controllers/Admin/PartnerController.php   |  10 ++
 .../Controllers/Admin/PaymentController.php   |   4 +
 .../Controllers/Admin/ProductController.php   |  17 +++
 app/Http/Controllers/Admin/RoleController.php |  12 ++
 .../Controllers/Admin/ServerController.php    |  21 +++-
 .../Admin/ShopProductController.php           |  15 ++-
 .../TicketCategoryController.php              |  21 +++-
 .../TicketsController.php                     |  42 +++++--
 .../Admin/UsefulLinkController.php            |   7 ++
 app/Http/Controllers/Admin/UserController.php |  58 ++++++++-
 .../Controllers/Admin/VoucherController.php   |   9 ++
 config/permissions_web.php                    |  21 +++-
 routes/web.php                                |  33 +++--
 .../BlueInfinity/views/layouts/main.blade.php |   8 +-
 .../views/admin/overview/index.blade.php      |   2 +-
 themes/default/views/layouts/main.blade.php   | 116 +++++++++++-------
 .../views/mail/ticket/admin/create.blade.php  |   2 +-
 .../views/mail/ticket/admin/reply.blade.php   |   2 +-
 .../moderator/ticket/blacklist.blade.php      |   6 +-
 .../views/moderator/ticket/category.blade.php |   8 +-
 .../views/moderator/ticket/index.blade.php    |   6 +-
 .../views/moderator/ticket/show.blade.php     |   8 +-
 26 files changed, 342 insertions(+), 113 deletions(-)
 rename app/Http/Controllers/{Moderation => Admin}/TicketCategoryController.php (81%)
 rename app/Http/Controllers/{Moderation => Admin}/TicketsController.php (86%)

diff --git a/app/Http/Controllers/Admin/ActivityLogController.php b/app/Http/Controllers/Admin/ActivityLogController.php
index 2b0610948..25978a378 100644
--- a/app/Http/Controllers/Admin/ActivityLogController.php
+++ b/app/Http/Controllers/Admin/ActivityLogController.php
@@ -14,6 +14,7 @@
 
 class ActivityLogController extends Controller
 {
+    const VIEW_PERMISSION = "admin.logs.read";
     /**
      * Display a listing of the resource.
      *
@@ -21,6 +22,9 @@ class ActivityLogController extends Controller
      */
     public function index(Request $request)
     {
+        $this->checkPermission(self::VIEW_PERMISSION);
+
+
         $cronLogs = Storage::disk('logs')->exists('cron.log') ? Storage::disk('logs')->get('cron.log') : null;
 
         if ($request->input('search')) {
diff --git a/app/Http/Controllers/Admin/ApplicationApiController.php b/app/Http/Controllers/Admin/ApplicationApiController.php
index f037efe89..f6c00bbd8 100644
--- a/app/Http/Controllers/Admin/ApplicationApiController.php
+++ b/app/Http/Controllers/Admin/ApplicationApiController.php
@@ -16,6 +16,8 @@
 
 class ApplicationApiController extends Controller
 {
+    const READ_PERMISSION = "admin.api.read";
+    const WRITE_PERMISSION = "admin.api.write";
     /**
      * Display a listing of the resource.
      *
@@ -23,6 +25,8 @@ class ApplicationApiController extends Controller
      */
     public function index(LocaleSettings $locale_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.api.index', [
             'locale_datatables' => $locale_settings->datatables
         ]);
@@ -35,6 +39,8 @@ public function index(LocaleSettings $locale_settings)
      */
     public function create()
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         return view('admin.api.create');
     }
 
@@ -76,6 +82,7 @@ public function show(ApplicationApi $applicationApi)
      */
     public function edit(ApplicationApi $applicationApi)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         return view('admin.api.edit', [
             'applicationApi' => $applicationApi,
         ]);
@@ -107,6 +114,8 @@ public function update(Request $request, ApplicationApi $applicationApi)
      */
     public function destroy(ApplicationApi $applicationApi)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $applicationApi->delete();
 
         return redirect()->back()->with('success', __('api key has been removed!'));
diff --git a/app/Http/Controllers/Admin/LegalController.php b/app/Http/Controllers/Admin/LegalController.php
index 0eafca573..27c858fba 100644
--- a/app/Http/Controllers/Admin/LegalController.php
+++ b/app/Http/Controllers/Admin/LegalController.php
@@ -10,6 +10,8 @@
 
 class LegalController extends Controller
 {
+    const READ_PERMISSION = "admin.legal.read";
+    const WRITE_PERMISSION = "admin.legal.write";
     /**
      * Display
      *
@@ -17,6 +19,8 @@ class LegalController extends Controller
      */
     public function index()
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         $tos = File::get(Theme::path($path = 'views', "default") . '/information/tos-content.blade.php');
         $privacy = File::get(Theme::path($path = 'views', "default") . '/information/privacy-content.blade.php');
         $imprint = File::get(Theme::path($path = 'views', "default") . '/information/imprint-content.blade.php');
@@ -29,6 +33,8 @@ public function index()
     }
 
     public function update(Request $request){
+        $this->checkPermission(self::READ_PERMISSION);
+
         $tos = $request->tos;
         $privacy = $request->privacy;
         $imprint = $request->imprint;
diff --git a/app/Http/Controllers/Admin/OverViewController.php b/app/Http/Controllers/Admin/OverViewController.php
index eac33d02c..90cd9307a 100644
--- a/app/Http/Controllers/Admin/OverViewController.php
+++ b/app/Http/Controllers/Admin/OverViewController.php
@@ -19,6 +19,8 @@
 
 class OverViewController extends Controller
 {
+    const READ_PERMISSION = "admin.overview.read";
+    const SYNC_PERMISSION = "admin.overview.sync";
     public const TTL = 86400;
 
     private $pterodactyl;
@@ -27,9 +29,11 @@ public function __construct(PterodactylSettings $ptero_settings)
     {
         $this->pterodactyl = new PterodactylClient($ptero_settings);
     }
-    
+
     public function index(GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         //Get counters
         $counters = collect();
         //Set basic variables in the collection
@@ -225,6 +229,8 @@ public function index(GeneralSettings $general_settings)
      */
     public function syncPterodactyl()
     {
+        $this->checkPermission(self::SYNC_PERMISSION);
+
         Node::syncNodes();
         Egg::syncEggs();
 
diff --git a/app/Http/Controllers/Admin/PartnerController.php b/app/Http/Controllers/Admin/PartnerController.php
index cea2aec24..5c4a6babb 100644
--- a/app/Http/Controllers/Admin/PartnerController.php
+++ b/app/Http/Controllers/Admin/PartnerController.php
@@ -11,8 +11,12 @@
 
 class PartnerController extends Controller
 {
+    const READ_PERMISSION = "admin.partners.read";
+    const WRITE_PERMISSION = "admin.partners.write";
     public function index(LocaleSettings $locale_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.partners.index', [
             'locale_datatables' => $locale_settings->datatables
         ]);
@@ -25,6 +29,8 @@ public function index(LocaleSettings $locale_settings)
      */
     public function create()
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         return view('admin.partners.create', [
             'partners' => PartnerDiscount::get(),
             'users' => User::orderBy('name')->get(),
@@ -62,6 +68,8 @@ public function store(Request $request)
      */
     public function edit(PartnerDiscount $partner)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         return view('admin.partners.edit', [
             'partners' => PartnerDiscount::get(),
             'partner' => $partner,
@@ -98,6 +106,8 @@ public function update(Request $request, PartnerDiscount $partner)
      */
     public function destroy(PartnerDiscount $partner)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $partner->delete();
 
         return redirect()->back()->with('success', __('partner has been removed!'));
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 02d91bde9..543cdcf69 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -24,11 +24,15 @@
 class PaymentController extends Controller
 {
     const BUY_PERMISSION = 'user.shop.buy';
+    const VIEW_PERMISSION = "admin.payments.read";
     /**
      * @return Application|Factory|View
      */
     public function index(LocaleSettings $locale_settings)
     {
+        $this->checkPermission(self::VIEW_PERMISSION);
+
+
         return view('admin.payments.index')->with([
             'payments' => Payment::paginate(15),
             'locale_datatables' => $locale_settings->datatables
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index f26691e31..3dc95829b 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -19,6 +19,10 @@
 
 class ProductController extends Controller
 {
+    const READ_PERMISSION = "admin.products.read";
+    const WRITE_PERMISSION = "admin.products.write";
+    const EDIT_PERMISSION = "admin.products.edit";
+    const DELETE_PERMISSION = "admin.products.delete";
     /**
      * Display a listing of the resource.
      *
@@ -26,6 +30,8 @@ class ProductController extends Controller
      */
     public function index(LocaleSettings $locale_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.products.index', [
             'locale_datatables' => $locale_settings->datatables
         ]);
@@ -38,6 +44,7 @@ public function index(LocaleSettings $locale_settings)
      */
     public function create(GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         return view('admin.products.create', [
             'locations' => Location::with('nodes')->get(),
             'nests' => Nest::with('eggs')->get(),
@@ -47,6 +54,8 @@ public function create(GeneralSettings $general_settings)
 
     public function clone(Product $product)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         return view('admin.products.create', [
             'product' => $product,
             'locations' => Location::with('nodes')->get(),
@@ -98,6 +107,8 @@ public function store(Request $request)
      */
     public function show(Product $product, UserSettings $user_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.products.show', [
             'product' => $product,
             'minimum_credits' => $user_settings->min_credits_to_make_server,
@@ -113,6 +124,8 @@ public function show(Product $product, UserSettings $user_settings, GeneralSetti
      */
     public function edit(Product $product, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::EDIT_PERMISSION);
+
         return view('admin.products.edit', [
             'product' => $product,
             'locations' => Location::with('nodes')->get(),
@@ -167,6 +180,8 @@ public function update(Request $request, Product $product): RedirectResponse
      */
     public function disable(Product $product)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $product->update(['disabled' => ! $product->disabled]);
 
         return redirect()->route('admin.products.index')->with('success', 'Product has been updated!');
@@ -180,6 +195,8 @@ public function disable(Product $product)
      */
     public function destroy(Product $product)
     {
+        $this->checkPermission(self::DELETE_PERMISSION);
+
         $servers = $product->servers()->count();
         if ($servers > 0) {
             return redirect()->back()->with('error', "Product cannot be removed while it's linked to {$servers} servers");
diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index ed4194bee..3850c1809 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -16,6 +16,10 @@
 class RoleController extends Controller
 {
 
+    const READ_PERMISSION = "admin.roles.read";
+    const CREATE_PERMISSION = "admin.roles.create";
+    const EDIT_PERMISSION = "admin.roles.edit";
+    const DELETE_PERMISSION = "admin.roles.delete";
     /**
      * Display a listing of the resource.
      *
@@ -26,6 +30,7 @@ class RoleController extends Controller
     public function index(Request $request)
     {
 
+        $this->checkPermission(self::READ_PERMISSION);
 
         //datatables
         if ($request->ajax()) {
@@ -43,6 +48,7 @@ public function index(Request $request)
      */
     public function create()
     {
+        $this->checkPermission(self::CREATE_PERMISSION);
 
         $permissions = Permission::all();
 
@@ -56,6 +62,8 @@ public function create()
      */
     public function store(Request $request): RedirectResponse
     {
+        $this->checkPermission(self::CREATE_PERMISSION);
+
         $role = Role::create([
             'name' => $request->name,
             'color' => $request->color
@@ -86,6 +94,7 @@ public function show()
      */
     public function edit(Role $role)
     {
+        $this->checkPermission(self::EDIT_PERMISSION);
 
         $permissions = Permission::all();
 
@@ -100,6 +109,8 @@ public function edit(Role $role)
      */
     public function update(Request $request, Role $role)
     {
+        $this->checkPermission(self::EDIT_PERMISSION);
+
         if ($request->permissions) {
             if($role->id != 1){ //disable admin permissions change
                 $role->syncPermissions($request->permissions);
@@ -135,6 +146,7 @@ public function update(Request $request, Role $role)
      */
     public function destroy(Role $role)
     {
+        $this->checkPermission(self::DELETE_PERMISSION);
 
         if($role->id == 1 || $role->id == 3 || $role->id == 4){ //cannot delete the hard coded roles
             return back()->with("error","You cannot delete that role");
diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index 8e2475f5c..6fb3266a7 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -20,6 +20,13 @@
 
 class ServerController extends Controller
 {
+
+    const READ_PERMISSION = "admin.servers.read";
+    const WRITE_PERMISSION = "admin.servers.write";
+    const SUSPEND_PERMISSION = "admin.servers.suspend";
+    const CHANGEOWNER_PERMISSION = "admin.servers.write.owner";
+    const CHANGE_IDENTIFIER_PERMISSION ="admin.servers.write.identifier";
+    const DELETE_PERMISSION = "admin.servers.delete";
     private $pterodactyl;
 
     public function __construct(PterodactylSettings $ptero_settings)
@@ -34,6 +41,8 @@ public function __construct(PterodactylSettings $ptero_settings)
      */
     public function index(LocaleSettings $locale_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.servers.index', [
             'locale_datatables' => $locale_settings->datatables
         ]);
@@ -47,6 +56,8 @@ public function index(LocaleSettings $locale_settings)
      */
     public function edit(Server $server)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         // get all users from the database
         $users = User::all();
 
@@ -70,7 +81,7 @@ public function update(Request $request, Server $server)
         ]);
 
 
-        if ($request->get('user_id') != $server->user_id) {
+        if ($request->get('user_id') != $server->user_id && $this->can(self::CHANGEOWNER_PERMISSION)) {
             // find the user
             $user = User::findOrFail($request->get('user_id'));
 
@@ -89,7 +100,10 @@ public function update(Request $request, Server $server)
         }
 
         // update the identifier
-        $server->identifier = $request->get('identifier');
+        if($this->can(self::CHANGE_IDENTIFIER_PERMISSION)) {
+
+            $server->identifier = $request->get('identifier');
+        }
         $server->save();
 
         return redirect()->route('admin.servers.index')->with('success', 'Server updated!');
@@ -103,6 +117,7 @@ public function update(Request $request, Server $server)
      */
     public function destroy(Server $server)
     {
+        $this->checkPermission(self::DELETE_PERMISSION);
         try {
             $server->delete();
 
@@ -118,6 +133,8 @@ public function destroy(Server $server)
      */
     public function toggleSuspended(Server $server)
     {
+        $this->checkPermission(self::SUSPEND_PERMISSION);
+
         try {
             $server->isSuspended() ? $server->unSuspend() : $server->suspend();
         } catch (Exception $exception) {
diff --git a/app/Http/Controllers/Admin/ShopProductController.php b/app/Http/Controllers/Admin/ShopProductController.php
index 690493f8f..74c32639a 100644
--- a/app/Http/Controllers/Admin/ShopProductController.php
+++ b/app/Http/Controllers/Admin/ShopProductController.php
@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers\Admin;
 
+use App\Http\Controllers\Controller;
 use App\Models\ShopProduct;
 use App\Settings\GeneralSettings;
 use App\Settings\LocaleSettings;
@@ -11,12 +12,15 @@
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
-use Illuminate\Routing\Controller;
 use Illuminate\Validation\Rule;
 
 class ShopProductController extends Controller
 {
 
+    const READ_PERMISSION = 'admin.store.read';
+    const WRITE_PERMISSION = 'admin.store.write';
+    const DISABLE_PERMISSION = 'admin.store.disable';
+
     /**
      * Display a listing of the resource.
      *
@@ -24,6 +28,8 @@ class ShopProductController extends Controller
      */
     public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         $isStoreEnabled = $general_settings->store_enabled;
 
 
@@ -40,6 +46,8 @@ public function index(LocaleSettings $locale_settings, GeneralSettings $general_
      */
     public function create(GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         return view('admin.store.create', [
             'currencyCodes' => config('currency_codes'),
             'credits_display_name' => $general_settings->credits_display_name
@@ -78,6 +86,8 @@ public function store(Request $request)
      */
     public function edit(ShopProduct $shopProduct, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         return view('admin.store.edit', [
             'currencyCodes' => config('currency_codes'),
             'shopProduct' => $shopProduct,
@@ -117,6 +127,8 @@ public function update(Request $request, ShopProduct $shopProduct)
      */
     public function disable(ShopProduct $shopProduct)
     {
+        $this->checkPermission(self::DISABLE_PERMISSION);
+
         $shopProduct->update(['disabled' => !$shopProduct->disabled]);
 
         return redirect()->route('admin.store.index')->with('success', __('Product has been updated!'));
@@ -130,6 +142,7 @@ public function disable(ShopProduct $shopProduct)
      */
     public function destroy(ShopProduct $shopProduct)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         $shopProduct->delete();
 
         return redirect()->back()->with('success', __('Store item has been removed!'));
diff --git a/app/Http/Controllers/Moderation/TicketCategoryController.php b/app/Http/Controllers/Admin/TicketCategoryController.php
similarity index 81%
rename from app/Http/Controllers/Moderation/TicketCategoryController.php
rename to app/Http/Controllers/Admin/TicketCategoryController.php
index 729e2f3c2..74fff87a7 100644
--- a/app/Http/Controllers/Moderation/TicketCategoryController.php
+++ b/app/Http/Controllers/Admin/TicketCategoryController.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace App\Http\Controllers\Moderation;
+namespace App\Http\Controllers\Admin;
 
 use App\Http\Controllers\Controller;
 use App\Models\Ticket;
@@ -9,15 +9,20 @@
 
 class TicketCategoryController extends Controller
 {
+    const READ_PERMISSION = "admin.tickets.read";
+    const WRITE_PERMISSION = "admin.tickets.write";
     /**
+     *
      * Display a listing of the resource.
      *
      * @return \Illuminate\Http\Response
      */
     public function index()
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         $categories = TicketCategory::all();
-        return view('moderator.ticket.category')->with("categories",$categories);
+        return view('admin.ticket.category')->with("categories",$categories);
     }
 
     /**
@@ -28,6 +33,8 @@ public function index()
      */
     public function store(Request $request)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $request->validate([
             'name' => 'required|string|max:191',
         ]);
@@ -35,7 +42,7 @@ public function store(Request $request)
         TicketCategory::create($request->all());
 
 
-        return redirect(route("moderator.ticket.category.index"))->with("success",__("Category created"));
+        return redirect(route("admin.ticket.category.index"))->with("success",__("Category created"));
     }
 
     /**
@@ -46,6 +53,8 @@ public function store(Request $request)
      */
     public function update(Request $request)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $request->validate([
             'category' => 'required|int',
             'name' => 'required|string|max:191',
@@ -68,6 +77,8 @@ public function update(Request $request)
      */
     public function destroy($id)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $category = TicketCategory::where("id",$id)->firstOrFail();
 
         if($category->id == 5 ){ //cannot delete "other" category
@@ -84,7 +95,7 @@ public function destroy($id)
         $category->delete();
 
         return redirect()
-            ->route('moderator.ticket.category.index')
+            ->route('admin.ticket.category.index')
             ->with('success', __('Category removed'));
     }
 
@@ -101,7 +112,7 @@ public function datatable()
             })
             ->addColumn('actions', function (TicketCategory $category) {
                 return '
-                           <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('moderator.ticket.category.destroy', $category->id).'">
+                           <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.ticket.category.destroy', $category->id).'">
                             '.csrf_field().'
                             '.method_field('DELETE').'
                            <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
diff --git a/app/Http/Controllers/Moderation/TicketsController.php b/app/Http/Controllers/Admin/TicketsController.php
similarity index 86%
rename from app/Http/Controllers/Moderation/TicketsController.php
rename to app/Http/Controllers/Admin/TicketsController.php
index cb05f36f8..3622c22ae 100644
--- a/app/Http/Controllers/Moderation/TicketsController.php
+++ b/app/Http/Controllers/Admin/TicketsController.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace App\Http\Controllers\Moderation;
+namespace App\Http\Controllers\Admin;
 
 use App\Http\Controllers\Controller;
+use App\Http\Controllers\Moderation\Exception;
 use App\Models\Server;
 use App\Models\Ticket;
 use App\Models\TicketBlacklist;
@@ -17,9 +18,16 @@
 
 class TicketsController extends Controller
 {
+    const READ_PERMISSION = "admin.tickets.read";
+    const WRITE_PERMISSION = "admin.tickets.write";
+
+    const BLACKLIST_READ_PERMISSION ='admin.ticket_blacklist.read';
+    const BLACKLIST_WRITE_PERMISSION ='admin.ticket_blacklist.write';
     public function index(LocaleSettings $locale_settings)
     {
-        return view('moderator.ticket.index', [
+        $this->checkPermission(self::READ_PERMISSION);
+
+        return view('admin.ticket.index', [
             'tickets' => Ticket::orderBy('id', 'desc')->paginate(10),
             'ticketcategories' => TicketCategory::all(),
             'locale_datatables' => $locale_settings->datatables
@@ -28,6 +36,7 @@ public function index(LocaleSettings $locale_settings)
 
     public function show($ticket_id, PterodactylSettings $ptero_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
         try {
         $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
         } catch (Exception $e)
@@ -39,11 +48,12 @@ public function show($ticket_id, PterodactylSettings $ptero_settings)
         $server = Server::where('id', $ticket->server)->first();
         $pterodactyl_url = $ptero_settings->panel_url;
 
-        return view('moderator.ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server', 'pterodactyl_url'));
+        return view('admin.ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server', 'pterodactyl_url'));
     }
 
     public function changeStatus($ticket_id)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         try {
         $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
         } catch(Exception $e)
@@ -65,6 +75,7 @@ public function changeStatus($ticket_id)
 
     public function delete($ticket_id)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         try {
         $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
         } catch (Exception $e)
@@ -80,6 +91,9 @@ public function delete($ticket_id)
 
     public function reply(Request $request)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
+
         $this->validate($request, ['ticketcomment' => 'required']);
         try {
             $ticket = Ticket::where('id', $request->input('ticket_id'))->firstOrFail();
@@ -114,7 +128,7 @@ public function dataTable()
                 return $tickets->ticketcategory->name;
             })
             ->editColumn('title', function (Ticket $tickets) {
-                return '<a class="text-info"  href="'.route('moderator.ticket.show', ['ticket_id' => $tickets->ticket_id]).'">'.'#'.$tickets->ticket_id.' - '.htmlspecialchars($tickets->title).'</a>';
+                return '<a class="text-info"  href="'.route('admin.ticket.show', ['ticket_id' => $tickets->ticket_id]).'">'.'#'.$tickets->ticket_id.' - '.htmlspecialchars($tickets->title).'</a>';
             })
             ->editColumn('user_id', function (Ticket $tickets) {
                 return '<a href="'.route('admin.users.show', $tickets->user->id).'">'.$tickets->user->name.'</a>';
@@ -125,13 +139,13 @@ public function dataTable()
                 $statusButtonText = ($tickets->status == "Closed") ? __('Reopen') : __('Close');
 
                 return '
-                            <a data-content="'.__('View').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('moderator.ticket.show', ['ticket_id' => $tickets->ticket_id]).'" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-eye"></i></a>
-                            <form class="d-inline"  method="post" action="'.route('moderator.ticket.changeStatus', ['ticket_id' => $tickets->ticket_id]).'">
+                            <a data-content="'.__('View').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.ticket.show', ['ticket_id' => $tickets->ticket_id]).'" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-eye"></i></a>
+                            <form class="d-inline"  method="post" action="'.route('admin.ticket.changeStatus', ['ticket_id' => $tickets->ticket_id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
                             <button data-content="'.__($statusButtonText).'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white '.$statusButtonColor.'  mr-1"><i class="fas '.$statusButtonIcon.'"></i></button>
                             </form>
-                            <form class="d-inline"  method="post" action="'.route('moderator.ticket.delete', ['ticket_id' => $tickets->ticket_id]).'">
+                            <form class="d-inline"  method="post" action="'.route('admin.ticket.delete', ['ticket_id' => $tickets->ticket_id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
                             <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
@@ -170,13 +184,17 @@ public function dataTable()
 
     public function blacklist(LocaleSettings $locale_settings)
     {
-        return view('moderator.ticket.blacklist', [
+        $this->checkPermission(self::BLACKLIST_READ_PERMISSION);
+
+        return view('admin.ticket.blacklist', [
             'locale_datatables' => $locale_settings->datatables
         ]);
     }
 
     public function blacklistAdd(Request $request)
     {
+        $this->checkPermission(self::BLACKLIST_WRITE_PERMISSION);
+
         try {
         $user = User::where('id', $request->user_id)->firstOrFail();
         $check = TicketBlacklist::where('user_id', $user->id)->first();
@@ -202,6 +220,8 @@ public function blacklistAdd(Request $request)
 
     public function blacklistDelete($id)
     {
+        $this->checkPermission(self::BLACKLIST_WRITE_PERMISSION);
+
         $blacklist = TicketBlacklist::where('id', $id)->first();
         $blacklist->delete();
 
@@ -210,6 +230,8 @@ public function blacklistDelete($id)
 
     public function blacklistChange($id)
     {
+        $this->checkPermission(self::BLACKLIST_WRITE_PERMISSION);
+
         try {
             $blacklist = TicketBlacklist::where('id', $id)->first();
         }
@@ -254,12 +276,12 @@ public function dataTableBlacklist()
             })
             ->addColumn('actions', function (TicketBlacklist $blacklist) {
                 return '
-                            <form class="d-inline"  method="post" action="'.route('moderator.ticket.blacklist.change', ['id' => $blacklist->id]).'">
+                            <form class="d-inline"  method="post" action="'.route('admin.ticket.blacklist.change', ['id' => $blacklist->id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
                             <button data-content="'.__('Change Status').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-sync-alt"></i></button>
                             </form>
-                            <form class="d-inline"  method="post" action="'.route('moderator.ticket.blacklist.delete', ['id' => $blacklist->id]).'">
+                            <form class="d-inline"  method="post" action="'.route('admin.ticket.blacklist.delete', ['id' => $blacklist->id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
                             <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
diff --git a/app/Http/Controllers/Admin/UsefulLinkController.php b/app/Http/Controllers/Admin/UsefulLinkController.php
index ddfdb7de6..17f8774b2 100644
--- a/app/Http/Controllers/Admin/UsefulLinkController.php
+++ b/app/Http/Controllers/Admin/UsefulLinkController.php
@@ -15,6 +15,8 @@
 
 class UsefulLinkController extends Controller
 {
+    const READ_PERMISSION = "admin.useful_links.read";
+    const WRITE_PERMISSION = "admin.useful_links.write";
     /**
      * Display a listing of the resource.
      *
@@ -22,6 +24,7 @@ class UsefulLinkController extends Controller
      */
     public function index(LocaleSettings $locale_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
         return view('admin.usefullinks.index', [
             'locale_datatables' => $locale_settings->datatables
         ]);
@@ -34,6 +37,7 @@ public function index(LocaleSettings $locale_settings)
      */
     public function create()
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         $positions = UsefulLinkLocation::cases();
         return view('admin.usefullinks.create')->with('positions', $positions);
     }
@@ -84,6 +88,8 @@ public function show(UsefulLink $usefullink)
      */
     public function edit(UsefulLink $usefullink)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $positions = UsefulLinkLocation::cases();
         return view('admin.usefullinks.edit', [
             'link' => $usefullink,
@@ -126,6 +132,7 @@ public function update(Request $request, UsefulLink $usefullink)
      */
     public function destroy(UsefulLink $usefullink)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         $usefullink->delete();
 
         return redirect()->back()->with('success', __('product has been removed!'));
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index caf8fafd4..82d27c4e8 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -30,6 +30,20 @@
 
 class UserController extends Controller
 {
+    const READ_PERMISSION = "admin.users.read";
+    const WRITE_PERMISSION = "admin.users.write";
+    const SUSPEND_PERMISSION = "admin.users.suspend";
+    const CHANGE_EMAIL_PERMISSION = "admin.users.write.email";
+    const CHANGE_CREDITS_PERMISSION = "admin.users.write.credits";
+    const CHANGE_USERNAME_PERMISSION = "admin.users.write.username";
+    const CHANGE_PASSWORD_PERMISSION = "admin.users.write.password";
+    const CHANGE_ROLE_PERMISSION ="admin.users.write.role";
+    const CHANGE_REFERAL_PERMISSION ="admin.users.write.referal";
+    const CHANGE_PTERO_PERMISSION = "admin.users.write.pterodactyl";
+    const DELETE_PERMISSION = "admin.users.delete";
+    const NOTIFY_PERMISSION = "admin.users.notify";
+    const LOGIN_PERMISSION = "admin.users.login_as";
+
     private $pterodactyl;
 
     public function __construct(PterodactylSettings $ptero_settings)
@@ -45,6 +59,8 @@ public function __construct(PterodactylSettings $ptero_settings)
      */
     public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.users.index', [
             'locale_datatables' => $locale_settings->datatables,
             'credits_display_name' => $general_settings->credits_display_name
@@ -59,6 +75,8 @@ public function index(LocaleSettings $locale_settings, GeneralSettings $general_
      */
     public function show(User $user, LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         //QUERY ALL REFERRALS A USER HAS
         //i am not proud of this at all.
         $allReferals = [];
@@ -109,6 +127,8 @@ public function json(Request $request)
      */
     public function edit(User $user, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
         $roles = Role::all();
         return view('admin.users.edit')->with([
             'user' => $user,
@@ -134,12 +154,11 @@ public function update(Request $request, User $user)
             'email' => 'required|string|email',
             'credits' => 'required|numeric|min:0|max:99999999',
             'server_limit' => 'required|numeric|min:0|max:1000000',
-            'role' => Rule::in(['admin', 'moderator', 'client', 'member']),
             'referral_code' => "required|string|min:2|max:32|unique:users,referral_code,{$user->id}",
         ]);
 
         //update roles
-        if ($request->roles) {
+        if ($request->roles && $this->can(self::CHANGE_ROLE_PERMISSION)) {
             $user->syncRoles($request->roles);
         }
 
@@ -149,7 +168,7 @@ public function update(Request $request, User $user)
             ]);
         }
 
-        if (!is_null($request->input('new_password'))) {
+        if (!is_null($request->input('new_password')) && $this->can(self::CHANGE_PASSWORD_PERMISSION)) {
             $request->validate([
                 'new_password' => 'required|string|min:8',
                 'new_password_confirmation' => 'required|same:new_password',
@@ -160,7 +179,24 @@ public function update(Request $request, User $user)
             ]);
         }
 
-        $user->update($request->all());
+        if($this->can(self::CHANGE_USERNAME_PERMISSION)){
+           $user->name = $request->name;
+        }
+        if($this->can(self::CHANGE_CREDITS_PERMISSION)){
+            $user->credits = $request->credits;
+        }
+        if($this->can(self::CHANGE_PTERO_PERMISSION)){
+            $user->pterodactyl_id = $request->pterodactyl_id;
+        }
+        if($this->can(self::CHANGE_REFERAL_PERMISSION)){
+            $user->referral_code = $request->referral_code;
+        }
+        if($this->can(self::CHANGE_EMAIL_PERMISSION)){
+            $user->email = $request->email;
+        }
+
+        $user->save();
+
         event(new UserUpdateCreditsEvent($user));
 
         return redirect()->route('admin.users.index')->with('success', 'User updated!');
@@ -174,7 +210,9 @@ public function update(Request $request, User $user)
      */
     public function destroy(User $user)
     {
-        if ($user->hasRole("Admin") && User::query()->where('role', 'admin')->count() === 1) {
+        $this->checkPermission(self::DELETE_PERMISSION);
+
+        if ($user->hasRole(1) && User::role(1)->count() === 1) {
             return redirect()->back()->with('error', __('You can not delete the last admin!'));
         }
 
@@ -203,6 +241,8 @@ public function verifyEmail(User $user)
      */
     public function loginAs(Request $request, User $user)
     {
+        $this->checkPermission(self::LOGIN_PERMISSION);
+
         $request->session()->put('previousUser', Auth::user()->id);
         Auth::login($user);
 
@@ -215,6 +255,8 @@ public function loginAs(Request $request, User $user)
      */
     public function logBackIn(Request $request)
     {
+        $this->checkPermission(self::LOGIN_PERMISSION);
+
         Auth::loginUsingId($request->session()->get('previousUser'), true);
         $request->session()->remove('previousUser');
 
@@ -229,6 +271,8 @@ public function logBackIn(Request $request)
      */
     public function notifications()
     {
+        $this->checkPermission(self::NOTIFY_PERMISSION);
+
         return view('admin.users.notifications');
     }
 
@@ -243,6 +287,8 @@ public function notifications()
      */
     public function notify(Request $request)
     {
+        $this->checkPermission(self::NOTIFY_PERMISSION);
+
         $data = $request->validate([
             'via' => 'required|min:1|array',
             'via.*' => 'required|string|in:mail,database',
@@ -283,6 +329,8 @@ public function notify(Request $request)
      */
     public function toggleSuspended(User $user)
     {
+        $this->checkPermission(self::SUSPEND_PERMISSION);
+
         try {
             !$user->isSuspended() ? $user->suspend() : $user->unSuspend();
         } catch (Exception $exception) {
diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php
index 734981763..f39f9c335 100644
--- a/app/Http/Controllers/Admin/VoucherController.php
+++ b/app/Http/Controllers/Admin/VoucherController.php
@@ -19,6 +19,8 @@
 
 class VoucherController extends Controller
 {
+    const READ_PERMISSION = "admin.voucher.read";
+    const WRITE_PERMISSION = "admin.voucher.write";
     /**
      * Display a listing of the resource.
      *
@@ -26,6 +28,8 @@ class VoucherController extends Controller
      */
     public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.vouchers.index', [
             'locale_datatables' => $locale_settings->datatables,
             'credits_display_name' => $general_settings->credits_display_name
@@ -39,6 +43,7 @@ public function index(LocaleSettings $locale_settings, GeneralSettings $general_
      */
     public function create(GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         return view('admin.vouchers.create', [
             'credits_display_name' => $general_settings->credits_display_name
         ]);
@@ -84,6 +89,7 @@ public function show(Voucher $voucher)
      */
     public function edit(Voucher $voucher, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         return view('admin.vouchers.edit', [
             'voucher' => $voucher,
             'credits_display_name' => $general_settings->credits_display_name
@@ -120,6 +126,7 @@ public function update(Request $request, Voucher $voucher)
      */
     public function destroy(Voucher $voucher)
     {
+        $this->checkPermission(self::WRITE_PERMISSION);
         $voucher->delete();
 
         return redirect()->back()->with('success', __('voucher has been removed!'));
@@ -127,6 +134,8 @@ public function destroy(Voucher $voucher)
 
     public function users(Voucher $voucher, LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
+        $this->checkPermission(self::READ_PERMISSION);
+
         return view('admin.vouchers.users', [
             'voucher' => $voucher,
             'locale_datatables' => $locale_settings->datatables,
diff --git a/config/permissions_web.php b/config/permissions_web.php
index accbd07a0..ad6718427 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -6,13 +6,15 @@
     /*
         * Permissions for admin
         */
-    'admin.sidebar.read',
 
     'admin.roles.read',
-    'admin.roles.write',
+    'admin.roles.create',
+    'admin.roles.edit',
+    'admin.roles.delete',
 
 
     'admin.ticket.read',
+    'admin.tickets.write',
 
     'admin.ticket_blacklist.read',
     'admin.ticket_blacklist.write',
@@ -32,13 +34,17 @@
     'admin.users.write.role',
     'admin.users.write.referal',
     'admin.users.write.pterodactyl',
+    'admin.users.write.email',
+    'admin.users.notify',
+    'admin.users.login_as',
+    'admin.users.delete',
 
     'admin.servers.read',
     'admin.servers.write',
     'admin.servers.suspend',
-    'admin.server.write.owner',
-    'admin.server.write.identifier',
-    'admin.server.delete',
+    'admin.servers.write.owner',
+    'admin.servers.write.identifier',
+    'admin.servers.delete',
 
     'admin.products.read',
     'admin.products.create',
@@ -58,6 +64,11 @@
     'admin.legal.read',
     'admin.legal.write',
 
+    'admin.payments.read',
+
+    'admin.partners.read',
+    'admin.partners.write',
+
     'admin.logs.read',
 
     /*
diff --git a/routes/web.php b/routes/web.php
index c7c6a9de1..5f96806ae 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -17,13 +17,13 @@
 use App\Http\Controllers\Admin\ServerController as AdminServerController;
 use App\Http\Controllers\Admin\SettingsController;
 use App\Http\Controllers\Admin\ShopProductController;
+use App\Http\Controllers\Admin\TicketCategoryController;
+use App\Http\Controllers\Admin\TicketsController as AdminTicketsController;
 use App\Http\Controllers\Admin\UsefulLinkController;
 use App\Http\Controllers\Admin\UserController;
 use App\Http\Controllers\Admin\VoucherController;
 use App\Http\Controllers\Auth\SocialiteController;
 use App\Http\Controllers\HomeController;
-use App\Http\Controllers\Moderation\TicketCategoryController;
-use App\Http\Controllers\Moderation\TicketsController as ModTicketsController;
 use App\Http\Controllers\NotificationController;
 use App\Http\Controllers\ProductController as FrontProductController;
 use App\Http\Controllers\ProfileController;
@@ -117,7 +117,7 @@
 
 
     //admin
-    Route::prefix('admin')->name('admin.')->middleware('admin')->group(function () {
+    Route::prefix('admin')->name('admin.')->group(function () {
         //Roles
         Route::get('roles/datatable', [RoleController::class, 'datatable'])->name('roles.datatable');
         Route::resource('roles', RoleController::class);
@@ -199,29 +199,28 @@
         Route::resource('api', ApplicationApiController::class)->parameters([
             'api' => 'applicationApi',
         ]);
-    });
 
-    //mod
-    Route::prefix('moderator')->name('moderator.')->middleware('moderator')->group(function () {
         //ticket moderation
-        Route::get('ticket', [ModTicketsController::class, 'index'])->name('ticket.index');
-        Route::get('ticket/datatable', [ModTicketsController::class, 'datatable'])->name('ticket.datatable');
-        Route::get('ticket/show/{ticket_id}', [ModTicketsController::class, 'show'])->name('ticket.show');
-        Route::post('ticket/reply', [ModTicketsController::class, 'reply'])->name('ticket.reply');
-        Route::post('ticket/status/{ticket_id}', [ModTicketsController::class, 'changeStatus'])->name('ticket.changeStatus');
-        Route::post('ticket/delete/{ticket_id}', [ModTicketsController::class, 'delete'])->name('ticket.delete');
+        Route::get('ticket', [AdminTicketsController::class, 'index'])->name('ticket.index');
+        Route::get('ticket/datatable', [AdminTicketsController::class, 'datatable'])->name('ticket.datatable');
+        Route::get('ticket/show/{ticket_id}', [AdminTicketsController::class, 'show'])->name('ticket.show');
+        Route::post('ticket/reply', [AdminTicketsController::class, 'reply'])->name('ticket.reply');
+        Route::post('ticket/status/{ticket_id}', [AdminTicketsController::class, 'changeStatus'])->name('ticket.changeStatus');
+        Route::post('ticket/delete/{ticket_id}', [AdminTicketsController::class, 'delete'])->name('ticket.delete');
         //ticket moderation blacklist
-        Route::get('ticket/blacklist', [ModTicketsController::class, 'blacklist'])->name('ticket.blacklist');
-        Route::post('ticket/blacklist', [ModTicketsController::class, 'blacklistAdd'])->name('ticket.blacklist.add');
-        Route::post('ticket/blacklist/delete/{id}', [ModTicketsController::class, 'blacklistDelete'])->name('ticket.blacklist.delete');
-        Route::post('ticket/blacklist/change/{id}', [ModTicketsController::class, 'blacklistChange'])->name('ticket.blacklist.change');
-        Route::get('ticket/blacklist/datatable', [ModTicketsController::class, 'dataTableBlacklist'])->name('ticket.blacklist.datatable');
+        Route::get('ticket/blacklist', [AdminTicketsController::class, 'blacklist'])->name('ticket.blacklist');
+        Route::post('ticket/blacklist', [AdminTicketsController::class, 'blacklistAdd'])->name('ticket.blacklist.add');
+        Route::post('ticket/blacklist/delete/{id}', [AdminTicketsController::class, 'blacklistDelete'])->name('ticket.blacklist.delete');
+        Route::post('ticket/blacklist/change/{id}', [AdminTicketsController::class, 'blacklistChange'])->name('ticket.blacklist.change');
+        Route::get('ticket/blacklist/datatable', [AdminTicketsController::class, 'dataTableBlacklist'])->name('ticket.blacklist.datatable');
 
 
         Route::get('ticket/category/datatable', [TicketCategoryController::class, 'datatable'])->name('ticket.category.datatable');
         Route::resource("ticket/category", TicketCategoryController::class, ['as' => 'ticket']);
     });
 
+
+
     Route::get('/home', [HomeController::class, 'index'])->name('home');
 });
 
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index a5c13de11..aa4a7cf55 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -257,15 +257,15 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                         <li class="nav-header">{{ __('Moderation') }}</li>
 
                         <li class="nav-item">
-                            <a href="{{ route('moderator.ticket.index') }}"
-                               class="nav-link @if (Request::routeIs('moderator.ticket.index')) active @endif">
+                            <a href="{{ route('admin.ticket.index') }}"
+                               class="nav-link @if (Request::routeIs('admin.ticket.index')) active @endif">
                                 <i class="nav-icon fas fa-ticket-alt"></i>
                                 <p>{{ __('Ticket List') }}</p>
                             </a>
                         </li>
                         <li class="nav-item">
-                            <a href="{{ route('moderator.ticket.blacklist') }}"
-                               class="nav-link @if (Request::routeIs('moderator.ticket.blacklist')) active @endif">
+                            <a href="{{ route('admin.ticket.blacklist') }}"
+                               class="nav-link @if (Request::routeIs('admin.ticket.blacklist')) active @endif">
                                 <i class="nav-icon fas fa-user-times"></i>
                                 <p>{{ __('Ticket Blacklist') }}</p>
                             </a>
diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index d5b8d5a8e..1e54c6f6a 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -183,7 +183,7 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
 
                                         @foreach($tickets as $ticket_id => $ticket)
                                             <tr>
-                                                <td><a class="text-info"  href="{{route('moderator.ticket.show', ['ticket_id' => $ticket_id])}}">#{{$ticket_id}} - {{$ticket->title}}</td>
+                                                <td><a class="text-info"  href="{{route('admin.ticket.show', ['ticket_id' => $ticket_id])}}">#{{$ticket_id}} - {{$ticket->title}}</td>
                                                 <td><a href="{{route('admin.users.show', $ticket->user_id)}}">{{$ticket->user}}</a></td>
                                                 <td><span class="badge {{$ticket->statusBadgeColor}}">{{$ticket->status}}</span></td>
                                                 <td>{{$ticket->last_updated}}</td>
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index c72187bd9..5c0f2f999 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -257,28 +257,11 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                                 @endcanany
                         @endif
 
-                        @if ((Auth::user()->hasRole(1) || Auth::user()->role == 'moderator') && $ticket_enabled)
-                            <li class="nav-header">{{ __('Moderation') }}</li>
 
-                            <li class="nav-item">
-                                <a href="{{ route('moderator.ticket.index') }}"
-                                    class="nav-link @if (Request::routeIs('moderator.ticket.index')) active @endif">
-                                    <i class="nav-icon fas fa-ticket-alt"></i>
-                                    <p>{{ __('Ticket List') }}</p>
-                                </a>
-                            </li>
-                            <li class="nav-item">
-                                <a href="{{ route('moderator.ticket.blacklist') }}"
-                                    class="nav-link @if (Request::routeIs('moderator.ticket.blacklist')) active @endif">
-                                    <i class="nav-icon fas fa-user-times"></i>
-                                    <p>{{ __('Ticket Blacklist') }}</p>
-                                </a>
-                            </li>
-                        @endif
 
-                        @if (Auth::user()->hasRole(1))
                             <li class="nav-header">{{ __('Administration') }}</li>
 
+                        @canany(['admin.overview.read','admin.overview.sync'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.overview.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.overview.*')) active @endif">
@@ -286,7 +269,29 @@ class="nav-link @if (Request::routeIs('admin.overview.*')) active @endif">
                                     <p>{{ __('Overview') }}</p>
                                 </a>
                             </li>
+                        @endcanany
+
+                        @canany(['admin.ticket.read','admin.tickets.write'])
+                            <li class="nav-item">
+                                <a href="{{ route('admin.ticket.index') }}"
+                                   class="nav-link @if (Request::routeIs('admin.ticket.index')) active @endif">
+                                    <i class="nav-icon fas fa-ticket-alt"></i>
+                                    <p>{{ __('Ticket List') }}</p>
+                                </a>
+                            </li>
+                        @endcanany
+
+                        @canany(['admin.ticket_blacklist.read','admin.ticket_blacklist.write'])
+                            <li class="nav-item">
+                                <a href="{{ route('admin.ticket.blacklist') }}"
+                                   class="nav-link @if (Request::routeIs('admin.ticket.blacklist')) active @endif">
+                                    <i class="nav-icon fas fa-user-times"></i>
+                                    <p>{{ __('Ticket Blacklist') }}</p>
+                                </a>
+                            </li>
+                        @endcanany
 
+                        @canany(['admin.roles.read','admin.roles.write'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.roles.index') }}"
                                    class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
@@ -294,6 +299,7 @@ class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
                                     <p>{{ __('Role Management') }}</p>
                                 </a>
                             </li>
+                            @endcanany
 
                             <li class="nav-item">
                                 <a href="{{ route('admin.settings.index') }}"
@@ -303,6 +309,7 @@ class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">
                                 </a>
                             </li>
 
+                        @canany(['admin.api.read','admin.api.write'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.api.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
@@ -310,9 +317,18 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                                     <p>{{ __('Application API') }}</p>
                                 </a>
                             </li>
-
+                        @endcanany
                             <li class="nav-header">{{ __('Management') }}</li>
 
+                        @canany(['admin.users.read',
+                                'admin.users.write',
+                                'admin.users.suspend',
+                                'admin.users.write.credits',
+                                'admin.users.write.username',
+                                'admin.users.write.password',
+                                'admin.users.write.role',
+                                'admin.users.write.referal',
+                                'admin.users.write.pterodactyl'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.users.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.users.*')) active @endif">
@@ -320,7 +336,13 @@ class="nav-link @if (Request::routeIs('admin.users.*')) active @endif">
                                     <p>{{ __('Users') }}</p>
                                 </a>
                             </li>
-
+                        @endcanany
+                        @canany(['admin.servers.read',
+                                'admin.servers.write',
+                                'admin.servers.suspend',
+                                'admin.servers.write.owner',
+                                'admin.servers.write.identifier',
+                                'admin.servers.delete'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.servers.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif">
@@ -328,7 +350,11 @@ class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif">
                                     <p>{{ __('Servers') }}</p>
                                 </a>
                             </li>
-
+                        @endcanany
+                        @canany(['admin.products.read',
+                                'admin.products.create',
+                                'admin.products.edit',
+                                'admin.products.delete',])
                             <li class="nav-item">
                                 <a href="{{ route('admin.products.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.products.*')) active @endif">
@@ -336,7 +362,8 @@ class="nav-link @if (Request::routeIs('admin.products.*')) active @endif">
                                     <p>{{ __('Products') }}</p>
                                 </a>
                             </li>
-
+                        @endcanany
+                        @canany(['admin.store.read','admin.store.write','admin.store.disable'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.store.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
@@ -344,7 +371,8 @@ class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
                                     <p>{{ __('Store') }}</p>
                                 </a>
                             </li>
-
+                        @endcanany
+                        @canany(["admin.voucher.read","admin.voucher.read"])
                             <li class="nav-item">
                                 <a href="{{ route('admin.vouchers.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.vouchers.*')) active @endif">
@@ -352,7 +380,8 @@ class="nav-link @if (Request::routeIs('admin.vouchers.*')) active @endif">
                                     <p>{{ __('Vouchers') }}</p>
                                 </a>
                             </li>
-
+                        @endcanany
+                        @canany(["admin.partners.read","admin.partners.read"])
                             <li class="nav-item">
                                 <a href="{{ route('admin.partners.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
@@ -360,28 +389,13 @@ class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
                                     <p>{{ __('Partners') }}</p>
                                 </a>
                             </li>
+                        @endcanany
 
-                            {{-- <li class="nav-header">Pterodactyl</li> --}}
-
-                            {{-- <li class="nav-item"> --}}
-                            {{-- <a href="{{route('admin.nodes.index')}}" --}}
-                            {{-- class="nav-link @if (Request::routeIs('admin.nodes.*')) active @endif"> --}}
-                            {{-- <i class="nav-icon fas fa-sitemap"></i> --}}
-                            {{-- <p>Nodes</p> --}}
-                            {{-- </a> --}}
-                            {{-- </li> --}}
-
-                            {{-- <li class="nav-item"> --}}
-                            {{-- <a href="{{route('admin.nests.index')}}" --}}
-                            {{-- class="nav-link @if (Request::routeIs('admin.nests.*')) active @endif"> --}}
-                            {{-- <i class="nav-icon fas fa-th-large"></i> --}}
-                            {{-- <p>Nests</p> --}}
-                            {{-- </a> --}}
-                            {{-- </li> --}}
-
-
-                            <li class="nav-header">{{ __('Other') }}</li>
+                            @canany(["admin.useful_links.read","admin.legal.read"])
+                                <li class="nav-header">{{ __('Other') }}</li>
+                            @endcanany
 
+                        @canany(["admin.useful_links.read","admin.useful_links.write"])
                             <li class="nav-item">
                                 <a href="{{ route('admin.usefullinks.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.usefullinks.*')) active @endif">
@@ -389,7 +403,9 @@ class="nav-link @if (Request::routeIs('admin.usefullinks.*')) active @endif">
                                     <p>{{ __('Useful Links') }}</p>
                                 </a>
                             </li>
+                            @endcanany
 
+                        @canany(["admin.legal.read","admin.legal.write"])
                             <li class="nav-item">
                                 <a href="{{ route('admin.legal.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.legal.*')) active @endif">
@@ -397,9 +413,14 @@ class="nav-link @if (Request::routeIs('admin.legal.*')) active @endif">
                                     <p>{{ __('Legal Sites') }}</p>
                                 </a>
                             </li>
+                            @endcanany
+
 
-                            <li class="nav-header">{{ __('Logs') }}</li>
+                            @canany(["admin.payments.read","admin.logs.read"])
+                                <li class="nav-header">{{ __('Logs') }}</li>
+                            @endcanany
 
+                        @can("admin.payments.read")
                             <li class="nav-item">
                                 <a href="{{ route('admin.payments.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.payments.*')) active @endif">
@@ -410,7 +431,9 @@ class="badge badge-success right">{{ \App\Models\Payment::count() }}</span>
                                     </p>
                                 </a>
                             </li>
+                        @endcan
 
+                        @can("admin.logs.read")
                             <li class="nav-item">
                                 <a href="{{ route('admin.activitylogs.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
@@ -418,7 +441,8 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
                                     <p>{{ __('Activity Logs') }}</p>
                                 </a>
                             </li>
-                        @endif
+                        @endcan
+
 
                     </ul>
                 </nav>
diff --git a/themes/default/views/mail/ticket/admin/create.blade.php b/themes/default/views/mail/ticket/admin/create.blade.php
index b0b3f1a3f..4ee96a697 100644
--- a/themes/default/views/mail/ticket/admin/create.blade.php
+++ b/themes/default/views/mail/ticket/admin/create.blade.php
@@ -17,7 +17,7 @@
 You can respond to this ticket by simply replying to this email or through the admin area at the url below.
 <br>
 
-{{ route('moderator.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}
+{{ route('admin.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}
 
 <br>
 {{__('Thanks')}},<br>
diff --git a/themes/default/views/mail/ticket/admin/reply.blade.php b/themes/default/views/mail/ticket/admin/reply.blade.php
index 704db26f5..a6f8cceb5 100644
--- a/themes/default/views/mail/ticket/admin/reply.blade.php
+++ b/themes/default/views/mail/ticket/admin/reply.blade.php
@@ -17,7 +17,7 @@
 You can respond to this ticket by simply replying to this email or through the admin area at the url below.
 <br>
 
-{{ route('moderator.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}
+{{ route('admin.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}
 
 <br>
 {{__('Thanks')}},<br>
diff --git a/themes/default/views/moderator/ticket/blacklist.blade.php b/themes/default/views/moderator/ticket/blacklist.blade.php
index 1e91393ce..e26304a16 100644
--- a/themes/default/views/moderator/ticket/blacklist.blade.php
+++ b/themes/default/views/moderator/ticket/blacklist.blade.php
@@ -12,7 +12,7 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{ route('moderator.ticket.blacklist') }}">{{ __('Ticket Blacklist') }}</a>
+                                                       href="{{ route('admin.ticket.blacklist') }}">{{ __('Ticket Blacklist') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -60,7 +60,7 @@
                                 class="fas fa-info-circle"></i></h5>
                         </div>
                         <div class="card-body">
-                            <form action="{{route('moderator.ticket.blacklist.add')}}" method="POST" class="ticket-form">
+                            <form action="{{route('admin.ticket.blacklist.add')}}" method="POST" class="ticket-form">
                             @csrf
                                 <div class="custom-control mb-3 p-0">
                                     <label for="user_id">{{ __('User') }}:
@@ -95,7 +95,7 @@ class="fas fa-info-circle"></i></h5>
                 processing: true,
                 serverSide: true,
                 stateSave: true,
-                ajax: "{{route('moderator.ticket.blacklist.datatable')}}",
+                ajax: "{{route('admin.ticket.blacklist.datatable')}}",
                 columns: [
                     {data: 'user' , name : 'user.name'},
                     {data: 'status'},
diff --git a/themes/default/views/moderator/ticket/category.blade.php b/themes/default/views/moderator/ticket/category.blade.php
index 28f723589..42524285e 100644
--- a/themes/default/views/moderator/ticket/category.blade.php
+++ b/themes/default/views/moderator/ticket/category.blade.php
@@ -12,7 +12,7 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{ route("moderator.ticket.category.index") }}">{{ __('Ticket Categories') }}</a>
+                                                       href="{{ route("admin.ticket.category.index") }}">{{ __('Ticket Categories') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -56,7 +56,7 @@
                             <h5 class="card-title">{{__('Add Category')}}
                         </div>
                         <div class="card-body">
-                            <form action="{{route("moderator.ticket.category.store")}}" method="POST" class="ticket-form">
+                            <form action="{{route("admin.ticket.category.store")}}" method="POST" class="ticket-form">
                             @csrf
                                 <div class="form-group ">
                                     <label for="name" class="control-label">{{__("Name")}}</label>
@@ -73,7 +73,7 @@
                             <h5 class="card-title">{{__('Edit Category')}}
                         </div>
                         <div class="card-body">
-                            <form action="{{route("moderator.ticket.category.update","1")}}" method="POST" class="ticket-form">
+                            <form action="{{route("admin.ticket.category.update","1")}}" method="POST" class="ticket-form">
                                 @csrf
                                 @method('PATCH')
                                 <select id="category" style="width:100%" class="custom-select" name="category"
@@ -109,7 +109,7 @@
                 processing: true,
                 serverSide: true,
                 stateSave: true,
-                ajax: "{{route('moderator.ticket.category.datatable')}}",
+                ajax: "{{route('admin.ticket.category.datatable')}}",
                 columns: [
                     {data: 'id'},
                     {data: 'name'},
diff --git a/themes/default/views/moderator/ticket/index.blade.php b/themes/default/views/moderator/ticket/index.blade.php
index f765b836c..5dc0bb936 100644
--- a/themes/default/views/moderator/ticket/index.blade.php
+++ b/themes/default/views/moderator/ticket/index.blade.php
@@ -12,7 +12,7 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('moderator.ticket.index')}}">{{__('Ticket List')}}</a></li>
+                                                       href="{{route('admin.ticket.index')}}">{{__('Ticket List')}}</a></li>
                     </ol>
                 </div>
             </div>
@@ -30,7 +30,7 @@
                     <div class="d-flex justify-content-between">
                         <h5 class="card-title"><i class="fas fa-ticket-alt mr-2"></i>{{__('Ticket List')}}</h5>
                     </div>
-                    <a href="{{route("moderator.ticket.category.index")}}"><button class="btn btn-primary float-right">+ {{__("Add Category")}}</button></a>
+                    <a href="{{route("admin.ticket.category.index")}}"><button class="btn btn-primary float-right">+ {{__("Add Category")}}</button></a>
                 </div>
 
 
@@ -72,7 +72,7 @@
                 processing: true,
                 serverSide: true,
                 stateSave: true,
-                ajax: "{{route('moderator.ticket.datatable')}}",
+                ajax: "{{route('admin.ticket.datatable')}}",
                 order: [[ 4, "desc" ]],
                 columns: [
                     {data: 'category'},
diff --git a/themes/default/views/moderator/ticket/show.blade.php b/themes/default/views/moderator/ticket/show.blade.php
index 3bec1feba..c2c67def6 100644
--- a/themes/default/views/moderator/ticket/show.blade.php
+++ b/themes/default/views/moderator/ticket/show.blade.php
@@ -12,7 +12,7 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{ route('moderator.ticket.index') }}">{{ __('Ticket') }}</a>
+                                                       href="{{ route('admin.ticket.index') }}">{{ __('Ticket') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -74,7 +74,7 @@
                                     <p><b>{{__("Created on")}}:</b> {{ $ticket->created_at->diffForHumans() }}</p>
                                     @if($ticket->status=='Closed')
                                         <form class="d-inline" method="post"
-                                              action="{{route('moderator.ticket.changeStatus', ['ticket_id' => $ticket->ticket_id ])}}">
+                                              action="{{route('admin.ticket.changeStatus', ['ticket_id' => $ticket->ticket_id ])}}">
                                             {{csrf_field()}}
                                             {{method_field("POST") }}
                                             <button data-content="{{__("Reopen")}}" data-toggle="popover"
@@ -84,7 +84,7 @@ class="fas fa-redo"></i>{{__("Reopen")}}</button>
                                         </form>
                                     @else
                                         <form class="d-inline" method="post"
-                                              action="{{route('moderator.ticket.changeStatus', ['ticket_id' => $ticket->ticket_id ])}}">
+                                              action="{{route('admin.ticket.changeStatus', ['ticket_id' => $ticket->ticket_id ])}}">
                                             {{csrf_field()}}
                                             {{method_field("POST") }}
                                             <button data-content="{{__("Close")}}" data-toggle="popover"
@@ -140,7 +140,7 @@ class="user-image" alt="User Image">
                             </div>
                             @endforeach
                             <div class="comment-form">
-                                <form action="{{ route('moderator.ticket.reply')}}" method="POST" class="form">
+                                <form action="{{ route('admin.ticket.reply')}}" method="POST" class="form">
                                     {!! csrf_field() !!}
                                     <input type="hidden" name="ticket_id" value="{{ $ticket->id }}">
                                     <div class="form-group{{ $errors->has('ticketcomment') ? ' has-error' : '' }}">

From 79432fce8214321c270ea74328ef9dfb49370275 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 01:21:19 +0200
Subject: [PATCH 121/514] Permission on sidebar

---
 app/Http/Controllers/Admin/UserController.php |  1 -
 themes/default/views/layouts/main.blade.php   | 29 +++++++++++++++++--
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 82d27c4e8..2edc3b7e5 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -255,7 +255,6 @@ public function loginAs(Request $request, User $user)
      */
     public function logBackIn(Request $request)
     {
-        $this->checkPermission(self::LOGIN_PERMISSION);
 
         Auth::loginUsingId($request->session()->get('previousUser'), true);
         $request->session()->remove('previousUser');
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 5c0f2f999..bc2da4ab3 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -257,9 +257,10 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                                 @endcanany
                         @endif
 
-
-
+                    <!-- lol how do i make this shorter? -->
+                        @canany(['admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
                             <li class="nav-header">{{ __('Administration') }}</li>
+                        @endcanany
 
                         @canany(['admin.overview.read','admin.overview.sync'])
                             <li class="nav-item">
@@ -318,7 +319,29 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                                 </a>
                             </li>
                         @endcanany
+
+                        <!-- good fuck do i shorten this lol -->
+                        @canany(['admin.users.read',
+                                'admin.users.write',
+                                'admin.users.suspend',
+                                'admin.users.write.credits',
+                                'admin.users.write.username',
+                                'admin.users.write.password',
+                                'admin.users.write.role',
+                                'admin.users.write.referal',
+                                'admin.users.write.pterodactyl','admin.servers.read',
+                                'admin.servers.write',
+                                'admin.servers.suspend',
+                                'admin.servers.write.owner',
+                                'admin.servers.write.identifier',
+                                'admin.servers.delete','admin.products.read',
+                                'admin.products.create',
+                                'admin.products.edit',
+                                'admin.products.delete',])
                             <li class="nav-header">{{ __('Management') }}</li>
+                        @endcanany
+
+
 
                         @canany(['admin.users.read',
                                 'admin.users.write',
@@ -354,7 +377,7 @@ class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif">
                         @canany(['admin.products.read',
                                 'admin.products.create',
                                 'admin.products.edit',
-                                'admin.products.delete',])
+                                'admin.products.delete'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.products.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.products.*')) active @endif">

From 03eef835f7a3cd405e1d2c000c3fa70f60055b7c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 01:28:56 +0200
Subject: [PATCH 122/514] simple settings perms

---
 .../Controllers/Admin/SettingsController.php  |  7 ++++++
 config/permissions_web.php                    | 22 ++-----------------
 themes/default/views/layouts/main.blade.php   |  4 +++-
 3 files changed, 12 insertions(+), 21 deletions(-)

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 7e1c5457f..3c6782f08 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -15,6 +15,9 @@
 
 class SettingsController extends Controller
 {
+
+    const READ_PERMISSIONS = "admin.settings.read";
+    const WRITE_PERMISSIONS = "admin.settings.write";
     /**
      * Display a listing of the resource.
      *
@@ -23,6 +26,8 @@ class SettingsController extends Controller
     public function index()
     {
 
+        $this->checkPermission(self::READ_PERMISSIONS);
+
         // get all other settings in app/Settings directory
         // group items by file name like $categories
         $settings = collect();
@@ -91,6 +96,8 @@ public function index()
      */
     public function update(Request $request)
     {
+        $this->checkPermission(self::WRITE_PERMISSIONS);
+
         $category = request()->get('category');
         $settings_class = request()->get('settings_class');
 
diff --git a/config/permissions_web.php b/config/permissions_web.php
index ad6718427..47ba6a469 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -71,26 +71,8 @@
 
     'admin.logs.read',
 
-    /*
-     * Permissions for settings
-     */
-    'settings.sidebar.read',
-
-    'settings.invoices.read',
-    'settings.invoices.write',
-
-    'settings.language.read',
-    'settings.language.write',
-
-    'settings.misc.read',
-    'settings.misc.write',
-
-    'settings.payment.read',
-    'settings.payment.write',
-
-    'settings.system.read',
-    'settings.system.write',
-
+    'admin.settings.read',
+    'admin.settings.write',
     /*
     * Permissions for users
     */
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index bc2da4ab3..49fc7332a 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -258,7 +258,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                         @endif
 
                     <!-- lol how do i make this shorter? -->
-                        @canany(['admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
+                        @canany(['admin.settings.read','admin.settings.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
                             <li class="nav-header">{{ __('Administration') }}</li>
                         @endcanany
 
@@ -302,6 +302,7 @@ class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
                             </li>
                             @endcanany
 
+                        @canany(['admin.settings.read','admin.settings.write'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.settings.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">
@@ -309,6 +310,7 @@ class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">
                                     <p>{{ __('Settings') }}</p>
                                 </a>
                             </li>
+                        @endcanany
 
                         @canany(['admin.api.read','admin.api.write'])
                             <li class="nav-item">

From a573454810f4775af4c3fd5db51c6ba239b8b243 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 10:59:15 +0200
Subject: [PATCH 123/514] full settings permissions

---
 .../Controllers/Admin/SettingsController.php  |  9 ++--
 config/permissions_web.php                    | 48 ++++++++++++++++++-
 .../views/admin/settings/index.blade.php      |  5 ++
 themes/default/views/layouts/main.blade.php   | 31 +++++++++++-
 4 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 3c6782f08..5b05db2b5 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -16,8 +16,7 @@
 class SettingsController extends Controller
 {
 
-    const READ_PERMISSIONS = "admin.settings.read";
-    const WRITE_PERMISSIONS = "admin.settings.write";
+
     /**
      * Display a listing of the resource.
      *
@@ -26,7 +25,6 @@ class SettingsController extends Controller
     public function index()
     {
 
-        $this->checkPermission(self::READ_PERMISSIONS);
 
         // get all other settings in app/Settings directory
         // group items by file name like $categories
@@ -96,9 +94,10 @@ public function index()
      */
     public function update(Request $request)
     {
-        $this->checkPermission(self::WRITE_PERMISSIONS);
-
         $category = request()->get('category');
+
+        $this->checkPermission("settings.".strtolower($category).".write");
+
         $settings_class = request()->get('settings_class');
 
         if (method_exists($settings_class, 'getValidations')) {
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 47ba6a469..0de102718 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -71,8 +71,52 @@
 
     'admin.logs.read',
 
-    'admin.settings.read',
-    'admin.settings.write',
+    /*
+     * Settings Permissions
+     */
+    'settings.discord.read',
+    'settings.discord.write',
+
+    'settings.general.read',
+    'settings.general.write',
+
+    'settings.invoice.read',
+    'settings.invoice.write',
+
+    'settings.locale.read',
+    'settings.locale.write',
+
+    'settings.mail.read',
+    'settings.mail.write',
+
+    'settings.pterodactyl.read',
+    'settings.pterodactyl.write',
+
+    'settings.referral.read',
+    'settings.referral.write',
+
+    'settings.server.read',
+    'settings.server.write',
+
+    'settings.ticket.read',
+    'settings.ticket.write',
+
+    'settings.user.read',
+    'settings.user.write',
+
+    'settings.website.read',
+    'settings.website.write',
+
+    'settings.paypal.read',
+    'settings.paypal.write',
+
+    'settings.stripe.read',
+    'settings.stripe.write',
+
+    'settings.mollie.read',
+    'settings.mollie.write',
+
+
     /*
     * Permissions for users
     */
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 134e0a959..2c63d4280 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -45,6 +45,7 @@
                                 <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                     data-accordion="false">
                                     @foreach ($settings as $category => $options)
+                                        @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
                                         <li class="nav-item border-bottom-0">
                                             <a href="#{{ $category }}"
                                                 class="nav-link {{ $loop->first ? 'active' : '' }}" data-toggle="pill"
@@ -56,6 +57,7 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                                 </p>
                                             </a>
                                         </li>
+                                        @endcanany
                                     @endforeach
                                 </ul>
                             </nav>
@@ -65,6 +67,7 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                         <div class="col-10 p-0">
                             <div class="tab-content ml-3" style="width: 100%;">
                                 @foreach ($settings as $category => $options)
+                                    @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
                                     <div container class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
                                         id="{{ $category }}" role="tabpanel">
 
@@ -158,6 +161,7 @@ class="custom-select w-100" name="{{ $key }}"
 
                                                     </div>
                                                 </div>
+
                                             @endforeach
 
                                             <!-- TODO: Display this only on the General tab
@@ -195,6 +199,7 @@ class="btn btn-secondary float-right ml-2">Reset</button>
                                             </div>
                                         </form>
                                     </div>
+                                    @endcanany
                                 @endforeach
 
                             </div>
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 49fc7332a..d72bf6ae8 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -258,7 +258,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                         @endif
 
                     <!-- lol how do i make this shorter? -->
-                        @canany(['admin.settings.read','admin.settings.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
+                        @canany(['settings.discord.read','settings.discord.write','settings.general.read','settings.general.write','settings.invoice.read','settings.invoice.write','settings.locale.read','settings.locale.write','settings.mail.read','settings.mail.write','settings.pterodactyl.read','settings.pterodactyl.write','settings.referral.read','settings.referral.write','settings.server.read','settings.server.write','settings.ticket.read','settings.ticket.write','settings.user.read','settings.user.write','settings.website.read','settings.website.write','settings.paypal.read','settings.paypal.write','settings.stripe.read','settings.stripe.write','settings.mollie.read','settings.mollie.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
                             <li class="nav-header">{{ __('Administration') }}</li>
                         @endcanany
 
@@ -302,7 +302,34 @@ class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
                             </li>
                             @endcanany
 
-                        @canany(['admin.settings.read','admin.settings.write'])
+                        @canany(['settings.discord.read',
+                                'settings.discord.write',
+                                'settings.general.read',
+                                'settings.general.write',
+                                'settings.invoice.read',
+                                'settings.invoice.write',
+                                'settings.locale.read',
+                                'settings.locale.write',
+                                'settings.mail.read',
+                                'settings.mail.write',
+                                'settings.pterodactyl.read',
+                                'settings.pterodactyl.write',
+                                'settings.referral.read',
+                                'settings.referral.write',
+                                'settings.server.read',
+                                'settings.server.write',
+                                'settings.ticket.read',
+                                'settings.ticket.write',
+                                'settings.user.read',
+                                'settings.user.write',
+                                'settings.website.read',
+                                'settings.website.write',
+                                'settings.paypal.read',
+                                'settings.paypal.write',
+                                'settings.stripe.read',
+                                'settings.stripe.write',
+                                'settings.mollie.read',
+                                'settings.mollie.write',])
                             <li class="nav-item">
                                 <a href="{{ route('admin.settings.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">

From 7d974d34081c39b87c1c08dee8e89572e715b55f Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 11:17:40 +0200
Subject: [PATCH 124/514] role powers

---
 app/Http/Controllers/Admin/RoleController.php | 15 ++++++++-
 .../2023_05_05_090127_role_power.php          | 32 +++++++++++++++++++
 database/seeders/PermissionsSeeder.php        |  8 ++---
 .../default/views/admin/roles/edit.blade.php  |  7 ++++
 .../default/views/admin/roles/index.blade.php |  2 ++
 5 files changed, 59 insertions(+), 5 deletions(-)
 create mode 100644 database/migrations/2023_05_05_090127_role_power.php

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 3850c1809..9a521938a 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -10,6 +10,7 @@
 use Illuminate\Contracts\View\View;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 use Spatie\Permission\Models\Permission;
 use Spatie\Permission\Models\Role;
 
@@ -66,7 +67,8 @@ public function store(Request $request): RedirectResponse
 
         $role = Role::create([
             'name' => $request->name,
-            'color' => $request->color
+            'color' => $request->color,
+            'power' => $request->power
         ]);
 
         if ($request->permissions) {
@@ -96,6 +98,10 @@ public function edit(Role $role)
     {
         $this->checkPermission(self::EDIT_PERMISSION);
 
+        if(Auth::user()->roles[0]->power < $role->power){
+            return back()->with("error","You dont have enough Power to edit that Role");
+        }
+
         $permissions = Permission::all();
 
         return view('admin.roles.edit', compact('role', 'permissions'));
@@ -111,6 +117,10 @@ public function update(Request $request, Role $role)
     {
         $this->checkPermission(self::EDIT_PERMISSION);
 
+        if(Auth::user()->roles[0]->power < $role->power){
+            return back()->with("error","You dont have enough Power to edit that Role");
+        }
+
         if ($request->permissions) {
             if($role->id != 1){ //disable admin permissions change
                 $role->syncPermissions($request->permissions);
@@ -201,6 +211,9 @@ class="fa fas fa-trash"></i></button>
             ->editColumn('permissionscount', function ($query){
                 return $query->permissions_count;
             })
+            ->editColumn('power', function (Role $role){
+                return $role->power;
+            })
             ->rawColumns(['actions', 'name'])
             ->make(true);
     }
diff --git a/database/migrations/2023_05_05_090127_role_power.php b/database/migrations/2023_05_05_090127_role_power.php
new file mode 100644
index 000000000..9c8da51d0
--- /dev/null
+++ b/database/migrations/2023_05_05_090127_role_power.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('roles', function (Blueprint $table) {
+            $table->integer('power')->after("color")->default(50);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('roles', function (Blueprint $table) {
+            $table->dropColumn('power');
+        });
+    }
+};
diff --git a/database/seeders/PermissionsSeeder.php b/database/seeders/PermissionsSeeder.php
index e688bdf07..e7738e704 100644
--- a/database/seeders/PermissionsSeeder.php
+++ b/database/seeders/PermissionsSeeder.php
@@ -66,10 +66,10 @@ public function createRoles()
             'user.referral',
         ];
         /** @var Role $adminRole */
-        $adminRole = Role::updateOrCreate(["name"=>"Admin","color"=>"#fa0000"]);
-        $supportRole = Role::updateOrCreate(["name"=>"Support-Team","color"=>"#00b0b3"]);
-        $clientRole = Role::updateOrCreate(["name"=>"Client","color"=>"#008009"]);
-        $userRole =  Role::updateOrCreate(["name"=>"User","color"=>"#0052a3"]);
+        $adminRole = Role::updateOrCreate(["name"=>"Admin","color"=>"#fa0000", "power"=>100]);
+        $supportRole = Role::updateOrCreate(["name"=>"Support-Team","color"=>"#00b0b3","power"=>50]);
+        $clientRole = Role::updateOrCreate(["name"=>"Client","color"=>"#008009","power"=>10]);
+        $userRole =  Role::updateOrCreate(["name"=>"User","color"=>"#0052a3","power"=>10]);
 
         $adminRole->givePermissionTo(Permission::findByName('*'));
 
diff --git a/themes/default/views/admin/roles/edit.blade.php b/themes/default/views/admin/roles/edit.blade.php
index 2abbe8087..453233f67 100644
--- a/themes/default/views/admin/roles/edit.blade.php
+++ b/themes/default/views/admin/roles/edit.blade.php
@@ -25,6 +25,13 @@
                                       name="color"
                                       value="{{ isset($role) ? $role->color : null}}"/>
 
+                        <x-input.number label="{{(__('Power'))}}"
+                                      name="power"
+                                        min="1"
+                                        max="100"
+                                        step="1"
+                                      value="{{ isset($role) ? $role->power : 10}}"/>
+
                     </div>
 
                     <div class="col-lg-6">
diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
index 0bc9d3a2e..213a7724d 100644
--- a/themes/default/views/admin/roles/index.blade.php
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -22,6 +22,7 @@ class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
                         <th>{{__("Name")}}</th>
                         <th>{{__("User count")}}</th>
                         <th>{{__("Permissions count")}}</th>
+                        <th>{{__("Power")}}</th>
                         <th>{{__("Actions")}}</th>
                     </tr>
                     </thead>
@@ -49,6 +50,7 @@ class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
                 {data: 'name'},
                 {data: 'usercount'},
                 {data: 'permissionscount'},
+                {data: 'power'},
                 {data: 'actions' , sortable : false},
             ],
             fnDrawCallback: function( oSettings ) {

From e7f19af9f91898523f58a5e8ab8ac5133c2a1555 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 11:38:00 +0200
Subject: [PATCH 125/514] MOTD

---
 .../settings/2023_02_01_182158_create_website_settings.php  | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/database/settings/2023_02_01_182158_create_website_settings.php b/database/settings/2023_02_01_182158_create_website_settings.php
index c7e8fa515..fd542ff33 100644
--- a/database/settings/2023_02_01_182158_create_website_settings.php
+++ b/database/settings/2023_02_01_182158_create_website_settings.php
@@ -14,8 +14,10 @@ public function up(): void
         $this->migrator->add(
             'website.motd_message',
             $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_MESSAGE") :
-                '<h1 style=\"text-align: center;\"><img style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/ctrlpanel.gg\/img\/controlpanel.png\" alt=\"\" width=\"200\" height=\"200\"><span style=\"font-size: 36pt;\">Controlpanel.gg<\/span><\/h1>\r\n<p><span style=\"font-size: 18pt;\">Thank you for using our Software<\/span><\/p>\r\n<p><span style=\"font-size: 18pt;\">If you have any questions, make sure to join our <a href=\"https:\/\/discord.com\/invite\/4Y6HjD2uyU\" target=\"_blank\" rel=\"noopener\">Discord<\/a><\/span><\/p>\r\n<p><span style=\"font-size: 10pt;\">(you can change this message in the <a href=\"admin\/settings#system\">Settings<\/a> )<\/span><\/p>'
-        );
+                "<h1 style='text-align: center;'><img style='display: block; margin-left: auto; margin-right: auto;' src='https://ctrlpanel.gg/img/controlpanel.png' alt=' width='200' height='200'><span style='font-size: 36pt;'>CtrlPanel.gg</span></h1>
+ <p><span style='font-size: 18pt;'>Thank you for using our Software</span></p>
+ <p><span style='font-size: 18pt;'>If you have any questions, make sure to join our <a href='https://discord.com/invite/4Y6HjD2uyU' target='_blank' rel='noopener'>Discord</a></span></p>
+ <p><span style='font-size: 10pt;'>(you can change this message in the <a href='admin/settings#system'>Settings</a> )</span></p>");
         $this->migrator->add('website.show_imprint', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_IMPRINT") : false);
         $this->migrator->add('website.show_privacy', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_PRIVACY") : false);
         $this->migrator->add('website.show_tos', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_TOS") : false);

From 57178da067ebc6827b0b08317cb3890aecfa7a95 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 11:54:12 +0200
Subject: [PATCH 126/514] Update app.php

---
 config/app.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/app.php b/config/app.php
index 534fafe3c..9d82ff72b 100644
--- a/config/app.php
+++ b/config/app.php
@@ -4,7 +4,7 @@
 
 return [
 
-    'version' => '0.9.4',
+    'version' => '0.10',
 
     /*
     |--------------------------------------------------------------------------

From f71b6153e6a86b89a393ef6bfbef4ff93c3421dd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 12:00:10 +0200
Subject: [PATCH 127/514] add back the github branch

---
 app/Providers/AppServiceProvider.php | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index aad430c63..4bd88d897 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -75,5 +75,19 @@ public function boot()
 
         $settings = $this->app->make(MailSettings::class);
         $settings->setConfig();
+
+        try {
+            $stringfromfile = file(base_path() . '/.git/HEAD');
+
+            $firstLine = $stringfromfile[0]; //get the string from the array
+
+            $explodedstring = explode('/', $firstLine, 3); //seperate out by the "/" in the string
+
+            $branchname = $explodedstring[2]; //get the one that is always the branch name
+        } catch (Exception $e) {
+            $branchname = 'unknown';
+            Log::notice($e);
+        }
+        config(['BRANCHNAME' => $branchname]);
     }
 }

From 44db7b4847290227cd2289c6697d19b7ff0faf6e Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 12:01:57 +0200
Subject: [PATCH 128/514] Update AppServiceProvider.php

---
 app/Providers/AppServiceProvider.php | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 4bd88d897..8b82efad9 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -60,6 +60,21 @@ public function boot()
             URL::forceScheme('https');
         }
 
+        //get the Github Branch the panel is running on
+        try {
+            $stringfromfile = file(base_path() . '/.git/HEAD');
+
+            $firstLine = $stringfromfile[0]; //get the string from the array
+
+            $explodedstring = explode('/', $firstLine, 3); //seperate out by the "/" in the string
+
+            $branchname = $explodedstring[2]; //get the one that is always the branch name
+        } catch (Exception $e) {
+            $branchname = 'unknown';
+            Log::notice($e);
+        }
+        config(['BRANCHNAME' => $branchname]);
+
         // Do not run this code if no APP_KEY is set
         if (config('app.key') == null) return;
 
@@ -76,18 +91,5 @@ public function boot()
         $settings = $this->app->make(MailSettings::class);
         $settings->setConfig();
 
-        try {
-            $stringfromfile = file(base_path() . '/.git/HEAD');
-
-            $firstLine = $stringfromfile[0]; //get the string from the array
-
-            $explodedstring = explode('/', $firstLine, 3); //seperate out by the "/" in the string
-
-            $branchname = $explodedstring[2]; //get the one that is always the branch name
-        } catch (Exception $e) {
-            $branchname = 'unknown';
-            Log::notice($e);
-        }
-        config(['BRANCHNAME' => $branchname]);
     }
 }

From 0ca052a2ba94c0ed77694d66977aef0e35f2c8e5 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 12:19:33 +0200
Subject: [PATCH 129/514] remove global verification banner

---
 themes/default/views/layouts/main.blade.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index d72bf6ae8..bff2fe7f9 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -507,6 +507,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
 
         <div class="content-wrapper">
 
+            <!--
             @if (!Auth::user()->hasVerifiedEmail())
                 @if (Auth::user()->created_at->diffInHours(now(), false) > 1)
                     <div class="alert alert-warning p-2 m-2">
@@ -518,6 +519,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
                     </div>
                 @endif
             @endif
+            -->
 
             @yield('content')
 

From d41d0a6e2dcf8d26a27b2bfef9ea2c2cc60969aa Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 12:29:28 +0200
Subject: [PATCH 130/514] ticket notify permission

---
 app/Http/Controllers/TicketsController.php | 23 +++++++++++-----------
 app/Settings/TicketSettings.php            | 13 ------------
 config/permissions_web.php                 |  1 +
 3 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index d5912e435..591c8d851 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -58,17 +58,13 @@ public function store(Request $request, TicketSettings $ticket_settings)
         );
         $ticket->save();
         $user = Auth::user();
-        switch ($ticket_settings->notify) {
-            case 'all':
-                $admin = User::where('role', 'admin')->orWhere('role', 'mod')->get();
-                Notification::send($admin, new AdminCreateNotification($ticket, $user));
-            case 'admin':
-                $admin = User::where('role', 'admin')->get();
-                Notification::send($admin, new AdminCreateNotification($ticket, $user));
-            case 'moderator':
-                $admin = User::where('role', 'mod')->get();
-                Notification::send($admin, new AdminCreateNotification($ticket, $user));
+
+        $staffNotify = User::permission('admin.tickets.get_notification')->get();
+        foreach($staffNotify as $staff){
+            Notification::send($staff, new AdminCreateNotification($ticket, $user));
         }
+
+
         $user->notify(new CreateNotification($ticket));
 
         return redirect()->route('ticket.index')->with('success', __('A ticket has been opened, ID: #') . $ticket->ticket_id);
@@ -112,9 +108,12 @@ public function reply(Request $request)
             'message' => $request->input('message'),
         ]);
         $user = Auth::user();
-        $admin = User::where('role', 'admin')->orWhere('role', 'mod')->get();
         $newmessage = $request->input('ticketcomment');
-        Notification::send($admin, new AdminReplyNotification($ticket, $user, $newmessage));
+
+        $staffNotify = User::permission('admin.tickets.get_notification')->get();
+        foreach($staffNotify as $staff){
+            Notification::send($staff, new AdminReplyNotification($ticket, $user, $newmessage));
+        }
 
         return redirect()->back()->with('success', __('Your comment has been submitted'));
     }
diff --git a/app/Settings/TicketSettings.php b/app/Settings/TicketSettings.php
index 10ac16b14..34fde789c 100644
--- a/app/Settings/TicketSettings.php
+++ b/app/Settings/TicketSettings.php
@@ -7,7 +7,6 @@
 class TicketSettings extends Settings
 {
     public bool $enabled;
-    public string $notify;
 
     public static function group(): string
     {
@@ -22,7 +21,6 @@ public static function getValidations()
     {
         return [
             'enabled' => 'nullable|boolean',
-            'notify' => 'nullable|string',
         ];
     }
 
@@ -40,17 +38,6 @@ public static function getOptionInputData()
                 'type' => 'boolean',
                 'description' => 'Enable or disable the ticket system.',
             ],
-            'notify' => [
-                'label' => 'Notify',
-                'type' => 'select',
-                'description' => 'Who will receive an E-Mail when a new Ticket is created.',
-                'options' => [
-                    'admin' => 'Admins',
-                    'moderator' => 'Moderators',
-                    'all' => 'Admins and Moderators',
-                    'none' => 'Nobody',
-                ],
-            ],
         ];
     }
 }
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 0de102718..71c1cd1ed 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -15,6 +15,7 @@
 
     'admin.ticket.read',
     'admin.tickets.write',
+    'admin.tickets.get_notification',
 
     'admin.ticket_blacklist.read',
     'admin.ticket_blacklist.write',

From 0899df594536fe15d71235a6e4af4f057ee29125 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 5 May 2023 14:06:38 +0200
Subject: [PATCH 131/514] OOM killer & Roles / Permissions API

---
 app/Classes/PterodactylClient.php             |   2 +
 .../Controllers/Admin/ProductController.php   |   5 +
 app/Http/Controllers/Api/RoleController.php   | 155 ++++++++++++++++++
 app/Http/Controllers/Api/UserController.php   |  59 +++----
 .../2023_05_05_103834_oom_killer.php          |  32 ++++
 .../views/admin/products/create.blade.php     |   8 +
 .../views/admin/products/edit.blade.php       |  10 ++
 .../views/admin/products/index.blade.php      |   2 +
 themes/default/views/layouts/main.blade.php   |   2 +-
 themes/default/views/servers/create.blade.php |   6 +
 10 files changed, 251 insertions(+), 30 deletions(-)
 create mode 100644 app/Http/Controllers/Api/RoleController.php
 create mode 100644 database/migrations/2023_05_05_103834_oom_killer.php

diff --git a/app/Classes/PterodactylClient.php b/app/Classes/PterodactylClient.php
index 8f1b116c1..7ac43a3e6 100644
--- a/app/Classes/PterodactylClient.php
+++ b/app/Classes/PterodactylClient.php
@@ -266,6 +266,7 @@ public function createServer(Server $server, Egg $egg, int $allocationId)
             'docker_image' => $egg->docker_image,
             'startup' => $egg->startup,
             'environment' => $egg->getEnvironmentVariables(),
+            'oom_disabled' => !$server->product->oom_killer,
             'limits' => [
                 'memory' => $server->product->memory,
                 'swap' => $server->product->swap,
@@ -378,6 +379,7 @@ public function updateServer(Server $server, Product $product)
             'io' => $product->io,
             'cpu' => $product->cpu,
             'threads' => null,
+            'oom_disabled' => !$server->product->oom_killer,
             'feature_limits' => [
                 'databases' => $product->databases,
                 'backups' => $product->backups,
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 3dc95829b..bfa8bd5a6 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -87,6 +87,7 @@ public function store(Request $request)
             'nodes.*' => 'required|exists:nodes,id',
             'eggs.*' => 'required|exists:eggs,id',
             'disabled' => 'nullable',
+            'oom_killer' => 'nullable',
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -159,6 +160,7 @@ public function update(Request $request, Product $product): RedirectResponse
             'nodes.*' => 'required|exists:nodes,id',
             'eggs.*' => 'required|exists:eggs,id',
             'disabled' => 'nullable',
+            'oom_killer' => 'nullable',
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
@@ -256,6 +258,9 @@ public function dataTable()
             ->editColumn('minimum_credits', function (Product $product, UserSettings $user_settings) {
                 return $product->minimum_credits==-1 ? $user_settings->min_credits_to_make_server : $product->minimum_credits;
             })
+            ->editColumn('oom_killer', function (Product $product, UserSettings $user_settings) {
+                return $product->oom_killer ? __("enabled") : __("disabled");
+            })
             ->editColumn('created_at', function (Product $product) {
                 return $product->created_at ? $product->created_at->diffForHumans() : '';
             })
diff --git a/app/Http/Controllers/Api/RoleController.php b/app/Http/Controllers/Api/RoleController.php
new file mode 100644
index 000000000..190dd6ccb
--- /dev/null
+++ b/app/Http/Controllers/Api/RoleController.php
@@ -0,0 +1,155 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Models\User;
+use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+use Illuminate\Http\Response;
+use Illuminate\Validation\Rule;
+use Spatie\Permission\Models\Role;
+use Spatie\QueryBuilder\QueryBuilder;
+
+class RoleController extends Controller
+{
+    const ALLOWED_INCLUDES = ['permissions', 'users'];
+
+    const ALLOWED_FILTERS = ['name'];
+
+    /**
+     * Display a listing of the resource.
+     *
+     * @return LengthAwarePaginator
+     */
+    public function index(Request $request)
+    {
+        $query = QueryBuilder::for(Role::class)
+            ->allowedIncludes(self::ALLOWED_INCLUDES)
+            ->allowedFilters(self::ALLOWED_FILTERS);
+
+        return $query->paginate($request->input('per_page') ?? 50);
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  Request  $request
+     * @return Response
+     */
+    public function store(Request $request)
+    {
+        $request->validate([
+            'name' => 'nullable|string|max:191',
+            'color' => [
+                'required',
+                'regex:/^#([a-f0-9]{6}|[a-f0-9]{3})$/i'
+            ],
+            'power' => 'required',
+        ]);
+
+        $role = Role::create([
+            'name' => $request->name,
+            'color' => $request->color,
+            'power' => $request->power,
+        ]);
+
+        if ($request->permissions) {
+            $role->givePermissionTo($request->permissions);
+        }
+
+        return $role;
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  int  $id
+     * @return Role|Collection|Model
+     */
+    public function show(int $id)
+    {
+        $query = QueryBuilder::for(Role::class)
+            ->where('id', '=', $id)
+            ->allowedIncludes(self::ALLOWED_INCLUDES);
+
+        return $query->firstOrFail();
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  int  $id
+     * @return Response
+     */
+    public function edit($id)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  Request  $request
+     * @param  int  $id
+     * @return Response
+     */
+    public function update(Request $request, int $id)
+    {
+        $role = Role::findOrFail($id);
+
+        $request->validate([
+            'name' => 'nullable|string|max:191',
+            'color' => [
+                'required',
+                'regex:/^#([a-f0-9]{6}|[a-f0-9]{3})$/i'
+            ],
+            'power' => 'required',
+        ]);
+
+        if ($request->permissions) {
+            $role->givePermissionTo($request->permissions);
+        }
+
+        $role->update($request->all());
+        //TODO PERMISSIONS?
+        return $role;
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  int  $id
+     * @return Response
+     */
+    public function destroy(int $id)
+    {
+        $role = Role::findOrFail($id);
+
+        if($role->id == 1 || $role->id == 3|| $role->id == 4){ //cannot delete admin and User role
+            return response()->json([
+                'error' => 'Not allowed to delete Admin, Client or Member'], 400);
+        }
+
+        $users = User::role($role)->get();
+
+        foreach($users as $user){
+            $user->syncRoles([4]);
+        }
+        $role->delete();
+
+        return $role;
+    }
+}
diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php
index 1a6ef3ebe..0dd445be3 100644
--- a/app/Http/Controllers/Api/UserController.php
+++ b/app/Http/Controllers/Api/UserController.php
@@ -2,16 +2,12 @@
 
 namespace App\Http\Controllers\Api;
 
+use App\Classes\Pterodactyl;
 use App\Events\UserUpdateCreditsEvent;
 use App\Http\Controllers\Controller;
 use App\Models\DiscordUser;
 use App\Models\User;
 use App\Notifications\ReferralNotification;
-use App\Traits\Referral;
-use App\Settings\PterodactylSettings;
-use App\Classes\PterodactylClient;
-use App\Settings\ReferralSettings;
-use App\Settings\UserSettings;
 use Carbon\Carbon;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@@ -31,18 +27,9 @@
 
 class UserController extends Controller
 {
-    use Referral;
+    const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'roles', 'discordUser'];
 
-    const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'discordUser'];
-
-    const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'role', 'suspended'];
-
-    private $pterodactyl;
-
-    public function __construct(PterodactylSettings $ptero_settings)
-    {
-        $this->pterodactyl = new PterodactylClient($ptero_settings);
-    }
+    const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'suspended'];
 
     /**
      * Display a listing of the resource.
@@ -98,14 +85,13 @@ public function update(Request $request, int $id)
             'email' => 'sometimes|string|email',
             'credits' => 'sometimes|numeric|min:0|max:1000000',
             'server_limit' => 'sometimes|numeric|min:0|max:1000000',
-            'role' => ['sometimes', Rule::in(['admin', 'moderator', 'client', 'member'])],
         ]);
 
         event(new UserUpdateCreditsEvent($user));
 
         //Update Users Password on Pterodactyl
         //Username,Mail,First and Lastname are required aswell
-        $response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
+        $response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
             'username' => $request->name,
             'first_name' => $request->name,
             'last_name' => $request->name,
@@ -213,7 +199,7 @@ public function decrement(Request $request, int $id)
      *
      * @throws ValidationException
      */
-    public function suspend(int $id)
+    public function suspend(Request $request, int $id)
     {
         $discordUser = DiscordUser::find($id);
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
@@ -237,12 +223,12 @@ public function suspend(int $id)
      *
      * @throws ValidationException
      */
-    public function unsuspend(int $id)
+    public function unsuspend(Request $request, int $id)
     {
         $discordUser = DiscordUser::find($id);
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
 
-        if (!$user->isSuspended()) {
+        if (! $user->isSuspended()) {
             throw ValidationException::withMessages([
                 'error' => 'You cannot unsuspend an User who is not suspended.',
             ]);
@@ -253,10 +239,25 @@ public function unsuspend(int $id)
         return $user;
     }
 
+    /**
+     * Create a unique Referral Code for User
+     *
+     * @return string
+     */
+    protected function createReferralCode()
+    {
+        $referralcode = STR::random(8);
+        if (User::where('referral_code', '=', $referralcode)->exists()) {
+            $this->createReferralCode();
+        }
+
+        return $referralcode;
+    }
+
     /**
      * @throws ValidationException
      */
-    public function store(Request $request, UserSettings $user_settings, ReferralSettings $referral_settings)
+    public function store(Request $request)
     {
         $request->validate([
             'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
@@ -265,7 +266,7 @@ public function store(Request $request, UserSettings $user_settings, ReferralSet
         ]);
 
         // Prevent the creation of new users via API if this is enabled.
-        if (!$user_settings->creation_enabled) {
+        if (! config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) {
             throw ValidationException::withMessages([
                 'error' => 'The creation of new users has been blocked by the system administrator.',
             ]);
@@ -274,13 +275,13 @@ public function store(Request $request, UserSettings $user_settings, ReferralSet
         $user = User::create([
             'name' => $request->input('name'),
             'email' => $request->input('email'),
-            'credits' => $user_settings->initial_credits,
-            'server_limit' => $user_settings->initial_server_limit,
+            'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
+            'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
             'password' => Hash::make($request->input('password')),
             'referral_code' => $this->createReferralCode(),
         ]);
 
-        $response = $this->pterodactyl->application->post('/application/users', [
+        $response = Pterodactyl::client()->post('/application/users', [
             'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
             'username' => $user->name,
             'email' => $user->email,
@@ -303,12 +304,12 @@ public function store(Request $request, UserSettings $user_settings, ReferralSet
             'pterodactyl_id' => $response->json()['attributes']['id'],
         ]);
         //INCREMENT REFERRAL-USER CREDITS
-        if (!empty($request->input('referral_code'))) {
+        if (! empty($request->input('referral_code'))) {
             $ref_code = $request->input('referral_code');
             $new_user = $user->id;
             if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {
-                if ($referral_settings->mode === 'register' || $referral_settings->mode === 'both') {
-                    $ref_user->increment('credits', $referral_settings->reward);
+                if (config('SETTINGS::REFERRAL:MODE') == 'register' || config('SETTINGS::REFERRAL:MODE') == 'both') {
+                    $ref_user->increment('credits', config('SETTINGS::REFERRAL::REWARD'));
                     $ref_user->notify(new ReferralNotification($ref_user->id, $new_user));
                 }
                 //INSERT INTO USER_REFERRALS TABLE
diff --git a/database/migrations/2023_05_05_103834_oom_killer.php b/database/migrations/2023_05_05_103834_oom_killer.php
new file mode 100644
index 000000000..3fecb34ef
--- /dev/null
+++ b/database/migrations/2023_05_05_103834_oom_killer.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->boolean('oom_killer')->after("allocations")->default(false);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->dropColumn('oom_killer');
+        });
+    }
+};
diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index 0922fc4b2..853fa9b0b 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -131,7 +131,15 @@ class="form-control @error('description') is-invalid @enderror"
                                             </div>
                                             @enderror
                                         </div>
+                                        <div class="form-group">
+                                            <input type="checkbox"  value="1"  id="oom" name="oom_killer"
+                                                   class="">
 
+                                            <label for="oom_killer">{{__('OOM Killer')}} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{__('Enable or Disable the OOM Killer for this Product.')}}"
+                                                    class="fas fa-info-circle"></i></label>
+                                        </div>
                                     </div>
                                     <div class="col-lg-6">
                                         <div class="form-group">
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 4a0d9e24f..8e909af11 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -139,6 +139,16 @@ class="form-control @error('description') is-invalid @enderror"
                                             @enderror
                                         </div>
 
+                                        <div class="form-group">
+                                            <input type="checkbox" @if($product->oom_killer) checked @endif value="1"  id="oom" name="oom_killer"
+                                                   class="">
+
+                                            <label for="oom_killer">{{__('OOM Killer')}} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{__('Enable or Disable the OOM Killer for this Product.')}}"
+                                                    class="fas fa-info-circle"></i></label>
+                                        </div>
+
                                     </div>
                                     <div class="col-lg-6">
                                         <div class="form-group">
diff --git a/themes/default/views/admin/products/index.blade.php b/themes/default/views/admin/products/index.blade.php
index 130a2e1d3..f4eea091f 100644
--- a/themes/default/views/admin/products/index.blade.php
+++ b/themes/default/views/admin/products/index.blade.php
@@ -53,6 +53,7 @@ class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
                             <th>{{__('Nodes')}}</th>
                             <th>{{__('Eggs')}}</th>
                             <th>{{__('Min Credits')}}</th>
+                            <th>{{__('OOM Killer')}}</th>
                             <th>{{__('Servers')}}</th>
                             <th>{{__('Created at')}}</th>
                             <th>{{ __('Actions') }}</th>
@@ -101,6 +102,7 @@ function submitResult() {
                     {data: "nodes", sortable: false},
                     {data: "eggs", sortable: false},
                     {data: "minimum_credits"},
+                    {data: "oom_killer"},
                     {data: "servers", sortable: false},
                     {data: "created_at"},
                     {data: "actions", sortable: false}
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index bff2fe7f9..994f2bfc6 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -18,7 +18,7 @@
         href="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('favicon.ico') }}"
         type="image/x-icon">
 
-    <script src="{{ asset('plugins/alpinejs/3.12.0_cdn.min.js') }}"></script>
+    <script src="{{ asset('plugins/alpinejs/3.12.0_cdn.min.js') }}" defer></script>
 
     {{-- <link rel="stylesheet" href="{{asset('css/adminlte.min.css')}}"> --}}
     <link rel="stylesheet" href="{{ asset('plugins/datatables/jquery.dataTables.min.css') }}">
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index f8e9a5d40..9cef3a98e 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -201,6 +201,12 @@ class="custom-select">
                                                         {{ __('Databases') }}</span>
                                                     <span class="d-inline-block" x-text="product.databases"></span>
                                                 </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-skull-crossbones"></i>
+                                                        {{ __('OOM Killer') }}</span>
+                                                    <span class="d-inline-block"
+                                                          x-text="product.oom_killer == 1 ? 'enabled' : 'disabled'"></span>
+                                                </li>
                                                 <li class="d-flex justify-content-between">
                                                     <span class="d-inline-block"><i class="fas fa-network-wired"></i>
                                                         {{ __('Allocations') }}

From 587e071b87dbe493d5150984061d2556c4f089c8 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 17:38:25 +0200
Subject: [PATCH 132/514] Refactor "Moderator" views

---
 .../default/views/{moderator => admin}/ticket/blacklist.blade.php | 0
 .../default/views/{moderator => admin}/ticket/category.blade.php  | 0
 themes/default/views/{moderator => admin}/ticket/index.blade.php  | 0
 themes/default/views/{moderator => admin}/ticket/show.blade.php   | 0
 4 files changed, 0 insertions(+), 0 deletions(-)
 rename themes/default/views/{moderator => admin}/ticket/blacklist.blade.php (100%)
 rename themes/default/views/{moderator => admin}/ticket/category.blade.php (100%)
 rename themes/default/views/{moderator => admin}/ticket/index.blade.php (100%)
 rename themes/default/views/{moderator => admin}/ticket/show.blade.php (100%)

diff --git a/themes/default/views/moderator/ticket/blacklist.blade.php b/themes/default/views/admin/ticket/blacklist.blade.php
similarity index 100%
rename from themes/default/views/moderator/ticket/blacklist.blade.php
rename to themes/default/views/admin/ticket/blacklist.blade.php
diff --git a/themes/default/views/moderator/ticket/category.blade.php b/themes/default/views/admin/ticket/category.blade.php
similarity index 100%
rename from themes/default/views/moderator/ticket/category.blade.php
rename to themes/default/views/admin/ticket/category.blade.php
diff --git a/themes/default/views/moderator/ticket/index.blade.php b/themes/default/views/admin/ticket/index.blade.php
similarity index 100%
rename from themes/default/views/moderator/ticket/index.blade.php
rename to themes/default/views/admin/ticket/index.blade.php
diff --git a/themes/default/views/moderator/ticket/show.blade.php b/themes/default/views/admin/ticket/show.blade.php
similarity index 100%
rename from themes/default/views/moderator/ticket/show.blade.php
rename to themes/default/views/admin/ticket/show.blade.php

From 5e46bbbe7e75109b581126d2ac877f9bc68c68db Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 18:43:28 +0200
Subject: [PATCH 133/514] Cleanup Middleware, Fix locale

---
 .../Controllers/Admin/SettingsController.php  |  6 +++-
 app/Http/Kernel.php                           |  3 --
 app/Http/Middleware/GlobalNames.php           | 25 -----------------
 app/Http/Middleware/isAdmin.php               | 28 -------------------
 app/Http/Middleware/isMod.php                 | 27 ------------------
 .../views/admin/settings/index.blade.php      |  4 +--
 6 files changed, 7 insertions(+), 86 deletions(-)
 delete mode 100644 app/Http/Middleware/GlobalNames.php
 delete mode 100644 app/Http/Middleware/isAdmin.php
 delete mode 100644 app/Http/Middleware/isMod.php

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 5b05db2b5..7d1657f1d 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -119,16 +119,20 @@ public function update(Request $request)
             $rp = new \ReflectionProperty($settingsClass, $key);
             $rpType = $rp->getType();
 
+
             if ($rpType == 'bool') {
                 $settingsClass->$key = $request->has($key);
                 continue;
             }
+            if ($rp->name == 'available') {
+                $settingsClass->$key = implode(",",$request->$key);
+                continue;
+            }
 
             $nullable = $rpType->allowsNull();
             if ($nullable) $settingsClass->$key = $request->input($key) ?? null;
             else $settingsClass->$key = $request->input($key);
         }
-
         $settingsClass->save();
 
 
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index a6fb149b0..d0b1c7f7e 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -4,7 +4,6 @@
 
 use App\Http\Middleware\ApiAuthToken;
 use App\Http\Middleware\CheckSuspended;
-use App\Http\Middleware\GlobalNames;
 use App\Http\Middleware\isAdmin;
 use App\Http\Middleware\isMod;
 use App\Http\Middleware\LastSeen;
@@ -44,14 +43,12 @@ class Kernel extends HttpKernel
             \App\Http\Middleware\VerifyCsrfToken::class,
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
             LastSeen::class,
-            GlobalNames::class,
             \App\Http\Middleware\SetLocale::class,
         ],
 
         'api' => [
             'throttle:api',
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
-            GlobalNames::class,
         ],
     ];
 
diff --git a/app/Http/Middleware/GlobalNames.php b/app/Http/Middleware/GlobalNames.php
deleted file mode 100644
index 9250f23bf..000000000
--- a/app/Http/Middleware/GlobalNames.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use Closure;
-use Illuminate\Http\Request;
-
-class GlobalNames
-{
-    /**
-     * Handle an incoming request.
-     *
-     * @param  Request  $request
-     * @param  Closure  $next
-     * @return mixed
-     */
-    public function handle(Request $request, Closure $next)
-    {
-        $unsupported_lang_array = explode(',', config('app.unsupported_locales'));
-        $unsupported_lang_array = array_map('strtolower', $unsupported_lang_array);
-        define('UNSUPPORTED_LANGS', $unsupported_lang_array);
-
-        return $next($request);
-    }
-}
diff --git a/app/Http/Middleware/isAdmin.php b/app/Http/Middleware/isAdmin.php
deleted file mode 100644
index 6e8202a43..000000000
--- a/app/Http/Middleware/isAdmin.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use App\Providers\RouteServiceProvider;
-use Closure;
-use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Auth;
-
-class isAdmin
-{
-    /**
-     * Handle an incoming request.
-     *
-     * @param  Request  $request
-     * @param  Closure  $next
-     * @return mixed
-     */
-    public function handle(Request $request, Closure $next)
-    {
-        //if (Auth::user() && Auth::user()->hasRole("Admin")) {
-        if (Auth::user() && Auth::user()->hasRole(1)) {
-            return $next($request);
-        }
-
-        return redirect(RouteServiceProvider::HOME);
-    }
-}
diff --git a/app/Http/Middleware/isMod.php b/app/Http/Middleware/isMod.php
deleted file mode 100644
index 51d6db851..000000000
--- a/app/Http/Middleware/isMod.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use App\Providers\RouteServiceProvider;
-use Closure;
-use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Auth;
-
-class isMod
-{
-    /**
-     * Handle an incoming request.
-     *
-     * @param  Request  $request
-     * @param  Closure  $next
-     * @return mixed
-     */
-    public function handle(Request $request, Closure $next)
-    {
-        if (Auth::user() && Auth::user()->role == 'moderator' || Auth::user() && Auth::user()->hasRole(1)) {
-            return $next($request);
-        }
-
-        return redirect(RouteServiceProvider::HOME);
-    }
-}
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 2c63d4280..db4344b6e 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -132,11 +132,11 @@ class="custom-select w-100" name="{{ $key }}">
 
                                                                     @case($value['type'] == 'multiselect')
                                                                         <select id="{{ $key }}"
-                                                                            class="custom-select w-100" name="{{ $key }}"
+                                                                            class="custom-select w-100" name="{{ $key }}[]"
                                                                             multiple>
                                                                             @foreach ($value['options'] as $option)
                                                                                 <option value="{{ $option }}"
-                                                                                    {{ $value['value'] == $option ? 'selected' : '' }}>
+                                                                                    {{ strpos($value['value'],$option) !== false  ? 'selected' : '' }}>
                                                                                     {{ __($option) }}
                                                                                 </option>
                                                                             @endforeach

From f72447dfa13576029cb75915b22377ac886f5ba5 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 18:57:57 +0200
Subject: [PATCH 134/514] fix view of partner programm

---
 themes/default/views/home.blade.php | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/themes/default/views/home.blade.php b/themes/default/views/home.blade.php
index 119c50ffe..8993972c7 100644
--- a/themes/default/views/home.blade.php
+++ b/themes/default/views/home.blade.php
@@ -203,9 +203,7 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                         </div>
                         <!-- /.card-header -->
                         <div class="card-body py-0 pb-2">
-                            @if (
-                                ($referral_settings->allowed == 'client' && Auth::user()->role != 'member') ||
-                                    $referral_settings->allowed == 'everyone')
+                            @if (Auth::user()->can("user.referral"))
                                 <div class="row">
                                     <div class="mt-3 col-md-8">
                                         <span class="badge badge-success" style="font-size: 14px">
@@ -254,15 +252,14 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                                     <table class="table">
                                         <thead>
                                             <tr>
-                                                <th>{{ __('Reward per registered user') }}</th>
-                                                <th>{{ __('New user payment commision') }}</th>
+                                                @if(in_array($referral_settings->mode, ["Commission","Both"]))<th>{{ __('Reward per registered user') }}</th> @endif
+                                                @if(in_array($referral_settings->mode, ["Sign-Up","Both"]))<th>{{ __('New user payment commision') }}</th> @endif
                                             </tr>
                                         </thead>
                                         <tbody>
                                             <tr>
-                                                <td>{{ $referral_settings->reward }}
-                                                    {{ $general_settings->credits_display_name }}</td>
-                                                <td>{{ $referral_settings->percentage }}%</td>
+                                                @if(in_array($referral_settings->mode, ["Commission","Both"]))<td>{{ $referral_settings->reward }} {{ $general_settings->credits_display_name }}</td> @endif
+                                                @if(in_array($referral_settings->mode, ["Sign-Up","Both"]))<td>{{ $referral_settings->percentage }}%</td> @endif
                                             </tr>
                                         </tbody>
                                     </table>

From 28afc71d7f26e37a2493742fbbb6b24d4d303804 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 19:05:50 +0200
Subject: [PATCH 135/514] remove "allowed" on referral. its now a permission

---
 app/Settings/ReferralSettings.php                    | 12 +-----------
 .../2023_02_01_182135_create_referral_settings.php   |  1 -
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/app/Settings/ReferralSettings.php b/app/Settings/ReferralSettings.php
index e49fbaae3..47d086465 100644
--- a/app/Settings/ReferralSettings.php
+++ b/app/Settings/ReferralSettings.php
@@ -6,7 +6,6 @@
 
 class ReferralSettings extends Settings
 {
-    public string $allowed;
     public bool $always_give_commission;
     public bool $enabled;
     public ?float $reward;
@@ -43,19 +42,10 @@ public static function getOptionInputData()
     {
         return [
             'category_icon' => 'fas fa-user-friends',
-            'allowed' => [
-                'label' => 'Allowed',
-                'type' => 'select',
-                'description' => 'Who is allowed to see their referral-URL',
-                'options' => [
-                    'everyone' => 'Everyone',
-                    'clients' => 'Clients',
-                ],
-            ],
             'always_give_commission' => [
                 'label' => 'Always Give Commission',
                 'type' => 'boolean',
-                'description' => 'Always give commission to the referrer.',
+                'description' => 'Always give commission to the referrer or only on the first Purchase.',
             ],
             'enabled' => [
                 'label' => 'Enabled',
diff --git a/database/settings/2023_02_01_182135_create_referral_settings.php b/database/settings/2023_02_01_182135_create_referral_settings.php
index 8a2cde829..5727557b1 100644
--- a/database/settings/2023_02_01_182135_create_referral_settings.php
+++ b/database/settings/2023_02_01_182135_create_referral_settings.php
@@ -10,7 +10,6 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('referral.allowed', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ALLOWED') : 'client');
         $this->migrator->add('referral.always_give_commission', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION') : false);
         $this->migrator->add('referral.enabled', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ENABLED') : false);
         $this->migrator->add('referral.reward', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::REWARD') : 100);

From a2a54262528f8ebc8692e015cdb16faeb60b54fd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 19:45:50 +0200
Subject: [PATCH 136/514] fix cloning

---
 app/Http/Controllers/Admin/ProductController.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index bfa8bd5a6..c05a13032 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -52,12 +52,13 @@ public function create(GeneralSettings $general_settings)
         ]);
     }
 
-    public function clone(Product $product)
+    public function clone(Product $product, GeneralSettings $general_settings)
     {
         $this->checkPermission(self::WRITE_PERMISSION);
 
         return view('admin.products.create', [
             'product' => $product,
+            'credits_display_name' =>  $general_settings->credits_display_name,
             'locations' => Location::with('nodes')->get(),
             'nests' => Nest::with('eggs')->get(),
         ]);

From 8279f071569c0b4e77b0f24e6c4b6df8086fd71c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 19:49:05 +0200
Subject: [PATCH 137/514] new Permission
 "admin.servers.bypass_creation_enabled"

---
 app/Http/Controllers/ServerController.php | 2 +-
 config/permissions_web.php                | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index acd4392e3..30262cac0 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -164,7 +164,7 @@ private function validateConfigurationRules(UserSettings $user_settings, ServerS
         }
 
         //Required Verification for creating an server
-        if (!$server_settings->creation_enabled && Auth::user()->role != 'admin') {
+        if (!$server_settings->creation_enabled && Auth::user()->cannot("admin.servers.bypass_creation_enabled")) {
             return redirect()->route('servers.index')->with('error', __('The system administrator has blocked the creation of new servers.'));
         }
 
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 71c1cd1ed..0ae789ca7 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -46,6 +46,7 @@
     'admin.servers.write.owner',
     'admin.servers.write.identifier',
     'admin.servers.delete',
+    'admin.servers.bypass_creation_enabled',
 
     'admin.products.read',
     'admin.products.create',

From bc56f713ad84899540bcf794f736843e583f9216 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 7 May 2023 21:24:26 +0200
Subject: [PATCH 138/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Call=20parent=20c?=
 =?UTF-8?q?onstructor=20on=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Models/Server.php | 2 ++
 app/Models/User.php   | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/app/Models/Server.php b/app/Models/Server.php
index 21d2c2456..8fb64c02e 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -69,6 +69,8 @@ public function getActivitylogOptions(): LogOptions
 
     public function __construct()
     {
+        parent::__construct();
+
         $ptero_settings = new PterodactylSettings();
         $this->pterodactyl = new PterodactylClient($ptero_settings);
     }
diff --git a/app/Models/User.php b/app/Models/User.php
index d25a71009..eabbf0cbf 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -93,6 +93,8 @@ class User extends Authenticatable implements MustVerifyEmail
 
     public function __construct()
     {
+        parent::__construct();
+
         $ptero_settings = new PterodactylSettings();
         $this->pterodactyl = new PterodactylClient($ptero_settings);
     }

From a32d42feabd0ef278d195c961f9a88b3d4c93d88 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 21:41:26 +0200
Subject: [PATCH 139/514] OOM Killer

---
 app/Http/Controllers/Admin/ProductController.php |  7 +++++--
 themes/default/views/servers/index.blade.php     |  2 +-
 themes/default/views/servers/settings.blade.php  | 12 ++++++++++++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index c05a13032..33d98c504 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -91,8 +91,10 @@ public function store(Request $request)
             'oom_killer' => 'nullable',
         ]);
 
+
         $disabled = ! is_null($request->input('disabled'));
-        $product = Product::create(array_merge($request->all(), ['disabled' => $disabled]));
+        $oomkiller = ! is_null($request->input('oom_killer'));
+        $product = Product::create(array_merge($request->all(), ['disabled' => $disabled, 'oom_killer' => $oomkiller]));
 
         //link nodes and eggs
         $product->eggs()->attach($request->input('eggs'));
@@ -165,7 +167,8 @@ public function update(Request $request, Product $product): RedirectResponse
         ]);
 
         $disabled = ! is_null($request->input('disabled'));
-        $product->update(array_merge($request->all(), ['disabled' => $disabled]));
+        $oomkiller = ! is_null($request->input('oom_killer'));
+        $product->update(array_merge($request->all(), ['disabled' => $disabled, 'oom_killer' => $oomkiller]));
 
         //link nodes and eggs
         $product->eggs()->detach();
diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index df47ae53f..93f31b7d2 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -103,7 +103,7 @@ class="fas fa-info-circle"></i>
                                             <span>{{ $server->product->name }}
                                             </span>
                                             <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                                data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>"
+                                                data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>{{ __('OOM Killer') }}: {{ $server->product->oom_killer ? __("enabled") : __("disabled") }} <br/>"
                                                 class="fas fa-info-circle"></i>
                                         </div>
 
diff --git a/themes/default/views/servers/settings.blade.php b/themes/default/views/servers/settings.blade.php
index 4ef717443..9525cd238 100644
--- a/themes/default/views/servers/settings.blade.php
+++ b/themes/default/views/servers/settings.blade.php
@@ -204,6 +204,18 @@
                                 </div>
                             </div>
                         </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('OOM Killer')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->product->oom_killer ? __("enabled") : __("disabled") }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
                         <div class="col-lg-6">
                             <div class="row">
                                 <div class="col-lg-4">

From b07238cbed2f5ac8ac3699bc02a266373856a302 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 21:57:13 +0200
Subject: [PATCH 140/514] customizable ticket information

---
 app/Http/Controllers/TicketsController.php            |  3 ++-
 app/Settings/TicketSettings.php                       |  7 +++++++
 .../2023_02_04_181156_create_ticket_settings.php      |  1 -
 .../settings/2023_05_07_195343_ticket_information.php | 11 +++++++++++
 themes/default/views/ticket/index.blade.php           |  3 +--
 5 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 database/settings/2023_05_07_195343_ticket_information.php

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index 591c8d851..de59bf883 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -23,9 +23,10 @@ class TicketsController extends Controller
 {
     const READ_PERMISSION = 'user.ticket.read';
     const WRITE_PERMISSION = 'user.ticket.write';
-    public function index(LocaleSettings $locale_settings)
+    public function index(LocaleSettings $locale_settings, TicketSettings $ticketSettings)
     {
         return view('ticket.index', [
+            'ticketsettings' => $ticketSettings,
             'tickets' => Ticket::where('user_id', Auth::user()->id)->paginate(10),
             'ticketcategories' => TicketCategory::all(),
             'locale_datatables' => $locale_settings->datatables
diff --git a/app/Settings/TicketSettings.php b/app/Settings/TicketSettings.php
index 34fde789c..cd621b173 100644
--- a/app/Settings/TicketSettings.php
+++ b/app/Settings/TicketSettings.php
@@ -7,6 +7,7 @@
 class TicketSettings extends Settings
 {
     public bool $enabled;
+    public ?string $information;
 
     public static function group(): string
     {
@@ -21,6 +22,7 @@ public static function getValidations()
     {
         return [
             'enabled' => 'nullable|boolean',
+            'information' => 'nullable|string',
         ];
     }
 
@@ -38,6 +40,11 @@ public static function getOptionInputData()
                 'type' => 'boolean',
                 'description' => 'Enable or disable the ticket system.',
             ],
+            'information' => [
+                'label' => 'Ticket Information',
+                'type' => 'textarea',
+                'description' => 'Message shown on the right side when users create a new ticket.',
+            ],
         ];
     }
 }
diff --git a/database/settings/2023_02_04_181156_create_ticket_settings.php b/database/settings/2023_02_04_181156_create_ticket_settings.php
index fcdcd588e..701ca14ae 100644
--- a/database/settings/2023_02_04_181156_create_ticket_settings.php
+++ b/database/settings/2023_02_04_181156_create_ticket_settings.php
@@ -11,7 +11,6 @@ public function up(): void
 
         // Get the user-set configuration values from the old table.
         $this->migrator->add('ticket.enabled', $table_exists ? $this->getOldValue('SETTINGS::TICKET:ENABLED') : 'all');
-        $this->migrator->add('ticket.notify', $table_exists ? $this->getOldValue('SETTINGS::TICKET:NOTIFY') : 'all');
     }
 
     public function down(): void
diff --git a/database/settings/2023_05_07_195343_ticket_information.php b/database/settings/2023_05_07_195343_ticket_information.php
new file mode 100644
index 000000000..a4d89f25c
--- /dev/null
+++ b/database/settings/2023_05_07_195343_ticket_information.php
@@ -0,0 +1,11 @@
+<?php
+
+use Spatie\LaravelSettings\Migrations\SettingsMigration;
+
+return new class extends SettingsMigration
+{
+    public function up(): void
+    {
+        $this->migrator->add('ticket.information',  "Can't start your server? Need an additional port? Do you have any other questions? Let us know by opening a ticket.");
+    }
+};
diff --git a/themes/default/views/ticket/index.blade.php b/themes/default/views/ticket/index.blade.php
index 0c1d40988..aae642215 100644
--- a/themes/default/views/ticket/index.blade.php
+++ b/themes/default/views/ticket/index.blade.php
@@ -66,8 +66,7 @@ class="fas fa-info-circle"></i></h5>
 
                         </div>
                         <div class="card-body">
-                            <p>{{__("Can't start your server? Need an additional port? Do you have any other questions? Let us know by
-                                opening a ticket.")}}</p>
+                            <p>{!! $ticketsettings->information !!}</p>
 
                         </div>
                     </div>

From 3d8a1cf53fa69047e082ab17e865f85937dc31bf Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 7 May 2023 22:36:50 +0200
Subject: [PATCH 141/514] notify groups (check validation needed)

---
 app/Http/Controllers/Admin/UserController.php | 20 ++++++++++++++-----
 .../views/admin/users/notifications.blade.php | 12 +++++++++--
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 2edc3b7e5..4956e565c 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -272,7 +272,9 @@ public function notifications()
     {
         $this->checkPermission(self::NOTIFY_PERMISSION);
 
-        return view('admin.users.notifications');
+        $roles = Role::all();
+
+        return view('admin.users.notifications')->with(["roles" => $roles]);
     }
 
     /**
@@ -288,12 +290,14 @@ public function notify(Request $request)
     {
         $this->checkPermission(self::NOTIFY_PERMISSION);
 
+//TODO: reimplement the required validation on all,users and roles . didnt work -- required_without:users,roles
         $data = $request->validate([
             'via' => 'required|min:1|array',
             'via.*' => 'required|string|in:mail,database',
-            'all' => 'required_without:users|boolean',
-            'users' => 'required_without:all|min:1|array',
-            'users.*' => 'exists:users,id',
+            'all' => 'boolean',
+            'users' => 'min:1|array',
+            'roles' => 'min:1|array',
+            'roles.*' => 'required_without:all,users|exists:roles,id',
             'title' => 'required|string|min:1',
             'content' => 'required|string|min:1',
         ]);
@@ -312,7 +316,13 @@ public function notify(Request $request)
                 ->line(new HtmlString($data['content']));
         }
         $all = $data['all'] ?? false;
-        $users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
+        if(!$data["roles"]){
+            $users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
+        } else{
+            $users = User::role($data["roles"])->get();
+        }
+
+
         try {
             Notification::send($users, new DynamicNotification($data['via'], $database, $mail));
         } catch (Exception $e) {
diff --git a/themes/default/views/admin/users/notifications.blade.php b/themes/default/views/admin/users/notifications.blade.php
index 53a87f19a..e29303add 100644
--- a/themes/default/views/admin/users/notifications.blade.php
+++ b/themes/default/views/admin/users/notifications.blade.php
@@ -33,13 +33,20 @@
                                 @method('POST')
 
                                 <div class="form-group">
-                                    <label>{{__('Users')}}</label><br>
                                     <input id="all" name="all"
                                            type="checkbox" value="1"
                                            onchange="toggleClass('users-form', 'd-none')">
-                                    <label for="all">{{__('All')}}</label>
+                                    <label for="all">{{__('All')}}</label><br>
                                     <div id="users-form">
+                                        <label>{{__('Users')}}</label><br>
                                         <select id="users" name="users[]" class="form-control" multiple></select>
+
+                                        <label>{{__('Roles')}}</label><br>
+                                        <select id="roles" name="roles[]" onchange="toggleClass('users', 'd-none')" class="form-control" multiple>
+                                            @foreach($roles as $role)
+                                                <option value="{{$role->id}}">{{$role->name}}</option>
+                                            @endforeach
+                                        </select>
                                     </div>
                                     @error('all')
                                         <div class="invalid-feedback d-block">
@@ -126,6 +133,7 @@ class="form-control @error('content') is-invalid @enderror">
             })
 
             function initUserSelect(data) {
+                $('#roles').select2();
                 $('#users').select2({
                     ajax: {
                         url: '/admin/users.json',

From 6ef0b63c36ba8162fb8f0c2d6595fb1b28fc3392 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 10:45:47 +0200
Subject: [PATCH 142/514] API Fixes || Missing: Update Role

---
 app/Http/Controllers/Api/RoleController.php | 17 +++++++++++------
 app/Http/Controllers/Api/UserController.php |  5 ++++-
 routes/api.php                              |  3 +++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/app/Http/Controllers/Api/RoleController.php b/app/Http/Controllers/Api/RoleController.php
index 190dd6ccb..65e2cb69e 100644
--- a/app/Http/Controllers/Api/RoleController.php
+++ b/app/Http/Controllers/Api/RoleController.php
@@ -52,7 +52,7 @@ public function create()
     public function store(Request $request)
     {
         $request->validate([
-            'name' => 'nullable|string|max:191',
+            'name' => 'required|string|max:191',
             'color' => [
                 'required',
                 'regex:/^#([a-f0-9]{6}|[a-f0-9]{3})$/i'
@@ -67,7 +67,10 @@ public function store(Request $request)
         ]);
 
         if ($request->permissions) {
-            $role->givePermissionTo($request->permissions);
+            $permissions = explode(",",$request->permissions);
+            foreach($permissions as $permission){
+                $role->givePermissionTo($permission);
+            }
         }
 
         return $role;
@@ -111,7 +114,7 @@ public function update(Request $request, int $id)
         $role = Role::findOrFail($id);
 
         $request->validate([
-            'name' => 'nullable|string|max:191',
+            'name' => 'required|string|max:191',
             'color' => [
                 'required',
                 'regex:/^#([a-f0-9]{6}|[a-f0-9]{3})$/i'
@@ -120,11 +123,13 @@ public function update(Request $request, int $id)
         ]);
 
         if ($request->permissions) {
-            $role->givePermissionTo($request->permissions);
+            $permissions = explode(",",$request->permissions);
+                $role->syncPermissions($permissions);
         }
 
-        $role->update($request->all());
-        //TODO PERMISSIONS?
+
+        $role->update($request->except('permissions'));
+
         return $role;
     }
 
diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php
index 0dd445be3..78e56da2f 100644
--- a/app/Http/Controllers/Api/UserController.php
+++ b/app/Http/Controllers/Api/UserController.php
@@ -104,7 +104,10 @@ public function update(Request $request, int $id)
                 'pterodactyl_error_status' => $response->toException()->getCode(),
             ]);
         }
-        $user->update($request->all());
+        if($request->has("role")){
+            $user->syncRoles($request->role);
+        }
+        $user->update($request->except('role'));
 
         return $user;
     }
diff --git a/routes/api.php b/routes/api.php
index 74333b749..141b7529d 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -1,6 +1,7 @@
 <?php
 
 use App\Http\Controllers\Api\NotificationController;
+use App\Http\Controllers\Api\RoleController;
 use App\Http\Controllers\Api\ServerController;
 use App\Http\Controllers\Api\UserController;
 use App\Http\Controllers\Api\VoucherController;
@@ -31,6 +32,8 @@
     //    Route::get('/vouchers/{voucher}/users' , [VoucherController::class , 'users']);
     Route::resource('vouchers', VoucherController::class)->except('create', 'edit');
 
+    Route::resource('roles', RoleController::class);
+
     Route::get('/notifications/{user}', [NotificationController::class, 'index']);
     Route::get('/notifications/{user}/{notification}', [NotificationController::class, 'view']);
     Route::post('/notifications', [NotificationController::class, 'send']);

From 4a4f6bebdb2512aafe2245a31a6fce8bd5b15aa1 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 10:55:37 +0200
Subject: [PATCH 143/514] Role API Update

---
 app/Http/Controllers/Api/RoleController.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/Api/RoleController.php b/app/Http/Controllers/Api/RoleController.php
index 65e2cb69e..928473f8d 100644
--- a/app/Http/Controllers/Api/RoleController.php
+++ b/app/Http/Controllers/Api/RoleController.php
@@ -114,12 +114,12 @@ public function update(Request $request, int $id)
         $role = Role::findOrFail($id);
 
         $request->validate([
-            'name' => 'required|string|max:191',
+            'name' => 'sometimes|string|max:191',
             'color' => [
-                'required',
+                'sometimes',
                 'regex:/^#([a-f0-9]{6}|[a-f0-9]{3})$/i'
             ],
-            'power' => 'required',
+            'power' => 'sometimes',
         ]);
 
         if ($request->permissions) {

From e965b5f5c43d7a5f8283e52e85bc83ff8634dea8 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 11:03:11 +0200
Subject: [PATCH 144/514] PermissionsSeeder in Migration

---
 database/migrations/2023_05_05_090127_role_power.php | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/database/migrations/2023_05_05_090127_role_power.php b/database/migrations/2023_05_05_090127_role_power.php
index 9c8da51d0..1bf02c444 100644
--- a/database/migrations/2023_05_05_090127_role_power.php
+++ b/database/migrations/2023_05_05_090127_role_power.php
@@ -2,6 +2,7 @@
 
 use Illuminate\Database\Migrations\Migration;
 use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\Schema;
 
 return new class extends Migration
@@ -16,6 +17,10 @@ public function up()
         Schema::table('roles', function (Blueprint $table) {
             $table->integer('power')->after("color")->default(50);
         });
+
+        Artisan::call('db:seed', [
+            '--class' => 'PermissionsSeeder',
+        ]);
     }
 
     /**

From e6f02d0679094984a986e344a19e42ee3d045895 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 11:09:49 +0200
Subject: [PATCH 145/514] force the seeder

---
 database/migrations/2023_05_05_090127_role_power.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/database/migrations/2023_05_05_090127_role_power.php b/database/migrations/2023_05_05_090127_role_power.php
index 1bf02c444..7eb0d9113 100644
--- a/database/migrations/2023_05_05_090127_role_power.php
+++ b/database/migrations/2023_05_05_090127_role_power.php
@@ -20,6 +20,7 @@ public function up()
 
         Artisan::call('db:seed', [
             '--class' => 'PermissionsSeeder',
+            '--force' => true
         ]);
     }
 

From ae9ab59dec6aeda9bad891f5e582529bfe24e7d3 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 8 May 2023 11:10:51 +0200
Subject: [PATCH 146/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Make=20migrations?=
 =?UTF-8?q?=20be=20compatible=20to=20installed=20addon?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...022_07_21_234818_undo_decimal_in_price.php | 32 -------------------
 ...092704_add_billing_period_to_products.php} |  8 +++--
 ...8_094402_update_user_credits_datatype.php} |  3 +-
 ...5818_add_last_billed_field_to_servers.php} |  5 +++
 ...4527_add_cancelation_to_servers_table.php} |  5 +++
 lang/en.json                                  |  1 -
 6 files changed, 17 insertions(+), 37 deletions(-)
 delete mode 100644 database/migrations/2022_07_21_234818_undo_decimal_in_price.php
 rename database/migrations/{2022_06_16_092704_add_billing_period_to_products.php => 2023_05_08_092704_add_billing_period_to_products.php} (89%)
 rename database/migrations/{2022_06_16_094402_update_user_credits_datatype.php => 2023_05_08_094402_update_user_credits_datatype.php} (89%)
 rename database/migrations/{2022_06_16_095818_add_last_billed_field_to_servers.php => 2023_05_08_095818_add_last_billed_field_to_servers.php} (83%)
 rename database/migrations/{2022_07_21_234527_add_cancelation_to_servers_table.php => 2023_05_08_234527_add_cancelation_to_servers_table.php} (82%)

diff --git a/database/migrations/2022_07_21_234818_undo_decimal_in_price.php b/database/migrations/2022_07_21_234818_undo_decimal_in_price.php
deleted file mode 100644
index cf4abb69b..000000000
--- a/database/migrations/2022_07_21_234818_undo_decimal_in_price.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-use Illuminate\Database\Migrations\Migration;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Support\Facades\Schema;
-
-class UndoDecimalInPrice extends Migration
-{
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        Schema::table('products', function (Blueprint $table) {
-            $table->decimal('price', 15, 4)->change();
-        });
-    }
-
-    /**
-     * Reverse the migrations.
-     *
-     * @return void
-     */
-    public function down()
-    {
-        Schema::table('products', function (Blueprint $table) {
-            $table->decimal('price',['11','2'])->change();
-        });
-    }
-}
diff --git a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php b/database/migrations/2023_05_08_092704_add_billing_period_to_products.php
similarity index 89%
rename from database/migrations/2022_06_16_092704_add_billing_period_to_products.php
rename to database/migrations/2023_05_08_092704_add_billing_period_to_products.php
index ceed9362f..c4a7ac9ac 100644
--- a/database/migrations/2022_06_16_092704_add_billing_period_to_products.php
+++ b/database/migrations/2023_05_08_092704_add_billing_period_to_products.php
@@ -14,11 +14,16 @@ class AddBillingPeriodToProducts extends Migration
      */
     public function up()
     {
+        // User already has installed the addon before
+        if (Schema::hasColumn("products", "billing_period")) {
+            return;
+        }
+
         Schema::table('products', function (Blueprint $table) {
+
             $table->string('billing_period')->default("hourly");
             $table->decimal('price', 15, 4)->change();
             $table->decimal('minimum_credits', 15, 4)->change();
-
         });
 
         DB::statement('UPDATE products SET billing_period="hourly"');
@@ -29,7 +34,6 @@ public function up()
             $price = $price / 30 / 24;
             DB::table('products')->where('id', $product->id)->update(['price' => $price]);
         }
-
     }
 
     /**
diff --git a/database/migrations/2022_06_16_094402_update_user_credits_datatype.php b/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
similarity index 89%
rename from database/migrations/2022_06_16_094402_update_user_credits_datatype.php
rename to database/migrations/2023_05_08_094402_update_user_credits_datatype.php
index ed5922e86..292102ccc 100644
--- a/database/migrations/2022_06_16_094402_update_user_credits_datatype.php
+++ b/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
@@ -26,8 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->unsignedFloat('credits')->default(250)->change();
-
+            $table->decimal('price', ['11', '2'])->change();
         });
     }
 }
diff --git a/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php b/database/migrations/2023_05_08_095818_add_last_billed_field_to_servers.php
similarity index 83%
rename from database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php
rename to database/migrations/2023_05_08_095818_add_last_billed_field_to_servers.php
index 6b05f3a5b..9d43ae96d 100644
--- a/database/migrations/2022_06_16_095818_add_last_billed_field_to_servers.php
+++ b/database/migrations/2023_05_08_095818_add_last_billed_field_to_servers.php
@@ -14,6 +14,11 @@ class AddLastBilledFieldToServers extends Migration
      */
     public function up()
     {
+        // User already has installed the addon before
+        if (Schema::hasColumn("servers", "last_billed")) {
+            return;
+        }
+
         Schema::table('servers', function (Blueprint $table) {
             $table->dateTime('last_billed')->default(DB::raw('CURRENT_TIMESTAMP'))->nullable();
         });
diff --git a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php b/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
similarity index 82%
rename from database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
rename to database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
index 15fafb168..0d0f4e203 100644
--- a/database/migrations/2022_07_21_234527_add_cancelation_to_servers_table.php
+++ b/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
@@ -13,6 +13,11 @@ class AddCancelationToServersTable extends Migration
      */
     public function up()
     {
+        // User already has installed the addon before
+        if (Schema::hasColumn("servers", "cancelled")) {
+            return;
+        }
+
         Schema::table('servers', function (Blueprint $table) {
             $table->dateTime('cancelled')->nullable();
         });
diff --git a/lang/en.json b/lang/en.json
index 4db852063..90f23aae0 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -600,5 +600,4 @@
     "Billing period": "Billing period",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
     "Caution": "Caution"
-    "hu": "Hungarian"
 }

From ad5ff407614cac9b1c037e1ceb0f6b8bd941ecf0 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 8 May 2023 11:26:47 +0200
Subject: [PATCH 147/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Old=20settings=20?=
 =?UTF-8?q?relict?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php    | 16 ++++++++--------
 themes/default/views/servers/index.blade.php |  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 23d032bff..10917ee00 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -48,7 +48,7 @@ public function index(GeneralSettings $general_settings, PterodactylSettings $pt
 
             //Get server infos from ptero
             $serverAttributes = $this->pterodactyl->getServerAttributes($server->pterodactyl_id);
-            if (! $serverAttributes) {
+            if (!$serverAttributes) {
                 continue;
             }
             $serverRelationships = $serverAttributes['relationships'];
@@ -90,7 +90,7 @@ public function create(UserSettings $user_settings, ServerSettings $server_setti
     {
         $this->checkPermission(self::CREATE_PERMISSION);
 
-        $validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings);
+        $validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings, $general_settings);
 
         if (!is_null($validate_configuration)) {
             return $validate_configuration;
@@ -132,7 +132,7 @@ public function create(UserSettings $user_settings, ServerSettings $server_setti
     /**
      * @return null|RedirectResponse
      */
-    private function validateConfigurationRules(UserSettings $user_settings, ServerSettings $server_settings)
+    private function validateConfigurationRules(UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $generalSettings)
     {
         //limit validation
         if (Auth::user()->servers()->count() >= Auth::user()->server_limit) {
@@ -157,7 +157,7 @@ private function validateConfigurationRules(UserSettings $user_settings, ServerS
             if (Auth::user()->credits < ($product->minimum_credits == -1
                 ? $user_settings->min_credits_to_make_server
                 : $product->minimum_credits)) {
-                return redirect()->route('servers.index')->with('error', 'You do not have the required amount of '.CREDITS_DISPLAY_NAME.' to use this product!');
+                return redirect()->route('servers.index')->with('error', 'You do not have the required amount of ' . $generalSettings->credits_display_name . ' to use this product!');
             }
         }
 
@@ -180,12 +180,12 @@ private function validateConfigurationRules(UserSettings $user_settings, ServerS
     }
 
     /** Store a newly created resource in storage. */
-    public function store(Request $request, UserSettings $user_settings, ServerSettings $server_settings)
+    public function store(Request $request, UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $generalSettings)
     {
         /** @var Node $node */
         /** @var Egg $egg */
         /** @var Product $product */
-        $validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings);
+        $validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings, $generalSettings);
 
         if (!is_null($validate_configuration)) {
             return $validate_configuration;
@@ -211,7 +211,7 @@ public function store(Request $request, UserSettings $user_settings, ServerSetti
 
         //get free allocation ID
         $allocationId = $this->pterodactyl->getFreeAllocationId($node);
-        if (! $allocationId) {
+        if (!$allocationId) {
             return $this->noAllocationsError($server);
         }
 
@@ -338,7 +338,7 @@ public function upgrade(Server $server, Request $request)
         if ($server->user_id != Auth::user()->id) {
             return redirect()->route('servers.index');
         }
-        if (! isset($request->product_upgrade)) {
+        if (!isset($request->product_upgrade)) {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('this product is the only one'));
         }
         $user = Auth::user();
diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index 74dc6378e..83b39354c 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -174,7 +174,7 @@ class="fas fa-info-circle"></i>
                                     <div class="col-4">
                                         {{ __('Price') }}:
                                         <span class="text-muted">
-                                            ({{ CREDITS_DISPLAY_NAME }})
+                                            ({{ $credits_display_name }})
                                         </span>
                                     </div>
                                     <div class="col-8 text-center">

From da338aacdcc8d11d48537b561c0750ff8ead3dba Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 8 May 2023 11:35:28 +0200
Subject: [PATCH 148/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Old=20settings=20?=
 =?UTF-8?q?relict=20the=20second?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/servers/index.blade.php | 22 +++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index 83b39354c..e700b15d6 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -204,19 +204,17 @@ class="fas fa-info-circle"></i>
                         </div>
 
                         <div class="card-footer text-center">
-                            <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
+                            <a href="{{ $pterodactyl_url }}/server/{{ $server->identifier }}"
                                 target="__blank"
                                 class="btn btn-info text-center float-left ml-2"
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
                                 <i class="fas fa-tools mx-2"></i>
                             </a>
-                            @if(config("SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN"))
                             <a href="{{ route('servers.show', ['server' => $server->id])}}"
                             	class="btn btn-info text-center mr-3"
                             	data-toggle="tooltip" data-placement="bottom" title="{{ __('Server Settings') }}">
                                 <i class="fas fa-cog mx-2"></i>
                             </a>
-                            @endif
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
                                 {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
@@ -260,7 +258,14 @@ class="btn btn-danger  text-center float-right mr-2"
                         }
                     }).then(() => {
                         window.location.reload();
-                    });
+                    }).catch((error) => {
+                        Swal.fire({
+                            title: "{{ __('Error') }}",
+                            text: "{{ __('Something went wrong, please try again later.') }}",
+                            icon: 'error',
+                            confirmButtonColor: '#d9534f',
+                        })
+                    })
                     return
                 }
             })
@@ -286,7 +291,14 @@ class="btn btn-danger  text-center float-right mr-2"
                         }
                     }).then(() => {
                         window.location.reload();
-                    });
+                    }).catch((error) => {
+                        Swal.fire({
+                            title: "{{ __('Error') }}",
+                            text: "{{ __('Something went wrong, please try again later.') }}",
+                            icon: 'error',
+                            confirmButtonColor: '#d9534f',
+                        })
+                    })
                     return
                 }
             });

From b1aaaeb329b59b628894f1837dee344dff9adc43 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 8 May 2023 11:39:21 +0200
Subject: [PATCH 149/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20add=20missing=20c?=
 =?UTF-8?q?ancel=20functionality?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Http/Controllers/ServerController.php | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 10917ee00..6324f870e 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -276,7 +276,13 @@ public function destroy(Server $server)
     /** Cancel Server */
     public function cancel(Server $server)
     {
+        if ($server->user_id != Auth::user()->id) {
+            return back()->with('error', __('This is not your Server!'));
+        }
         try {
+            $server->update([
+                'cancelled' => now(),
+            ]);
             return redirect()->route('servers.index')->with('success', __('Server cancelled'));
         } catch (Exception $e) {
             return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
@@ -286,8 +292,6 @@ public function cancel(Server $server)
     /** Show Server Settings */
     public function show(Server $server, ServerSettings $server_settings, GeneralSettings $general_settings)
     {
-
-
         if ($server->user_id != Auth::user()->id) {
             return back()->with('error', __('This is not your Server!'));
         }

From 6bba6123c602eef7110a4b8daa43a4730e4f9760 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 11:55:17 +0200
Subject: [PATCH 150/514] Update to new Settings

---
 app/Http/Controllers/Api/UserController.php   |   5 +-
 routes/web.php                                |   4 +-
 .../BlueInfinity/views/layouts/app.blade.php  |   2 +-
 .../BlueInfinity/views/layouts/main.blade.php | 240 ++++++++++++------
 4 files changed, 172 insertions(+), 79 deletions(-)

diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php
index 0dd445be3..726eb9e86 100644
--- a/app/Http/Controllers/Api/UserController.php
+++ b/app/Http/Controllers/Api/UserController.php
@@ -8,6 +8,7 @@
 use App\Models\DiscordUser;
 use App\Models\User;
 use App\Notifications\ReferralNotification;
+use App\Settings\UserSettings;
 use Carbon\Carbon;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@@ -257,7 +258,7 @@ protected function createReferralCode()
     /**
      * @throws ValidationException
      */
-    public function store(Request $request)
+    public function store(Request $request, UserSettings $userSettings)
     {
         $request->validate([
             'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
@@ -266,7 +267,7 @@ public function store(Request $request)
         ]);
 
         // Prevent the creation of new users via API if this is enabled.
-        if (! config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) {
+        if (! $userSettings->creation_enabled) {
             throw ValidationException::withMessages([
                 'error' => 'The creation of new users has been blocked by the system administrator.',
             ]);
diff --git a/routes/web.php b/routes/web.php
index 6f682f7f0..8de0863e3 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -75,7 +75,9 @@
     Route::resource('notifications', NotificationController::class);
     Route::patch('/servers/cancel/{server}', [ServerController::class, 'cancel'])->name('servers.cancel');
     Route::resource('servers', ServerController::class);
-    if (config('SETTINGS::SYSTEM:ENABLE_UPGRADE')) {
+
+    $serverSettings = app(App\Settings\ServerSettings::class);
+    if ($serverSettings->enable_upgrade) {
         Route::post('servers/{server}/upgrade', [ServerController::class, 'upgrade'])->name('servers.upgrade');
     }
 
diff --git a/themes/BlueInfinity/views/layouts/app.blade.php b/themes/BlueInfinity/views/layouts/app.blade.php
index 07050e684..376f1d920 100644
--- a/themes/BlueInfinity/views/layouts/app.blade.php
+++ b/themes/BlueInfinity/views/layouts/app.blade.php
@@ -27,7 +27,7 @@
     <noscript>
         <link rel="stylesheet" href="{{ asset('plugins/fontawesome-free/css/all.min.css') }}">
     </noscript>
-    @if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true')
+    @if (app(App\Settings\GeneralSettings::class)->recaptcha_enabled)
         {!! htmlScriptTagJsApi() !!}
     @endif
     <link rel="stylesheet" href="{{ asset('themes/BlueInfinity/app.css') }}">
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index aa4a7cf55..b6549a7a0 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -2,22 +2,26 @@
 <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
 
 <head>
+    @php($website_settings = app(App\Settings\WebsiteSettings::class))
+    @php($general_settings = app(App\Settings\GeneralSettings::class))
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <!-- CSRF Token -->
     <meta name="csrf-token" content="{{ csrf_token() }}">
-    <meta content="{{ config('SETTINGS::SYSTEM:SEO_TITLE') }}" property="og:title">
-    <meta content="{{ config('SETTINGS::SYSTEM:SEO_DESCRIPTION') }}" property="og:description">
-    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}' property="og:image">
+    <meta content="{{ $website_settings->seo_title }}" property="og:title">
+    <meta content="{{ $website_settings->seo_description }}" property="og:description">
+    <meta
+        content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}'
+        property="og:image">
     <title>{{ config('app.name', 'Laravel') }}</title>
     <link rel="icon"
           href="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('favicon.ico') }}"
           type="image/x-icon">
 
-    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
+    <script src="{{ asset('plugins/alpinejs/3.12.0_cdn.min.js') }}" defer></script>
 
     {{-- <link rel="stylesheet" href="{{asset('css/adminlte.min.css')}}"> --}}
-    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.css" />
+    <link rel="stylesheet" href="{{ asset('plugins/datatables/jquery.dataTables.min.css') }}">
 
     {{-- summernote --}}
     <link rel="stylesheet" href="{{ asset('plugins/summernote/summernote-bs4.min.css') }}">
@@ -36,7 +40,7 @@
     </noscript>
     <script src="{{ asset('js/app.js') }}"></script>
     <!-- tinymce -->
-    <script src={{ asset('plugins/tinymce/js/tinymce/tinymce.min.js') }}></script>
+    <script src="{{ asset('plugins/tinymce/js/tinymce/tinymce.min.js') }}"></script>
     <link rel="stylesheet" href="{{ asset('themes/BlueInfinity/app.css') }}">
 </head>
 
@@ -54,15 +58,16 @@ class="fas fa-bars"></i></a>
                 <a href="{{ route('home') }}" class="nav-link"><i
                         class="fas fa-home mr-2"></i>{{ __('Home') }}</a>
             </li>
-            @if (config('SETTINGS::DISCORD:INVITE_URL'))
+            @if (!empty($discord_settings->invite_url))
                 <li class="nav-item d-none d-sm-inline-block">
-                    <a href="{{ config('SETTINGS::DISCORD:INVITE_URL') }}" class="nav-link" target="__blank"><i
+                    <a href="{{ $discord_settings->invite_url }}" class="nav-link" target="__blank"><i
                             class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                 </li>
             @endif
 
             <!-- Language Selection -->
-            @if (config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true')
+            @php($locale_settings = app(App\Settings\LocaleSettings::class))
+            @if ($locale_settings->clients_can_change)
                 <li class="nav-item dropdown">
                     <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
                        aria-haspopup="true" aria-expanded="false">
@@ -74,7 +79,7 @@ class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                          aria-labelledby="changeLocale">
                         <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
                             @csrf
-                            @foreach (explode(',', config('SETTINGS::LOCALE:AVAILABLE')) as $key)
+                            @foreach (explode(',', $locale_settings->available) as $key)
                                 <button class="dropdown-item" name="inputLocale" value="{{ $key }}">
                                     {{ __($key) }}
                                 </button>
@@ -85,10 +90,10 @@ class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                 </li>
                 <!-- End Language Selection -->
             @endif
-            @foreach($useful_links as $link)
+            @foreach ($useful_links as $link)
                 <li class="nav-item d-none d-sm-inline-block">
                     <a href="{{ $link->link }}" class="nav-link" target="__blank"><i
-                            class="{{$link->icon}}"></i> {{ $link->title }}</a>
+                            class="{{ $link->icon }}"></i> {{ $link->title }}</a>
                 </li>
             @endforeach
         </ul>
@@ -230,11 +235,7 @@ class="nav-link @if (Request::routeIs('servers.*')) active @endif">
                         </a>
                     </li>
 
-                    @if (env('APP_ENV') == 'local' ||
-                        (config('SETTINGS::PAYMENTS:PAYPAL:SECRET') && config('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID')) ||
-                        (config('SETTINGS::PAYMENTS:STRIPE:SECRET') &&
-                            config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') &&
-                            config('SETTINGS::PAYMENTS:STRIPE:METHODS')))
+                    @if (env('APP_ENV') == 'local' || $general_settings->store_enabled)
                         <li class="nav-item">
                             <a href="{{ route('store.index') }}"
                                class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')) active @endif">
@@ -243,19 +244,35 @@ class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')
                             </a>
                         </li>
                     @endif
-                    @if (config('SETTINGS::TICKET:ENABLED'))
+                    @php($ticket_enabled = app(App\Settings\TicketSettings::class)->enabled)
+                    @if ($ticket_enabled)
+                        @canany(["user.ticket.read", "user.ticket.write"])
+                            <li class="nav-item">
+                                <a href="{{ route('ticket.index') }}"
+                                   class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
+                                    <i class="nav-icon fas fas fa-ticket-alt"></i>
+                                    <p>{{ __('Support Ticket') }}</p>
+                                </a>
+                            </li>
+                        @endcanany
+                    @endif
+
+                    <!-- lol how do i make this shorter? -->
+                    @canany(['settings.discord.read','settings.discord.write','settings.general.read','settings.general.write','settings.invoice.read','settings.invoice.write','settings.locale.read','settings.locale.write','settings.mail.read','settings.mail.write','settings.pterodactyl.read','settings.pterodactyl.write','settings.referral.read','settings.referral.write','settings.server.read','settings.server.write','settings.ticket.read','settings.ticket.write','settings.user.read','settings.user.write','settings.website.read','settings.website.write','settings.paypal.read','settings.paypal.write','settings.stripe.read','settings.stripe.write','settings.mollie.read','settings.mollie.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
+                        <li class="nav-header">{{ __('Administration') }}</li>
+                    @endcanany
+
+                    @canany(['admin.overview.read','admin.overview.sync'])
                         <li class="nav-item">
-                            <a href="{{ route('ticket.index') }}"
-                               class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
-                                <i class="nav-icon fas fas fa-ticket-alt"></i>
-                                <p>{{ __('Support Ticket') }}</p>
+                            <a href="{{ route('admin.overview.index') }}"
+                               class="nav-link @if (Request::routeIs('admin.overview.*')) active @endif">
+                                <i class="nav-icon fa fa-home"></i>
+                                <p>{{ __('Overview') }}</p>
                             </a>
                         </li>
-                    @endif
-
-                    @if ((Auth::user()->hasRole("Admin") || Auth::user()->role == 'moderator') && config('SETTINGS::TICKET:ENABLED'))
-                        <li class="nav-header">{{ __('Moderation') }}</li>
+                    @endcanany
 
+                    @canany(['admin.ticket.read','admin.tickets.write'])
                         <li class="nav-item">
                             <a href="{{ route('admin.ticket.index') }}"
                                class="nav-link @if (Request::routeIs('admin.ticket.index')) active @endif">
@@ -263,6 +280,9 @@ class="nav-link @if (Request::routeIs('admin.ticket.index')) active @endif">
                                 <p>{{ __('Ticket List') }}</p>
                             </a>
                         </li>
+                    @endcanany
+
+                    @canany(['admin.ticket_blacklist.read','admin.ticket_blacklist.write'])
                         <li class="nav-item">
                             <a href="{{ route('admin.ticket.blacklist') }}"
                                class="nav-link @if (Request::routeIs('admin.ticket.blacklist')) active @endif">
@@ -270,20 +290,46 @@ class="nav-link @if (Request::routeIs('admin.ticket.blacklist')) active @endif">
                                 <p>{{ __('Ticket Blacklist') }}</p>
                             </a>
                         </li>
-                    @endif
-
-                    @if (Auth::user()->hasRole("Admin"))
-                        <li class="nav-header">{{ __('Administration') }}</li>
+                    @endcanany
 
+                    @canany(['admin.roles.read','admin.roles.write'])
                         <li class="nav-item">
-                            <a href="{{ route('admin.overview.index') }}"
-                               class="nav-link @if (Request::routeIs('admin.overview.*')) active @endif">
-                                <i class="nav-icon fa fa-home"></i>
-                                <p>{{ __('Overview') }}</p>
+                            <a href="{{ route('admin.roles.index') }}"
+                               class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
+                                <i class="nav-icon fa fa-user-check"></i>
+                                <p>{{ __('Role Management') }}</p>
                             </a>
                         </li>
-
-
+                    @endcanany
+
+                    @canany(['settings.discord.read',
+                            'settings.discord.write',
+                            'settings.general.read',
+                            'settings.general.write',
+                            'settings.invoice.read',
+                            'settings.invoice.write',
+                            'settings.locale.read',
+                            'settings.locale.write',
+                            'settings.mail.read',
+                            'settings.mail.write',
+                            'settings.pterodactyl.read',
+                            'settings.pterodactyl.write',
+                            'settings.referral.read',
+                            'settings.referral.write',
+                            'settings.server.read',
+                            'settings.server.write',
+                            'settings.ticket.read',
+                            'settings.ticket.write',
+                            'settings.user.read',
+                            'settings.user.write',
+                            'settings.website.read',
+                            'settings.website.write',
+                            'settings.paypal.read',
+                            'settings.paypal.write',
+                            'settings.stripe.read',
+                            'settings.stripe.write',
+                            'settings.mollie.read',
+                            'settings.mollie.write',])
                         <li class="nav-item">
                             <a href="{{ route('admin.settings.index') }}"
                                class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">
@@ -291,7 +337,9 @@ class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">
                                 <p>{{ __('Settings') }}</p>
                             </a>
                         </li>
+                    @endcanany
 
+                    @canany(['admin.api.read','admin.api.write'])
                         <li class="nav-item">
                             <a href="{{ route('admin.api.index') }}"
                                class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
@@ -299,9 +347,40 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                                 <p>{{ __('Application API') }}</p>
                             </a>
                         </li>
-
+                    @endcanany
+
+                    <!-- good fuck do i shorten this lol -->
+                    @canany(['admin.users.read',
+                            'admin.users.write',
+                            'admin.users.suspend',
+                            'admin.users.write.credits',
+                            'admin.users.write.username',
+                            'admin.users.write.password',
+                            'admin.users.write.role',
+                            'admin.users.write.referal',
+                            'admin.users.write.pterodactyl','admin.servers.read',
+                            'admin.servers.write',
+                            'admin.servers.suspend',
+                            'admin.servers.write.owner',
+                            'admin.servers.write.identifier',
+                            'admin.servers.delete','admin.products.read',
+                            'admin.products.create',
+                            'admin.products.edit',
+                            'admin.products.delete',])
                         <li class="nav-header">{{ __('Management') }}</li>
+                    @endcanany
+
+
 
+                    @canany(['admin.users.read',
+                            'admin.users.write',
+                            'admin.users.suspend',
+                            'admin.users.write.credits',
+                            'admin.users.write.username',
+                            'admin.users.write.password',
+                            'admin.users.write.role',
+                            'admin.users.write.referal',
+                            'admin.users.write.pterodactyl'])
                         <li class="nav-item">
                             <a href="{{ route('admin.users.index') }}"
                                class="nav-link @if (Request::routeIs('admin.users.*')) active @endif">
@@ -309,7 +388,13 @@ class="nav-link @if (Request::routeIs('admin.users.*')) active @endif">
                                 <p>{{ __('Users') }}</p>
                             </a>
                         </li>
-
+                    @endcanany
+                    @canany(['admin.servers.read',
+                            'admin.servers.write',
+                            'admin.servers.suspend',
+                            'admin.servers.write.owner',
+                            'admin.servers.write.identifier',
+                            'admin.servers.delete'])
                         <li class="nav-item">
                             <a href="{{ route('admin.servers.index') }}"
                                class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif">
@@ -317,7 +402,11 @@ class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif">
                                 <p>{{ __('Servers') }}</p>
                             </a>
                         </li>
-
+                    @endcanany
+                    @canany(['admin.products.read',
+                            'admin.products.create',
+                            'admin.products.edit',
+                            'admin.products.delete'])
                         <li class="nav-item">
                             <a href="{{ route('admin.products.index') }}"
                                class="nav-link @if (Request::routeIs('admin.products.*')) active @endif">
@@ -325,7 +414,8 @@ class="nav-link @if (Request::routeIs('admin.products.*')) active @endif">
                                 <p>{{ __('Products') }}</p>
                             </a>
                         </li>
-
+                    @endcanany
+                    @canany(['admin.store.read','admin.store.write','admin.store.disable'])
                         <li class="nav-item">
                             <a href="{{ route('admin.store.index') }}"
                                class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
@@ -333,7 +423,8 @@ class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
                                 <p>{{ __('Store') }}</p>
                             </a>
                         </li>
-
+                    @endcanany
+                    @canany(["admin.voucher.read","admin.voucher.read"])
                         <li class="nav-item">
                             <a href="{{ route('admin.vouchers.index') }}"
                                class="nav-link @if (Request::routeIs('admin.vouchers.*')) active @endif">
@@ -341,7 +432,8 @@ class="nav-link @if (Request::routeIs('admin.vouchers.*')) active @endif">
                                 <p>{{ __('Vouchers') }}</p>
                             </a>
                         </li>
-
+                    @endcanany
+                    @canany(["admin.partners.read","admin.partners.read"])
                         <li class="nav-item">
                             <a href="{{ route('admin.partners.index') }}"
                                class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
@@ -349,28 +441,13 @@ class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
                                 <p>{{ __('Partners') }}</p>
                             </a>
                         </li>
+                    @endcanany
 
-                        {{-- <li class="nav-header">Pterodactyl</li> --}}
-
-                        {{-- <li class="nav-item"> --}}
-                        {{-- <a href="{{route('admin.nodes.index')}}" --}}
-                        {{-- class="nav-link @if (Request::routeIs('admin.nodes.*')) active @endif"> --}}
-                        {{-- <i class="nav-icon fas fa-sitemap"></i> --}}
-                        {{-- <p>Nodes</p> --}}
-                        {{-- </a> --}}
-                        {{-- </li> --}}
-
-                        {{-- <li class="nav-item"> --}}
-                        {{-- <a href="{{route('admin.nests.index')}}" --}}
-                        {{-- class="nav-link @if (Request::routeIs('admin.nests.*')) active @endif"> --}}
-                        {{-- <i class="nav-icon fas fa-th-large"></i> --}}
-                        {{-- <p>Nests</p> --}}
-                        {{-- </a> --}}
-                        {{-- </li> --}}
-
-
+                    @canany(["admin.useful_links.read","admin.legal.read"])
                         <li class="nav-header">{{ __('Other') }}</li>
+                    @endcanany
 
+                    @canany(["admin.useful_links.read","admin.useful_links.write"])
                         <li class="nav-item">
                             <a href="{{ route('admin.usefullinks.index') }}"
                                class="nav-link @if (Request::routeIs('admin.usefullinks.*')) active @endif">
@@ -378,7 +455,9 @@ class="nav-link @if (Request::routeIs('admin.usefullinks.*')) active @endif">
                                 <p>{{ __('Useful Links') }}</p>
                             </a>
                         </li>
+                    @endcanany
 
+                    @canany(["admin.legal.read","admin.legal.write"])
                         <li class="nav-item">
                             <a href="{{ route('admin.legal.index') }}"
                                class="nav-link @if (Request::routeIs('admin.legal.*')) active @endif">
@@ -386,9 +465,14 @@ class="nav-link @if (Request::routeIs('admin.legal.*')) active @endif">
                                 <p>{{ __('Legal Sites') }}</p>
                             </a>
                         </li>
+                    @endcanany
 
+
+                    @canany(["admin.payments.read","admin.logs.read"])
                         <li class="nav-header">{{ __('Logs') }}</li>
+                    @endcanany
 
+                    @can("admin.payments.read")
                         <li class="nav-item">
                             <a href="{{ route('admin.payments.index') }}"
                                class="nav-link @if (Request::routeIs('admin.payments.*')) active @endif">
@@ -399,7 +483,9 @@ class="badge badge-success right">{{ \App\Models\Payment::count() }}</span>
                                 </p>
                             </a>
                         </li>
+                    @endcan
 
+                    @can("admin.logs.read")
                         <li class="nav-item">
                             <a href="{{ route('admin.activitylogs.index') }}"
                                class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
@@ -407,7 +493,8 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
                                 <p>{{ __('Activity Logs') }}</p>
                             </a>
                         </li>
-                    @endif
+                    @endcan
+
 
                 </ul>
             </nav>
@@ -420,17 +507,19 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
 
     <div class="content-wrapper">
 
-        @if (!Auth::user()->hasVerifiedEmail())
+        <!--
+            @if (!Auth::user()->hasVerifiedEmail())
             @if (Auth::user()->created_at->diffInHours(now(), false) > 1)
                 <div class="alert alert-warning p-2 m-2">
                     <h5><i class="icon fas fa-exclamation-circle"></i> {{ __('Warning!') }}</h5>
-                    {{ __('You have not yet verified your email address') }} <a class="text-primary"
-                                                                                href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
-                    <br>
-                    {{ __('Please contact support If you didnt receive your verification email.') }}
+                        {{ __('You have not yet verified your email address') }} <a class="text-primary"
+                            href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
+                        <br>
+                        {{ __('Please contact support If you didnt receive your verification email.') }}
                 </div>
-            @endif
+@endif
         @endif
+        -->
 
         @yield('content')
 
@@ -441,21 +530,22 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
         <strong>Copyright &copy; 2021-{{ date('Y') }} <a
                 href="{{ url('/') }}">{{ env('APP_NAME', 'Laravel') }}</a>.</strong>
         All rights
-        reserved. Powered by <a href="https://CtrlPanel.gg">ControlPanel</a>. | Theme by <a href="https://2icecube.de/cpgg">2IceCube</a>
+        reserved. Powered by <a href="https://CtrlPanel.gg">CtrlPanel</a>. | Theme by <a href="https://2icecube.de/cpgg">2IceCube</a>
         @if (!str_contains(config('BRANCHNAME'), 'main') && !str_contains(config('BRANCHNAME'), 'unknown'))
             Version <b>{{ config('app')['version'] }} - {{ config('BRANCHNAME') }}</b>
         @endif
 
         {{-- Show imprint and privacy link --}}
         <div class="float-right d-none d-sm-inline-block">
-            @if (config('SETTINGS::SYSTEM:SHOW_IMPRINT') == "true")
+            @if ($website_settings->show_imprint)
                 <a target="_blank" href="{{ route('imprint') }}"><strong>{{ __('Imprint') }}</strong></a> |
             @endif
-            @if (config('SETTINGS::SYSTEM:SHOW_PRIVACY') == "true")
+            @if ($website_settings->show_privacy)
                 <a target="_blank" href="{{ route('privacy') }}"><strong>{{ __('Privacy') }}</strong></a>
             @endif
-            @if (config('SETTINGS::SYSTEM:SHOW_TOS') == "true")
-                | <a target="_blank" href="{{ route('tos') }}"><strong>{{ __('Terms of Service') }}</strong></a>
+            @if ($website_settings->show_tos)
+                | <a target="_blank"
+                     href="{{ route('tos') }}"><strong>{{ __('Terms of Service') }}</strong></a>
             @endif
         </div>
     </footer>
@@ -469,9 +559,9 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
 <!-- ./wrapper -->
 
 <!-- Scripts -->
-<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10.14.1/dist/sweetalert2.all.min.js"></script>
+<script src="{{ asset('plugins/sweetalert2/sweetalert2.all.min.js') }}"></script>
 
-<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script>
+<script src="{{ asset('plugins/datatables/jquery.dataTables.min.js') }}"></script>
 <!-- Summernote -->
 <script src="{{ asset('plugins/summernote/summernote-bs4.min.js') }}"></script>
 <!-- select2 -->

From 34287d00144310d64cfac765b171b2987a3a5efe Mon Sep 17 00:00:00 2001
From: Dennis <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 12:03:08 +0200
Subject: [PATCH 151/514] Update README.md

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 4e6591b4d..1bbc5152f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 ### Features
 
--   PayPal Integration
--   Stripe Integration
+-   PayPal, Stripe and Mollie Integration
+-   Hourly, Weekely, Monthly, Quarterly and Annual billing Cycles
 -   Referral System
 -   Partner System
 -   Ticket System

From fb6b2ba2efee36cf4575d72d083ace121ee39b93 Mon Sep 17 00:00:00 2001
From: Dennis <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 12:05:23 +0200
Subject: [PATCH 152/514] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1bbc5152f..c121ff78a 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@
 ![](https://img.shields.io/github/stars/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/forks/ctrlpanel-gg/panel) ![](https://img.shields.io/github/tag/ctrlpanel-gg/panel) [![Crowdin](https://badges.crowdin.com/project/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ctrlpanel-gg/panel) ![](https://img.shields.io/github/license/ctrlpanel-gg/panel) ![](https://img.shields.io/discord/787829714483019826)
 ## About
 
-CtrlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that credits users hourly for each server they have and suspends them if they run out of credits.
+CtrlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that charges users depending on the billing cycle you chose for each server they have and suspends them if they run out of credits.
 
 This dashboard offers an easy to use and free billing solution for all starting and experienced hosting providers. This dashboard has many customisation options and added discord Oauth verification to offer a solid link between your discord server and your dashboard. You can check our [Demo here](https://demo.CtrlPanel.gg "Demo").
 

From 9804149beb183ea8793b1e19f5f693f2cda2ecfd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 12:07:23 +0200
Subject: [PATCH 153/514] oom killer frontend

---
 themes/default/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index e700b15d6..dd417eac2 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -126,7 +126,7 @@ class="fas fa-info-circle"></i>
                                         <span>{{ $server->product->name }}
                                         </span>
                                         <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
+                                            data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>{{ __('OOM Killer') }}: {{ $server->product->oom_killer ? __("enabled") : __("disabled") }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
                                             class="fas fa-info-circle"></i>
                                     </div>
                                 </div>

From 88ae8774e0c36de11d83d2a106e8f4904f5f09f1 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 8 May 2023 12:12:16 +0200
Subject: [PATCH 154/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Add=20status=20to?=
 =?UTF-8?q?=20payments=20table?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/admin/payments/index.blade.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/themes/default/views/admin/payments/index.blade.php b/themes/default/views/admin/payments/index.blade.php
index cda9984cd..93ce751fa 100644
--- a/themes/default/views/admin/payments/index.blade.php
+++ b/themes/default/views/admin/payments/index.blade.php
@@ -47,6 +47,7 @@ class="btn btn-info">{{ __('Download all Invoices') }}</button></a>
                                 <th>{{ __('Total Price') }}</th>
                                 <th>{{ __('Payment ID') }}</th>
                                 <th>{{ __('Payment Method') }}</th>
+                                <th>{{ __('Status') }}</th>
                                 <th>{{ __('Created at') }}</th>
                                 <th></th>
                             </tr>
@@ -85,6 +86,7 @@ class="btn btn-info">{{ __('Download all Invoices') }}</button></a>
                     {data: 'total_price'},
                     {data: 'payment_id'},
                     {data: 'payment_method'},
+                    {data: 'status'},
                     {data: 'created_at', type: 'num', render: {_: 'display', sort: 'raw'}},
                     {data: 'actions' , sortable : false},
                 ],

From 98a894fd1eac2d0c6bd353fc14799a3827a31484 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 12:26:49 +0200
Subject: [PATCH 155/514] possible fix?

---
 database/settings/2023_02_04_181156_create_ticket_settings.php | 3 ++-
 database/settings/2023_05_07_195343_ticket_information.php     | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/database/settings/2023_02_04_181156_create_ticket_settings.php b/database/settings/2023_02_04_181156_create_ticket_settings.php
index 701ca14ae..4637cbe3c 100644
--- a/database/settings/2023_02_04_181156_create_ticket_settings.php
+++ b/database/settings/2023_02_04_181156_create_ticket_settings.php
@@ -10,7 +10,8 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('ticket.enabled', $table_exists ? $this->getOldValue('SETTINGS::TICKET:ENABLED') : 'all');
+        $this->migrator->add('ticket.enabled', $table_exists ? $this->getOldValue('SETTINGS::TICKET:ENABLED') : 'true');
+        $this->migrator->add('ticket.notify', $table_exists ? $this->getOldValue('SETTINGS::TICKET:NOTIFY') : 'all');
     }
 
     public function down(): void
diff --git a/database/settings/2023_05_07_195343_ticket_information.php b/database/settings/2023_05_07_195343_ticket_information.php
index a4d89f25c..21d9aa67b 100644
--- a/database/settings/2023_05_07_195343_ticket_information.php
+++ b/database/settings/2023_05_07_195343_ticket_information.php
@@ -6,6 +6,7 @@
 {
     public function up(): void
     {
+        $this->migrator->delete('ticket.notify');
         $this->migrator->add('ticket.information',  "Can't start your server? Need an additional port? Do you have any other questions? Let us know by opening a ticket.");
     }
 };

From 78dfe881d28dc2c02529662e5b36d4700d8803ab Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 12:35:52 +0200
Subject: [PATCH 156/514] Fix migration

---
 .../settings/2023_02_04_181156_create_ticket_settings.php    | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/database/settings/2023_02_04_181156_create_ticket_settings.php b/database/settings/2023_02_04_181156_create_ticket_settings.php
index 4637cbe3c..1e71ad3a8 100644
--- a/database/settings/2023_02_04_181156_create_ticket_settings.php
+++ b/database/settings/2023_02_04_181156_create_ticket_settings.php
@@ -58,11 +58,16 @@ public function getOldValue(string $key)
         $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
 
         // Handle the old values to return without it being a string in all cases.
+
+        if (is_null($old_value)) {
+            return '';
+        }
         if ($old_value->type === "string" || $old_value->type === "text") {
             if (is_null($old_value->value)) {
                 return '';
             }
 
+
             // Some values have the type string, but their values are boolean.
             if ($old_value->value === "false" || $old_value->value === "true") {
                 return filter_var($old_value->value, FILTER_VALIDATE_BOOL);

From 29b5b39d1773a42010befad70141d3a2c16efa08 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 13:53:21 +0200
Subject: [PATCH 157/514] fix general settings

---
 app/Settings/GeneralSettings.php                   | 14 +++++++-------
 .../default/views/admin/settings/index.blade.php   |  5 +++--
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 8aa91e222..06a4819ee 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -8,13 +8,13 @@ class GeneralSettings extends Settings
 {
     public bool $store_enabled;
     public string $credits_display_name;
-    public bool $recaptcha_enabled;
-    public string $recaptcha_site_key;
-    public string $recaptcha_secret_key;
-    public string $phpmyadmin_url;
-    public bool $alert_enabled;
+    public ?bool $recaptcha_enabled;
+    public ?string $recaptcha_site_key;
+    public ?string $recaptcha_secret_key;
+    public ?string $phpmyadmin_url;
+    public ?bool $alert_enabled;
     public string $alert_type;
-    public string $alert_message;
+    public ?string $alert_message;
     public string $theme;
 
     //public int $initial_user_role; wait for Roles & Permissions PR.
@@ -41,7 +41,7 @@ public static function getValidations()
             'phpmyadmin_url' => 'nullable|string',
             'alert_enabled' => 'nullable|boolean',
             'alert_type' => 'required|in:primary,secondary,success,danger,warning,info',
-            'alert_message' => 'required|string',
+            'alert_message' => 'nullable|string',
             'theme' => 'required|in:default,BlueInfinity' // TODO: themes should be made/loaded dynamically
         ];
     }
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index db4344b6e..28615dbee 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -121,10 +121,11 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                                                     @case($value['type'] == 'select')
                                                                         <select id="{{ $key }}"
                                                                             class="custom-select w-100" name="{{ $key }}">
-                                                                            @foreach ($value['options'] as $option)
+
+                                                                            @foreach ($value['options'] as $option=>$display)
                                                                                 <option value="{{ $option }}"
                                                                                     {{ $value['value'] == $option ? 'selected' : '' }}>
-                                                                                    {{ __($option) }}
+                                                                                    {{ __($display) }}
                                                                                 </option>
                                                                             @endforeach
                                                                         </select>

From 6894e2db8435992030dd0407f2e0bbfa3f171515 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 14:01:02 +0200
Subject: [PATCH 158/514] ReImplement ThemeSwitcher

---
 app/Providers/AppServiceProvider.php | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 8b82efad9..fb6e8f9ce 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -4,6 +4,7 @@
 
 use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
 use App\Models\UsefulLink;
+use App\Settings\GeneralSettings;
 use App\Settings\MailSettings;
 use Exception;
 use Illuminate\Pagination\Paginator;
@@ -12,6 +13,7 @@
 use Illuminate\Support\Facades\URL;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\ServiceProvider;
+use Qirolab\Theme\Theme;
 
 
 class AppServiceProvider extends ServiceProvider
@@ -87,6 +89,17 @@ public function boot()
             Log::error("Couldnt find useful_links. Probably the installation is not completet. " . $e);
         }
 
+        $generalSettings = $this->app->make(GeneralSettings::class);
+        if (!file_exists(base_path('themes') . "/" . $generalSettings->theme)) {
+            $generalSettings->theme = "default";
+        }
+
+        if ($generalSettings->theme && $generalSettings->theme !== config('theme.active')) {
+            Theme::set($generalSettings->theme, "default");
+        } else {
+            Theme::set("default", "default");
+        }
+
 
         $settings = $this->app->make(MailSettings::class);
         $settings->setConfig();

From 3822c123ba2a8ae4204b8103029164f0005e38f8 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 14:20:42 +0200
Subject: [PATCH 159/514] Fix some Settings

---
 app/Settings/GeneralSettings.php  | 2 +-
 app/Settings/ReferralSettings.php | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 06a4819ee..5c4d14113 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -114,7 +114,7 @@ public static function getOptionInputData()
                 'description' => 'The type of alert to display.'
             ],
             'alert_message' => [
-                'type' => 'string',
+                'type' => 'textarea',
                 'label' => 'Alert Message',
                 'description' => 'The message to display in the alert.'
             ],
diff --git a/app/Settings/ReferralSettings.php b/app/Settings/ReferralSettings.php
index 47d086465..28e1a9edc 100644
--- a/app/Settings/ReferralSettings.php
+++ b/app/Settings/ReferralSettings.php
@@ -24,11 +24,10 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'allowed' => 'required|in:Everyone,Clients',
             'always_give_commission' => 'nullable|boolean',
             'enabled' => 'nullable|boolean',
             'reward' => 'nullable|numeric',
-            'mode' => 'required|in:Commission,Sign-Up,Both',
+            'mode' => 'required|in:comission,sign-up,both',
             'percentage' => 'nullable|numeric',
         ];
     }

From 9dbd812fc2ee677e82889bddf84c86c0b2651d78 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 14:42:46 +0200
Subject: [PATCH 160/514] Fix Settings bool -> String

---
 app/Settings/GeneralSettings.php  | 10 +++++-----
 app/Settings/InvoiceSettings.php  |  2 +-
 app/Settings/LocaleSettings.php   |  4 ++--
 app/Settings/MailSettings.php     |  2 +-
 app/Settings/ReferralSettings.php |  4 ++--
 app/Settings/ServerSettings.php   |  6 +++---
 app/Settings/TicketSettings.php   |  2 +-
 app/Settings/UserSettings.php     |  8 ++++----
 app/Settings/WebsiteSettings.php  | 12 ++++++------
 9 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 5c4d14113..23c0c0f76 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -8,11 +8,11 @@ class GeneralSettings extends Settings
 {
     public bool $store_enabled;
     public string $credits_display_name;
-    public ?bool $recaptcha_enabled;
+    public bool $recaptcha_enabled;
     public ?string $recaptcha_site_key;
     public ?string $recaptcha_secret_key;
     public ?string $phpmyadmin_url;
-    public ?bool $alert_enabled;
+    public bool $alert_enabled;
     public string $alert_type;
     public ?string $alert_message;
     public string $theme;
@@ -33,13 +33,13 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'store_enabled' => 'boolean',
+            'store_enabled' => 'nullable|string',
             'credits_display_name' => 'required|string',
-            'recaptcha_enabled' => 'nullable|boolean',
+            'recaptcha_enabled' => 'nullable|string',
             'recaptcha_site_key' => 'nullable|string',
             'recaptcha_secret_key' => 'nullable|string',
             'phpmyadmin_url' => 'nullable|string',
-            'alert_enabled' => 'nullable|boolean',
+            'alert_enabled' => 'nullable|string',
             'alert_type' => 'required|in:primary,secondary,success,danger,warning,info',
             'alert_message' => 'nullable|string',
             'theme' => 'required|in:default,BlueInfinity' // TODO: themes should be made/loaded dynamically
diff --git a/app/Settings/InvoiceSettings.php b/app/Settings/InvoiceSettings.php
index 46dce9c54..c7b0068bf 100644
--- a/app/Settings/InvoiceSettings.php
+++ b/app/Settings/InvoiceSettings.php
@@ -33,7 +33,7 @@ public static function getValidations()
             'company_phone' => 'nullable|string',
             'company_vat' => 'nullable|string',
             'company_website' => 'nullable|string',
-            'enabled' => 'nullable|boolean',
+            'enabled' => 'nullable|string',
             'prefix' => 'nullable|string',
         ];
     }
diff --git a/app/Settings/LocaleSettings.php b/app/Settings/LocaleSettings.php
index 7802f499b..61934bc17 100644
--- a/app/Settings/LocaleSettings.php
+++ b/app/Settings/LocaleSettings.php
@@ -25,10 +25,10 @@ public static function getValidations()
     {
         return [
             'available' => 'nullable|array',
-            'clients_can_change' => 'nullable|boolean',
+            'clients_can_change' => 'nullable|string',
             'datatables' => 'nullable|string',
             'default' => 'required|in:' . implode(',', config('app.available_locales')),
-            'dynamic' => 'nullable|boolean',
+            'dynamic' => 'nullable|string',
         ];
     }
 
diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php
index cd70a7fa4..8b37f632f 100644
--- a/app/Settings/MailSettings.php
+++ b/app/Settings/MailSettings.php
@@ -52,7 +52,7 @@ public static function getValidations()
             'mail_from_address' => 'nullable|string',
             'mail_from_name' => 'nullable|string',
             'mail_mailer' => 'nullable|string',
-            'mail_enabled' => 'nullable|boolean',
+            'mail_enabled' => 'nullable|string',
         ];
     }
 
diff --git a/app/Settings/ReferralSettings.php b/app/Settings/ReferralSettings.php
index 28e1a9edc..f56b71883 100644
--- a/app/Settings/ReferralSettings.php
+++ b/app/Settings/ReferralSettings.php
@@ -24,8 +24,8 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'always_give_commission' => 'nullable|boolean',
-            'enabled' => 'nullable|boolean',
+            'always_give_commission' => 'nullable|string',
+            'enabled' => 'nullable|string',
             'reward' => 'nullable|numeric',
             'mode' => 'required|in:comission,sign-up,both',
             'percentage' => 'nullable|numeric',
diff --git a/app/Settings/ServerSettings.php b/app/Settings/ServerSettings.php
index ee43e6673..f56418765 100644
--- a/app/Settings/ServerSettings.php
+++ b/app/Settings/ServerSettings.php
@@ -24,9 +24,9 @@ public static function getValidations()
     {
         return [
             'allocation_limit' => 'required|integer|min:0',
-            'creation_enabled' => 'nullable|boolean',
-            'enable_upgrade' => 'nullable|boolean',
-            'charge_first_hour' => 'nullable|boolean',
+            'creation_enabled' => 'nullable|string',
+            'enable_upgrade' => 'nullable|string',
+            'charge_first_hour' => 'nullable|string',
         ];
     }
 
diff --git a/app/Settings/TicketSettings.php b/app/Settings/TicketSettings.php
index cd621b173..89eec7270 100644
--- a/app/Settings/TicketSettings.php
+++ b/app/Settings/TicketSettings.php
@@ -21,7 +21,7 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'enabled' => 'nullable|boolean',
+            'enabled' => 'nullable|string',
             'information' => 'nullable|string',
         ];
     }
diff --git a/app/Settings/UserSettings.php b/app/Settings/UserSettings.php
index ec34f678e..5c1b65dba 100644
--- a/app/Settings/UserSettings.php
+++ b/app/Settings/UserSettings.php
@@ -33,16 +33,16 @@ public static function getValidations()
         return [
             'credits_reward_after_verify_discord' => 'required|numeric',
             'credits_reward_after_verify_email' => 'required|numeric',
-            'force_discord_verification' => 'nullable|boolean',
-            'force_email_verification' => 'nullable|boolean',
+            'force_discord_verification' => 'nullable|string',
+            'force_email_verification' => 'nullable|string',
             'initial_credits' => 'required|numeric',
             'initial_server_limit' => 'required|numeric',
             'min_credits_to_make_server' => 'required|numeric',
             'server_limit_after_irl_purchase' => 'required|numeric',
             'server_limit_after_verify_discord' => 'required|numeric',
             'server_limit_after_verify_email' => 'required|numeric',
-            'register_ip_check' => 'nullable|boolean',
-            'creation_enabled' => 'nullable|boolean',
+            'register_ip_check' => 'nullable|string',
+            'creation_enabled' => 'nullable|string',
         ];
     }
 
diff --git a/app/Settings/WebsiteSettings.php b/app/Settings/WebsiteSettings.php
index e557fd937..e6607c210 100644
--- a/app/Settings/WebsiteSettings.php
+++ b/app/Settings/WebsiteSettings.php
@@ -31,13 +31,13 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'motd_enabled' => 'nullable|boolean',
+            'motd_enabled' => 'nullable|string',
             'motd_message' => 'nullable|string',
-            'show_imprint' => 'nullable|boolean',
-            'show_privacy' => 'nullable|boolean',
-            'show_tos' => 'nullable|boolean',
-            'useful_links_enabled' => 'nullable|boolean',
-            'enable_login_logo' => 'nullable|boolean',
+            'show_imprint' => 'nullable|string',
+            'show_privacy' => 'nullable|string',
+            'show_tos' => 'nullable|string',
+            'useful_links_enabled' => 'nullable|string',
+            'enable_login_logo' => 'nullable|string',
             'seo_title' => 'nullable|string',
             'seo_description' => 'nullable|string',
         ];

From 259a08b3bab75e687d5ff915f3f859c93267fc01 Mon Sep 17 00:00:00 2001
From: Dennis <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 14:48:07 +0200
Subject: [PATCH 161/514] fix div

---
 themes/default/views/home.blade.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/themes/default/views/home.blade.php b/themes/default/views/home.blade.php
index 8993972c7..b3827bee1 100644
--- a/themes/default/views/home.blade.php
+++ b/themes/default/views/home.blade.php
@@ -150,9 +150,8 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                         </div>
                         <!-- /.card-body -->
                     </div>
-
+                @endif
             </div>
-            @endif
 
             <div class="col-md-6">
                 <div class="card card-default">

From 166dccd3de5f9cd81e08252702b992b7ee0a6c92 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 21:16:06 +0200
Subject: [PATCH 162/514] Update web.php

---
 routes/web.php | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/routes/web.php b/routes/web.php
index 8de0863e3..425c56135 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -76,9 +76,11 @@
     Route::patch('/servers/cancel/{server}', [ServerController::class, 'cancel'])->name('servers.cancel');
     Route::resource('servers', ServerController::class);
 
-    $serverSettings = app(App\Settings\ServerSettings::class);
-    if ($serverSettings->enable_upgrade) {
-        Route::post('servers/{server}/upgrade', [ServerController::class, 'upgrade'])->name('servers.upgrade');
+    if (config('app.key')) {
+        $serverSettings = app(App\Settings\ServerSettings::class);
+        if ($serverSettings->enable_upgrade) {
+            Route::post('servers/{server}/upgrade', [ServerController::class, 'upgrade'])->name('servers.upgrade');
+        }
     }
 
     Route::post('profile/selfdestruct', [ProfileController::class, 'selfDestroyUser'])->name('profile.selfDestroyUser');

From 6f74a7379f2fbfa0623688a6cc82f2b00ca75537 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 23:00:29 +0200
Subject: [PATCH 163/514] Show referredBy on User

---
 app/Models/User.php                           | 14 +++++++++++++
 .../default/views/admin/users/show.blade.php  | 21 ++++++++++++++-----
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/app/Models/User.php b/app/Models/User.php
index c72e693c4..da4a3a7f9 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -15,6 +15,7 @@
 use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
+use Illuminate\Support\Facades\DB;
 use Spatie\Activitylog\LogOptions;
 use Spatie\Activitylog\Traits\CausesActivity;
 use Spatie\Activitylog\Traits\LogsActivity;
@@ -97,6 +98,8 @@ public function __construct()
 
         $ptero_settings = new PterodactylSettings();
         $this->pterodactyl = new PterodactylClient($ptero_settings);
+
+
     }
 
     public static function boot()
@@ -285,6 +288,17 @@ public function reVerifyEmail()
         ])->save();
     }
 
+    public function referredBy(){
+        $referee = DB::table('user_referrals')->where("registered_user_id",$this->id)->first();
+
+        if($referee){
+            $referee = User::where("id",$referee->referral_id)->firstOrFail();
+            return $referee;
+        }
+        return Null;
+
+    }
+
     public function getActivitylogOptions(): LogOptions
     {
         return LogOptions::defaults()
diff --git a/themes/default/views/admin/users/show.blade.php b/themes/default/views/admin/users/show.blade.php
index 3ab0d62ee..5656c307b 100644
--- a/themes/default/views/admin/users/show.blade.php
+++ b/themes/default/views/admin/users/show.blade.php
@@ -173,6 +173,20 @@
                             </div>
                         </div>
 
+
+
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{ __('IP') }}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->ip }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
                         <div class="col-lg-6">
                             <div class="row">
                                 <div class="col-lg-4">
@@ -185,21 +199,18 @@
                                 </div>
                             </div>
                         </div>
-
-
                         <div class="col-lg-6">
                             <div class="row">
                                 <div class="col-lg-4">
-                                    <label>{{ __('IP') }}</label>
+                                    <label>{{ __('Referred by') }}</label>
                                 </div>
                                 <div class="col-lg-8">
                                     <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                        {{ $user->ip }}
+                                        {{ $user->referredBy() != Null ? $user->referredBy()->name : "None" }}
                                     </span>
                                 </div>
                             </div>
                         </div>
-
                         <div class="col-lg-6">
                             <div class="row">
                                 <div class="col-lg-4">

From f53aa0e8b0caf656a35821373da94d4a1661004f Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 8 May 2023 23:13:50 +0200
Subject: [PATCH 164/514] Fix Ptero UserID

---
 app/Http/Controllers/Auth/RegisterController.php | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php
index 9f1e8019b..566d86fd5 100644
--- a/app/Http/Controllers/Auth/RegisterController.php
+++ b/app/Http/Controllers/Auth/RegisterController.php
@@ -142,7 +142,7 @@ protected function create(array $data)
         $user->syncRoles(4);
 
         $response = $this->pterodactyl->application->post('/application/users', [
-            'external_id' => $user->pterodactyl_id,
+            'external_id' => null,
             'username' => $user->name,
             'email' => $user->email,
             'first_name' => $user->name,
@@ -151,6 +151,14 @@ protected function create(array $data)
             'root_admin' => false,
             'language' => 'en',
         ]);
+        
+        $user->update([
+            'pterodactyl_id' => $response->json()['attributes']['id'],
+        ]);
+
+
+
+
 
         if ($response->failed()) {
             $user->delete();

From 38db0a6ee0a028397c91c7842bcac6245dff37c6 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 9 May 2023 18:04:11 +0200
Subject: [PATCH 165/514] Fix Notifications

---
 app/Models/User.php                        |  5 +++--
 app/Notifications/ReferralNotification.php | 13 +++++++++++--
 app/Notifications/WelcomeMessage.php       |  5 ++++-
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/app/Models/User.php b/app/Models/User.php
index da4a3a7f9..6d14f585a 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -106,8 +106,8 @@ public static function boot()
     {
         parent::boot();
 
-        static::created(function (User $user, GeneralSettings $general_settings, UserSettings $user_settings) {
-            $user->notify(new WelcomeMessage($user, $general_settings, $user_settings));
+        static::created(function (User $user) {
+            $user->notify(new WelcomeMessage($user));
         });
 
         static::deleting(function (User $user) {
@@ -276,6 +276,7 @@ public function getVerifiedStatus()
 
     public function verifyEmail()
     {
+
         $this->forceFill([
             'email_verified_at' => now(),
         ])->save();
diff --git a/app/Notifications/ReferralNotification.php b/app/Notifications/ReferralNotification.php
index a1eaff0c8..f8acbcf52 100644
--- a/app/Notifications/ReferralNotification.php
+++ b/app/Notifications/ReferralNotification.php
@@ -19,6 +19,10 @@ class ReferralNotification extends Notification
 
     private $ref_user;
 
+    private $reward;
+
+    private $credits_display_name;
+
     /**
      * Create a new notification instance.
      *
@@ -26,6 +30,11 @@ class ReferralNotification extends Notification
      */
     public function __construct(int $user, int $ref_user)
     {
+        $general_settings= new GeneralSettings();
+        $referral_settings = new ReferralSettings();
+
+        $this->credits_display_name = $general_settings->credits_display_name;
+        $this->reward = $referral_settings->reward;
         $this->user = User::findOrFail($user);
         $this->ref_user = User::findOrFail($ref_user);
     }
@@ -47,12 +56,12 @@ public function via($notifiable)
      * @param  mixed  $notifiable
      * @return array
      */
-    public function toArray($notifiable, GeneralSettings $general_settings, ReferralSettings $referral_settings)
+    public function toArray($notifiable)
     {
         return [
             'title' => __('Someone registered using your Code!'),
             'content' => '
-                <p>You received '. $referral_settings->reward . ' ' . $general_settings->credits_display_name . '</p>
+                <p>You received '. $this->reward . ' ' . $this->credits_display_name . '</p>
                 <p>because ' . $this->ref_user->name . ' registered with your Referral-Code!</p>
                 <p>Thank you very much for supporting us!.</p>
                 <p>'.config('app.name', 'Laravel').'</p>
diff --git a/app/Notifications/WelcomeMessage.php b/app/Notifications/WelcomeMessage.php
index ac33e1c1b..7bef9f848 100644
--- a/app/Notifications/WelcomeMessage.php
+++ b/app/Notifications/WelcomeMessage.php
@@ -33,8 +33,11 @@ class WelcomeMessage extends Notification implements ShouldQueue
      *
      * @param  User  $user
      */
-    public function __construct(User $user, GeneralSettings $general_settings, UserSettings $user_settings)
+    public function __construct(User $user)
     {
+        $general_settings= new GeneralSettings();
+        $user_settings = new UserSettings();
+
         $this->user = $user;
         $this->credits_display_name = $general_settings->credits_display_name;
         $this->credits_reward_after_verify_discord = $user_settings->credits_reward_after_verify_discord;

From b58040c45772b55078098d9ab4a78d59911c2fd3 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 9 May 2023 18:04:11 +0200
Subject: [PATCH 166/514] Fix Notifications

---
 app/Models/User.php                        |  5 +++--
 app/Notifications/ReferralNotification.php | 13 +++++++++++--
 app/Notifications/WelcomeMessage.php       |  5 ++++-
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/app/Models/User.php b/app/Models/User.php
index da4a3a7f9..6d14f585a 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -106,8 +106,8 @@ public static function boot()
     {
         parent::boot();
 
-        static::created(function (User $user, GeneralSettings $general_settings, UserSettings $user_settings) {
-            $user->notify(new WelcomeMessage($user, $general_settings, $user_settings));
+        static::created(function (User $user) {
+            $user->notify(new WelcomeMessage($user));
         });
 
         static::deleting(function (User $user) {
@@ -276,6 +276,7 @@ public function getVerifiedStatus()
 
     public function verifyEmail()
     {
+
         $this->forceFill([
             'email_verified_at' => now(),
         ])->save();
diff --git a/app/Notifications/ReferralNotification.php b/app/Notifications/ReferralNotification.php
index a1eaff0c8..f8acbcf52 100644
--- a/app/Notifications/ReferralNotification.php
+++ b/app/Notifications/ReferralNotification.php
@@ -19,6 +19,10 @@ class ReferralNotification extends Notification
 
     private $ref_user;
 
+    private $reward;
+
+    private $credits_display_name;
+
     /**
      * Create a new notification instance.
      *
@@ -26,6 +30,11 @@ class ReferralNotification extends Notification
      */
     public function __construct(int $user, int $ref_user)
     {
+        $general_settings= new GeneralSettings();
+        $referral_settings = new ReferralSettings();
+
+        $this->credits_display_name = $general_settings->credits_display_name;
+        $this->reward = $referral_settings->reward;
         $this->user = User::findOrFail($user);
         $this->ref_user = User::findOrFail($ref_user);
     }
@@ -47,12 +56,12 @@ public function via($notifiable)
      * @param  mixed  $notifiable
      * @return array
      */
-    public function toArray($notifiable, GeneralSettings $general_settings, ReferralSettings $referral_settings)
+    public function toArray($notifiable)
     {
         return [
             'title' => __('Someone registered using your Code!'),
             'content' => '
-                <p>You received '. $referral_settings->reward . ' ' . $general_settings->credits_display_name . '</p>
+                <p>You received '. $this->reward . ' ' . $this->credits_display_name . '</p>
                 <p>because ' . $this->ref_user->name . ' registered with your Referral-Code!</p>
                 <p>Thank you very much for supporting us!.</p>
                 <p>'.config('app.name', 'Laravel').'</p>
diff --git a/app/Notifications/WelcomeMessage.php b/app/Notifications/WelcomeMessage.php
index ac33e1c1b..7bef9f848 100644
--- a/app/Notifications/WelcomeMessage.php
+++ b/app/Notifications/WelcomeMessage.php
@@ -33,8 +33,11 @@ class WelcomeMessage extends Notification implements ShouldQueue
      *
      * @param  User  $user
      */
-    public function __construct(User $user, GeneralSettings $general_settings, UserSettings $user_settings)
+    public function __construct(User $user)
     {
+        $general_settings= new GeneralSettings();
+        $user_settings = new UserSettings();
+
         $this->user = $user;
         $this->credits_display_name = $general_settings->credits_display_name;
         $this->credits_reward_after_verify_discord = $user_settings->credits_reward_after_verify_discord;

From 5cff1e54615f1e88870f7a7cbcba4a59e2614f8b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 11 May 2023 09:32:13 +0200
Subject: [PATCH 167/514] Re-Implement Image uploading

---
 .../Controllers/Admin/SettingsController.php  | 21 ++++++++
 routes/web.php                                |  7 ++-
 .../views/admin/settings/index.blade.php      | 54 +++++++++++++++++++
 3 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 7d1657f1d..47cc4207d 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -138,4 +138,25 @@ public function update(Request $request)
 
         return Redirect::to('admin/settings' . '#' . $category)->with('success', 'Settings updated successfully.');
     }
+
+    public function updateIcons(Request $request)
+    {
+        $request->validate([
+            'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
+            'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
+            'favicon' => 'nullable|max:10000|mimes:ico',
+        ]);
+
+        if ($request->hasFile('icon')) {
+            $request->file('icon')->storeAs('public', 'icon.png');
+        }
+        if ($request->hasFile('logo')) {
+            $request->file('logo')->storeAs('public', 'logo.png');
+        }
+        if ($request->hasFile('favicon')) {
+            $request->file('favicon')->storeAs('public', 'favicon.ico');
+        }
+
+        return Redirect::to('admin/settings')->with('success', 'Icons updated successfully.');
+    }
 }
diff --git a/routes/web.php b/routes/web.php
index 425c56135..5e09c048b 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -169,13 +169,12 @@
         Route::get('payments', [PaymentController::class, 'index'])->name('payments.index');
 
         //settings
-        Route::get('settings/datatable', [SettingsController::class, 'datatable'])->name('settings.datatable');
-        Route::patch('settings/updatevalue', [SettingsController::class, 'updatevalue'])->name('settings.updatevalue');
-        Route::get('settings/checkPteroClientkey', [System::class, 'checkPteroClientkey'])->name('settings.checkPteroClientkey');
-        Route::redirect('settings#system', 'system')->name('settings.system');
+
 
         Route::get('settings', [SettingsController::class, 'index'])->name('settings.index');
         Route::post('settings', [SettingsController::class, 'update'])->name('settings.update');
+        Route::post('settings/icons', [SettingsController::class, 'updateIcons'])->name('settings.updateIcons');
+
 
         //invoices
         Route::get('invoices/download-invoices', [InvoiceController::class, 'downloadAllInvoices'])->name('invoices.downloadAllInvoices');
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 28615dbee..f3438dd2b 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -44,6 +44,17 @@
                             <nav class="mt-1">
                                 <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                     data-accordion="false">
+                                    <li class="nav-item border-bottom-0">
+                                        <a href="#icons"
+                                           class="nav-link" data-toggle="pill"
+                                           role="tab">
+                                            <i
+                                                class="nav-icon fas fa-image"></i>
+                                            <p>
+                                                {{ __("Images / Icons") }}
+                                            </p>
+                                        </a>
+                                    </li>
                                     @foreach ($settings as $category => $options)
                                         @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
                                         <li class="nav-item border-bottom-0">
@@ -66,6 +77,48 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                         <!-- Content in $settings -->
                         <div class="col-10 p-0">
                             <div class="tab-content ml-3" style="width: 100%;">
+                                <div container class="tab-pane fade container"
+                                     id="icons" role="tabpanel">
+
+                                    <form method="POST" enctype="multipart/form-data" class="mb-3"
+                                          action="{{ route('admin.settings.updateIcons') }}">
+                                        @csrf
+                                        @method('POST')
+                                        <div class="row">
+                                                <div class="card ml-5" style="width: 18rem;">
+                                                    <span class="h3 text-center">{{__("FavIcon")}} </span>
+                                                    <div class="card-body">
+
+                                                    </div>
+                                                    <input type="file" accept="image/x-icon" class="form-control" name="favicon"
+                                                           id="favicon">
+                                                </div>
+
+                                            <div class="card ml-5" style="width: 18rem;">
+                                                <span class="h3 text-center">{{__("Icon")}} </span>
+                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <div class="card-body">
+
+                                                </div>
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                       name="icon" id="icon">
+                                            </div>
+
+                                            <div class="card ml-5" style="width: 18rem;">
+                                                <span class="h3 text-center">{{__("Login-page Logo")}} </span>
+                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <div class="card-body">
+
+                                                </div>
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                       name="logo" id="logo">
+                                            </div>
+                                        </div>
+                                        <div class="row">
+                                            <button class="btn btn-primary ml-3 mt-3">{{ __('Save') }}</button>
+                                        </div>
+                                    </form>
+                                </div>
                                 @foreach ($settings as $category => $options)
                                     @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
                                     <div container class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
@@ -208,6 +261,7 @@ class="btn btn-secondary float-right ml-2">Reset</button>
                     </div>
                 </div>
             </div>
+            </div>
         </div>
 
 

From a1d302701a545cd3efbcbc091215d24b1d42fa7d Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 11 May 2023 11:06:30 +0200
Subject: [PATCH 168/514] Collapseable extension settings

---
 .../views/admin/settings/index.blade.php      | 310 ++++++++++--------
 1 file changed, 181 insertions(+), 129 deletions(-)

diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index f3438dd2b..3c396a8ce 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -12,7 +12,8 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a></li>
+                                                       href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a>
+                        </li>
                     </ol>
                 </div>
             </div>
@@ -24,7 +25,9 @@
             <h4>{{ __('The installer is not locked!') }}</h4>
             <p>{{ __('please create a file called "install.lock" in your dashboard Root directory. Otherwise no settings will be loaded!') }}
             </p>
-            <a href="/install?step=7"><button class="btn btn-outline-danger">{{ __('or click here') }}</button></a>
+            <a href="/install?step=7">
+                <button class="btn btn-outline-danger">{{ __('or click here') }}</button>
+            </a>
 
         </div>
     @endif
@@ -56,21 +59,54 @@ class="nav-icon fas fa-image"></i>
                                         </a>
                                     </li>
                                     @foreach ($settings as $category => $options)
-                                        @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
-                                        <li class="nav-item border-bottom-0">
-                                            <a href="#{{ $category }}"
-                                                class="nav-link {{ $loop->first ? 'active' : '' }}" data-toggle="pill"
-                                                role="tab">
-                                                <i
-                                                    class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
-                                                <p>
-                                                    {{ $category }}
-                                                </p>
-                                            </a>
-                                        </li>
-                                        @endcanany
+                                        @if(!str_contains($options['settings_class'],"Extension"))
+                                            @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
+                                                <li class="nav-item border-bottom-0">
+                                                    <a href="#{{ $category }}"
+                                                       class="nav-link {{ $loop->first ? 'active' : '' }}"
+                                                       data-toggle="pill"
+                                                       role="tab">
+                                                        <i
+                                                            class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
+                                                        <p>
+                                                            {{ $category }}
+                                                        </p>
+                                                    </a>
+                                                </li>
+                                            @endcanany
+                                        @endif
                                     @endforeach
                                 </ul>
+                                    <i class="fa-solid fa-up-right-from-square"></i>
+                                    <button class="btn btn-outline-secondary" type="button" data-toggle="collapse"
+                                            data-target="#collapseExtensions" aria-expanded="false"
+                                            aria-controls="collapseExample">
+                                        {{__("Extension Settings")}}
+                                    </button>
+                                    </p>
+                                    <div class="collapse" id="collapseExtensions">
+                                        <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
+                                            data-accordion="false">
+                                        @foreach ($settings as $category => $options)
+                                            @if(str_contains($options['settings_class'],"Extension"))
+
+                                                @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
+                                                        <li class="nav-item border-bottom-0">
+                                                            <a href="#{{ $category }}"
+                                                               class="nav-link"
+                                                               data-toggle="pill"
+                                                               role="tab">
+                                                                <i class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
+                                                                <p>
+                                                                    {{ $category }}
+                                                                </p>
+                                                            </a>
+                                                        </li>
+                                                @endcanany
+                                            @endif
+                                        @endforeach
+                                    </div>
+                                </ul>
                             </nav>
                         </div>
                         <!-- /.sidebar-menu -->
@@ -85,32 +121,41 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                         @csrf
                                         @method('POST')
                                         <div class="row">
-                                                <div class="card ml-5" style="width: 18rem;">
-                                                    <span class="h3 text-center">{{__("FavIcon")}} </span>
-                                                    <div class="card-body">
+                                            <div class="card ml-5" style="width: 18rem;">
+                                                <span class="h3 text-center">{{__("FavIcon")}} </span>
+                                                <div class="card-body">
 
-                                                    </div>
-                                                    <input type="file" accept="image/x-icon" class="form-control" name="favicon"
-                                                           id="favicon">
                                                 </div>
+                                                <input type="file" accept="image/x-icon" class="form-control"
+                                                       name="favicon"
+                                                       id="favicon">
+                                            </div>
 
                                             <div class="card ml-5" style="width: 18rem;">
                                                 <span class="h3 text-center">{{__("Icon")}} </span>
-                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <img
+                                                    src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
+                                                    style="width:5vw;display: block; margin-left: auto;margin-right: auto"
+                                                    class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
-                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg"
+                                                       class="form-control"
                                                        name="icon" id="icon">
                                             </div>
 
                                             <div class="card ml-5" style="width: 18rem;">
                                                 <span class="h3 text-center">{{__("Login-page Logo")}} </span>
-                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <img
+                                                    src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
+                                                    style="width:5vw;display: block; margin-left: auto;margin-right: auto"
+                                                    class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
-                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg"
+                                                       class="form-control"
                                                        name="logo" id="logo">
                                             </div>
                                         </div>
@@ -121,104 +166,110 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                 </div>
                                 @foreach ($settings as $category => $options)
                                     @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
-                                    <div container class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
-                                        id="{{ $category }}" role="tabpanel">
-
-                                        <form action="{{ route('admin.settings.update') }}" method="POST">
-                                            @csrf
-                                            @method('POST')
-                                            <input type="hidden" name="settings_class"
-                                                value="{{ $options['settings_class'] }}">
-                                            <input type="hidden" name="category" value="{{ $category }}">
-
-                                            @foreach ($options as $key => $value)
-                                                @if ($key == 'category_icon' || $key == 'settings_class')
-                                                    @continue
-                                                @endif
-                                                <div class="row">
-                                                    <div class="col-4 d-flex align-items-center">
-                                                        <label for="{{ $key }}">{{ $value['label'] }}</label>
-                                                    </div>
+                                        <div
+                                             class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
+                                             id="{{ $category }}" role="tabpanel">
+
+                                            <form action="{{ route('admin.settings.update') }}" method="POST">
+                                                @csrf
+                                                @method('POST')
+                                                <input type="hidden" name="settings_class"
+                                                       value="{{ $options['settings_class'] }}">
+                                                <input type="hidden" name="category" value="{{ $category }}">
+
+                                                @foreach ($options as $key => $value)
+                                                    @if ($key == 'category_icon' || $key == 'settings_class')
+                                                        @continue
+                                                    @endif
+                                                    <div class="row">
+                                                        <div class="col-4 d-flex align-items-center">
+                                                            <label for="{{ $key }}">{{ $value['label'] }}</label>
+                                                        </div>
 
-                                                    <div class="col-8">
-                                                        <div class="custom-control mb-3 d-flex align-items-center">
-                                                            @if ($value['description'])
-                                                                <i class="fas fa-info-circle mr-4" data-toggle="popover"
-                                                                    data-trigger="hover" data-placement="top"
-                                                                    data-html="true"
-                                                                    data-content="{{ $value['description'] }}"></i>
-                                                            @else
-                                                                <i class="fas fa-info-circle mr-4 invisible"></i>
-                                                            @endif
-
-                                                            <div class="w-100">
-                                                                @switch($value)
-                                                                    @case($value['type'] == 'string')
-                                                                        <input type="text" class="form-control"
-                                                                            name="{{ $key }}"
-                                                                            value="{{ $value['value'] }}">
-                                                                    @break
-
-                                                                    @case($value['type'] == 'boolean')
-                                                                        <input type="checkbox" name="{{ $key }}"
-                                                                            value="{{ $value['value'] }}"
-                                                                            {{ $value['value'] ? 'checked' : '' }}>
-                                                                    @break
-
-                                                                    @case($value['type'] == 'number')
-                                                                        <input type="number" class="form-control"
-                                                                            name="{{ $key }}"
-                                                                            value="{{ $value['value'] }}">
-                                                                    @break
-
-                                                                    @case($value['type'] == 'select')
-                                                                        <select id="{{ $key }}"
-                                                                            class="custom-select w-100" name="{{ $key }}">
-
-                                                                            @foreach ($value['options'] as $option=>$display)
-                                                                                <option value="{{ $option }}"
-                                                                                    {{ $value['value'] == $option ? 'selected' : '' }}>
-                                                                                    {{ __($display) }}
-                                                                                </option>
-                                                                            @endforeach
-                                                                        </select>
-                                                                    @break
-
-                                                                    @case($value['type'] == 'multiselect')
-                                                                        <select id="{{ $key }}"
-                                                                            class="custom-select w-100" name="{{ $key }}[]"
-                                                                            multiple>
-                                                                            @foreach ($value['options'] as $option)
-                                                                                <option value="{{ $option }}"
-                                                                                    {{ strpos($value['value'],$option) !== false  ? 'selected' : '' }}>
-                                                                                    {{ __($option) }}
-                                                                                </option>
-                                                                            @endforeach
-                                                                        </select>
-                                                                    @break
-
-                                                                    @case($value['type'] == 'textarea')
-                                                                        <textarea class="form-control" name="{{ $key }}" rows="3">{{ $value['value'] }}</textarea>
-                                                                    @break
-
-                                                                    @default
-                                                                @endswitch
-                                                                @error($key)
+                                                        <div class="col-8">
+                                                            <div class="custom-control mb-3 d-flex align-items-center">
+                                                                @if ($value['description'])
+                                                                    <i class="fas fa-info-circle mr-4"
+                                                                       data-toggle="popover"
+                                                                       data-trigger="hover" data-placement="top"
+                                                                       data-html="true"
+                                                                       data-content="{{ $value['description'] }}"></i>
+                                                                @else
+                                                                    <i class="fas fa-info-circle mr-4 invisible"></i>
+                                                                @endif
+
+                                                                <div class="w-100">
+                                                                    @switch($value)
+                                                                        @case($value['type'] == 'string')
+                                                                            <input type="text" class="form-control"
+                                                                                   name="{{ $key }}"
+                                                                                   value="{{ $value['value'] }}">
+                                                                            @break
+
+                                                                        @case($value['type'] == 'boolean')
+                                                                            <input type="checkbox" name="{{ $key }}"
+                                                                                   value="{{ $value['value'] }}"
+                                                                                {{ $value['value'] ? 'checked' : '' }}>
+                                                                            @break
+
+                                                                        @case($value['type'] == 'number')
+                                                                            <input type="number" class="form-control"
+                                                                                   name="{{ $key }}"
+                                                                                   value="{{ $value['value'] }}">
+                                                                            @break
+
+                                                                        @case($value['type'] == 'select')
+                                                                            <select id="{{ $key }}"
+                                                                                    class="custom-select w-100"
+                                                                                    name="{{ $key }}">
+
+                                                                                @foreach ($value['options'] as $option=>$display)
+                                                                                    <option value="{{ $option }}"
+                                                                                        {{ $value['value'] == $option ? 'selected' : '' }}>
+                                                                                        {{ __($display) }}
+                                                                                    </option>
+                                                                                @endforeach
+                                                                            </select>
+                                                                            @break
+
+                                                                        @case($value['type'] == 'multiselect')
+                                                                            <select id="{{ $key }}"
+                                                                                    class="custom-select w-100"
+                                                                                    name="{{ $key }}[]"
+                                                                                    multiple>
+                                                                                @foreach ($value['options'] as $option)
+                                                                                    <option value="{{ $option }}"
+                                                                                        {{ strpos($value['value'],$option) !== false  ? 'selected' : '' }}>
+                                                                                        {{ __($option) }}
+                                                                                    </option>
+                                                                                @endforeach
+                                                                            </select>
+                                                                            @break
+
+                                                                        @case($value['type'] == 'textarea')
+                                                                            <textarea class="form-control"
+                                                                                      name="{{ $key }}"
+                                                                                      rows="3">{{ $value['value'] }}</textarea>
+                                                                            @break
+
+                                                                        @default
+                                                                    @endswitch
+                                                                    @error($key)
                                                                     <div class="text-danger ">
                                                                         {{ $message }}
                                                                     </div>
-                                                                @enderror
-                                                            </div>
+                                                                    @enderror
+                                                                </div>
 
 
-                                                        </div>
+                                                            </div>
 
+                                                        </div>
                                                     </div>
-                                                </div>
 
-                                            @endforeach
+                                                @endforeach
 
-                                            <!-- TODO: Display this only on the General tab
+                                                <!-- TODO: Display this only on the General tab
 
                                             <div class="row">
                                                 <div class="col-4 d-flex align-items-center">
@@ -230,10 +281,10 @@ class="custom-select w-100" name="{{ $key }}[]"
                                                         <div class="w-100">
                                                 <div class="input-group mb-3">
                                                     {!! htmlScriptTagJsApi() !!}
-                                                    {!! htmlFormSnippet() !!}
-                                                    @error('g-recaptcha-response')
-                                                    <span class="text-danger" role="alert">
-                                                                                <small><strong>{{ $message }}</strong></small>
+                                                {!! htmlFormSnippet() !!}
+                                                @error('g-recaptcha-response')
+                                                <span class="text-danger" role="alert">
+                                                                            <small><strong>{{ $message }}</strong></small>
                                                                                 </span>
                                                     @enderror
                                                 </div>
@@ -243,16 +294,18 @@ class="custom-select w-100" name="{{ $key }}[]"
                                                -->
 
 
-                                            <div class="row">
-                                                <div class="col-12 d-flex align-items-center justify-content-end">
-                                                    <button type="submit"
-                                                        class="btn btn-primary float-right ">Save</button>
-                                                    <button type="reset"
-                                                        class="btn btn-secondary float-right ml-2">Reset</button>
+                                                <div class="row">
+                                                    <div class="col-12 d-flex align-items-center justify-content-end">
+                                                        <button type="submit"
+                                                                class="btn btn-primary float-right ">Save
+                                                        </button>
+                                                        <button type="reset"
+                                                                class="btn btn-secondary float-right ml-2">Reset
+                                                        </button>
+                                                    </div>
                                                 </div>
-                                            </div>
-                                        </form>
-                                    </div>
+                                            </form>
+                                        </div>
                                     @endcanany
                                 @endforeach
 
@@ -261,9 +314,8 @@ class="btn btn-secondary float-right ml-2">Reset</button>
                     </div>
                 </div>
             </div>
-            </div>
         </div>
-
+        </div>
 
 
         <!-- END CUSTOM CONTENT -->
@@ -277,7 +329,7 @@ class="btn btn-secondary float-right ml-2">Reset</button>
             $('.nav-item a[href="' + tabPaneHash + '"]').tab('show');
         }
 
-        $('.nav-pills a').click(function(e) {
+        $('.nav-pills a').click(function (e) {
             $(this).tab('show');
             const scrollmem = $('body').scrollTop();
             window.location.hash = this.hash;

From 1c179702d0aa473b254bd9d8adc4b68e9db42cbf Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 11 May 2023 09:32:13 +0200
Subject: [PATCH 169/514] Re-Implement Image uploading

---
 .../Controllers/Admin/SettingsController.php  | 21 ++++++++
 routes/web.php                                |  7 ++-
 .../views/admin/settings/index.blade.php      | 54 +++++++++++++++++++
 3 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 7d1657f1d..47cc4207d 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -138,4 +138,25 @@ public function update(Request $request)
 
         return Redirect::to('admin/settings' . '#' . $category)->with('success', 'Settings updated successfully.');
     }
+
+    public function updateIcons(Request $request)
+    {
+        $request->validate([
+            'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
+            'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
+            'favicon' => 'nullable|max:10000|mimes:ico',
+        ]);
+
+        if ($request->hasFile('icon')) {
+            $request->file('icon')->storeAs('public', 'icon.png');
+        }
+        if ($request->hasFile('logo')) {
+            $request->file('logo')->storeAs('public', 'logo.png');
+        }
+        if ($request->hasFile('favicon')) {
+            $request->file('favicon')->storeAs('public', 'favicon.ico');
+        }
+
+        return Redirect::to('admin/settings')->with('success', 'Icons updated successfully.');
+    }
 }
diff --git a/routes/web.php b/routes/web.php
index 425c56135..5e09c048b 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -169,13 +169,12 @@
         Route::get('payments', [PaymentController::class, 'index'])->name('payments.index');
 
         //settings
-        Route::get('settings/datatable', [SettingsController::class, 'datatable'])->name('settings.datatable');
-        Route::patch('settings/updatevalue', [SettingsController::class, 'updatevalue'])->name('settings.updatevalue');
-        Route::get('settings/checkPteroClientkey', [System::class, 'checkPteroClientkey'])->name('settings.checkPteroClientkey');
-        Route::redirect('settings#system', 'system')->name('settings.system');
+
 
         Route::get('settings', [SettingsController::class, 'index'])->name('settings.index');
         Route::post('settings', [SettingsController::class, 'update'])->name('settings.update');
+        Route::post('settings/icons', [SettingsController::class, 'updateIcons'])->name('settings.updateIcons');
+
 
         //invoices
         Route::get('invoices/download-invoices', [InvoiceController::class, 'downloadAllInvoices'])->name('invoices.downloadAllInvoices');
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 28615dbee..f3438dd2b 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -44,6 +44,17 @@
                             <nav class="mt-1">
                                 <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                     data-accordion="false">
+                                    <li class="nav-item border-bottom-0">
+                                        <a href="#icons"
+                                           class="nav-link" data-toggle="pill"
+                                           role="tab">
+                                            <i
+                                                class="nav-icon fas fa-image"></i>
+                                            <p>
+                                                {{ __("Images / Icons") }}
+                                            </p>
+                                        </a>
+                                    </li>
                                     @foreach ($settings as $category => $options)
                                         @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
                                         <li class="nav-item border-bottom-0">
@@ -66,6 +77,48 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                         <!-- Content in $settings -->
                         <div class="col-10 p-0">
                             <div class="tab-content ml-3" style="width: 100%;">
+                                <div container class="tab-pane fade container"
+                                     id="icons" role="tabpanel">
+
+                                    <form method="POST" enctype="multipart/form-data" class="mb-3"
+                                          action="{{ route('admin.settings.updateIcons') }}">
+                                        @csrf
+                                        @method('POST')
+                                        <div class="row">
+                                                <div class="card ml-5" style="width: 18rem;">
+                                                    <span class="h3 text-center">{{__("FavIcon")}} </span>
+                                                    <div class="card-body">
+
+                                                    </div>
+                                                    <input type="file" accept="image/x-icon" class="form-control" name="favicon"
+                                                           id="favicon">
+                                                </div>
+
+                                            <div class="card ml-5" style="width: 18rem;">
+                                                <span class="h3 text-center">{{__("Icon")}} </span>
+                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <div class="card-body">
+
+                                                </div>
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                       name="icon" id="icon">
+                                            </div>
+
+                                            <div class="card ml-5" style="width: 18rem;">
+                                                <span class="h3 text-center">{{__("Login-page Logo")}} </span>
+                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <div class="card-body">
+
+                                                </div>
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                       name="logo" id="logo">
+                                            </div>
+                                        </div>
+                                        <div class="row">
+                                            <button class="btn btn-primary ml-3 mt-3">{{ __('Save') }}</button>
+                                        </div>
+                                    </form>
+                                </div>
                                 @foreach ($settings as $category => $options)
                                     @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
                                     <div container class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
@@ -208,6 +261,7 @@ class="btn btn-secondary float-right ml-2">Reset</button>
                     </div>
                 </div>
             </div>
+            </div>
         </div>
 
 

From ce65b9860ccc454680bb26168413ef115c7a1b7b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 11 May 2023 11:06:30 +0200
Subject: [PATCH 170/514] Collapseable extension settings

---
 .../views/admin/settings/index.blade.php      | 310 ++++++++++--------
 1 file changed, 181 insertions(+), 129 deletions(-)

diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index f3438dd2b..3c396a8ce 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -12,7 +12,8 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a></li>
+                                                       href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a>
+                        </li>
                     </ol>
                 </div>
             </div>
@@ -24,7 +25,9 @@
             <h4>{{ __('The installer is not locked!') }}</h4>
             <p>{{ __('please create a file called "install.lock" in your dashboard Root directory. Otherwise no settings will be loaded!') }}
             </p>
-            <a href="/install?step=7"><button class="btn btn-outline-danger">{{ __('or click here') }}</button></a>
+            <a href="/install?step=7">
+                <button class="btn btn-outline-danger">{{ __('or click here') }}</button>
+            </a>
 
         </div>
     @endif
@@ -56,21 +59,54 @@ class="nav-icon fas fa-image"></i>
                                         </a>
                                     </li>
                                     @foreach ($settings as $category => $options)
-                                        @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
-                                        <li class="nav-item border-bottom-0">
-                                            <a href="#{{ $category }}"
-                                                class="nav-link {{ $loop->first ? 'active' : '' }}" data-toggle="pill"
-                                                role="tab">
-                                                <i
-                                                    class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
-                                                <p>
-                                                    {{ $category }}
-                                                </p>
-                                            </a>
-                                        </li>
-                                        @endcanany
+                                        @if(!str_contains($options['settings_class'],"Extension"))
+                                            @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
+                                                <li class="nav-item border-bottom-0">
+                                                    <a href="#{{ $category }}"
+                                                       class="nav-link {{ $loop->first ? 'active' : '' }}"
+                                                       data-toggle="pill"
+                                                       role="tab">
+                                                        <i
+                                                            class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
+                                                        <p>
+                                                            {{ $category }}
+                                                        </p>
+                                                    </a>
+                                                </li>
+                                            @endcanany
+                                        @endif
                                     @endforeach
                                 </ul>
+                                    <i class="fa-solid fa-up-right-from-square"></i>
+                                    <button class="btn btn-outline-secondary" type="button" data-toggle="collapse"
+                                            data-target="#collapseExtensions" aria-expanded="false"
+                                            aria-controls="collapseExample">
+                                        {{__("Extension Settings")}}
+                                    </button>
+                                    </p>
+                                    <div class="collapse" id="collapseExtensions">
+                                        <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
+                                            data-accordion="false">
+                                        @foreach ($settings as $category => $options)
+                                            @if(str_contains($options['settings_class'],"Extension"))
+
+                                                @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
+                                                        <li class="nav-item border-bottom-0">
+                                                            <a href="#{{ $category }}"
+                                                               class="nav-link"
+                                                               data-toggle="pill"
+                                                               role="tab">
+                                                                <i class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
+                                                                <p>
+                                                                    {{ $category }}
+                                                                </p>
+                                                            </a>
+                                                        </li>
+                                                @endcanany
+                                            @endif
+                                        @endforeach
+                                    </div>
+                                </ul>
                             </nav>
                         </div>
                         <!-- /.sidebar-menu -->
@@ -85,32 +121,41 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                         @csrf
                                         @method('POST')
                                         <div class="row">
-                                                <div class="card ml-5" style="width: 18rem;">
-                                                    <span class="h3 text-center">{{__("FavIcon")}} </span>
-                                                    <div class="card-body">
+                                            <div class="card ml-5" style="width: 18rem;">
+                                                <span class="h3 text-center">{{__("FavIcon")}} </span>
+                                                <div class="card-body">
 
-                                                    </div>
-                                                    <input type="file" accept="image/x-icon" class="form-control" name="favicon"
-                                                           id="favicon">
                                                 </div>
+                                                <input type="file" accept="image/x-icon" class="form-control"
+                                                       name="favicon"
+                                                       id="favicon">
+                                            </div>
 
                                             <div class="card ml-5" style="width: 18rem;">
                                                 <span class="h3 text-center">{{__("Icon")}} </span>
-                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <img
+                                                    src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
+                                                    style="width:5vw;display: block; margin-left: auto;margin-right: auto"
+                                                    class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
-                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg"
+                                                       class="form-control"
                                                        name="icon" id="icon">
                                             </div>
 
                                             <div class="card ml-5" style="width: 18rem;">
                                                 <span class="h3 text-center">{{__("Login-page Logo")}} </span>
-                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}" style="width:5vw;display: block; margin-left: auto;margin-right: auto" class="card-img-top" alt="..." >
+                                                <img
+                                                    src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
+                                                    style="width:5vw;display: block; margin-left: auto;margin-right: auto"
+                                                    class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
-                                                <input type="file" accept="image/png,image/jpeg,image/jpg" class="form-control"
+                                                <input type="file" accept="image/png,image/jpeg,image/jpg"
+                                                       class="form-control"
                                                        name="logo" id="logo">
                                             </div>
                                         </div>
@@ -121,104 +166,110 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                 </div>
                                 @foreach ($settings as $category => $options)
                                     @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
-                                    <div container class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
-                                        id="{{ $category }}" role="tabpanel">
-
-                                        <form action="{{ route('admin.settings.update') }}" method="POST">
-                                            @csrf
-                                            @method('POST')
-                                            <input type="hidden" name="settings_class"
-                                                value="{{ $options['settings_class'] }}">
-                                            <input type="hidden" name="category" value="{{ $category }}">
-
-                                            @foreach ($options as $key => $value)
-                                                @if ($key == 'category_icon' || $key == 'settings_class')
-                                                    @continue
-                                                @endif
-                                                <div class="row">
-                                                    <div class="col-4 d-flex align-items-center">
-                                                        <label for="{{ $key }}">{{ $value['label'] }}</label>
-                                                    </div>
+                                        <div
+                                             class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
+                                             id="{{ $category }}" role="tabpanel">
+
+                                            <form action="{{ route('admin.settings.update') }}" method="POST">
+                                                @csrf
+                                                @method('POST')
+                                                <input type="hidden" name="settings_class"
+                                                       value="{{ $options['settings_class'] }}">
+                                                <input type="hidden" name="category" value="{{ $category }}">
+
+                                                @foreach ($options as $key => $value)
+                                                    @if ($key == 'category_icon' || $key == 'settings_class')
+                                                        @continue
+                                                    @endif
+                                                    <div class="row">
+                                                        <div class="col-4 d-flex align-items-center">
+                                                            <label for="{{ $key }}">{{ $value['label'] }}</label>
+                                                        </div>
 
-                                                    <div class="col-8">
-                                                        <div class="custom-control mb-3 d-flex align-items-center">
-                                                            @if ($value['description'])
-                                                                <i class="fas fa-info-circle mr-4" data-toggle="popover"
-                                                                    data-trigger="hover" data-placement="top"
-                                                                    data-html="true"
-                                                                    data-content="{{ $value['description'] }}"></i>
-                                                            @else
-                                                                <i class="fas fa-info-circle mr-4 invisible"></i>
-                                                            @endif
-
-                                                            <div class="w-100">
-                                                                @switch($value)
-                                                                    @case($value['type'] == 'string')
-                                                                        <input type="text" class="form-control"
-                                                                            name="{{ $key }}"
-                                                                            value="{{ $value['value'] }}">
-                                                                    @break
-
-                                                                    @case($value['type'] == 'boolean')
-                                                                        <input type="checkbox" name="{{ $key }}"
-                                                                            value="{{ $value['value'] }}"
-                                                                            {{ $value['value'] ? 'checked' : '' }}>
-                                                                    @break
-
-                                                                    @case($value['type'] == 'number')
-                                                                        <input type="number" class="form-control"
-                                                                            name="{{ $key }}"
-                                                                            value="{{ $value['value'] }}">
-                                                                    @break
-
-                                                                    @case($value['type'] == 'select')
-                                                                        <select id="{{ $key }}"
-                                                                            class="custom-select w-100" name="{{ $key }}">
-
-                                                                            @foreach ($value['options'] as $option=>$display)
-                                                                                <option value="{{ $option }}"
-                                                                                    {{ $value['value'] == $option ? 'selected' : '' }}>
-                                                                                    {{ __($display) }}
-                                                                                </option>
-                                                                            @endforeach
-                                                                        </select>
-                                                                    @break
-
-                                                                    @case($value['type'] == 'multiselect')
-                                                                        <select id="{{ $key }}"
-                                                                            class="custom-select w-100" name="{{ $key }}[]"
-                                                                            multiple>
-                                                                            @foreach ($value['options'] as $option)
-                                                                                <option value="{{ $option }}"
-                                                                                    {{ strpos($value['value'],$option) !== false  ? 'selected' : '' }}>
-                                                                                    {{ __($option) }}
-                                                                                </option>
-                                                                            @endforeach
-                                                                        </select>
-                                                                    @break
-
-                                                                    @case($value['type'] == 'textarea')
-                                                                        <textarea class="form-control" name="{{ $key }}" rows="3">{{ $value['value'] }}</textarea>
-                                                                    @break
-
-                                                                    @default
-                                                                @endswitch
-                                                                @error($key)
+                                                        <div class="col-8">
+                                                            <div class="custom-control mb-3 d-flex align-items-center">
+                                                                @if ($value['description'])
+                                                                    <i class="fas fa-info-circle mr-4"
+                                                                       data-toggle="popover"
+                                                                       data-trigger="hover" data-placement="top"
+                                                                       data-html="true"
+                                                                       data-content="{{ $value['description'] }}"></i>
+                                                                @else
+                                                                    <i class="fas fa-info-circle mr-4 invisible"></i>
+                                                                @endif
+
+                                                                <div class="w-100">
+                                                                    @switch($value)
+                                                                        @case($value['type'] == 'string')
+                                                                            <input type="text" class="form-control"
+                                                                                   name="{{ $key }}"
+                                                                                   value="{{ $value['value'] }}">
+                                                                            @break
+
+                                                                        @case($value['type'] == 'boolean')
+                                                                            <input type="checkbox" name="{{ $key }}"
+                                                                                   value="{{ $value['value'] }}"
+                                                                                {{ $value['value'] ? 'checked' : '' }}>
+                                                                            @break
+
+                                                                        @case($value['type'] == 'number')
+                                                                            <input type="number" class="form-control"
+                                                                                   name="{{ $key }}"
+                                                                                   value="{{ $value['value'] }}">
+                                                                            @break
+
+                                                                        @case($value['type'] == 'select')
+                                                                            <select id="{{ $key }}"
+                                                                                    class="custom-select w-100"
+                                                                                    name="{{ $key }}">
+
+                                                                                @foreach ($value['options'] as $option=>$display)
+                                                                                    <option value="{{ $option }}"
+                                                                                        {{ $value['value'] == $option ? 'selected' : '' }}>
+                                                                                        {{ __($display) }}
+                                                                                    </option>
+                                                                                @endforeach
+                                                                            </select>
+                                                                            @break
+
+                                                                        @case($value['type'] == 'multiselect')
+                                                                            <select id="{{ $key }}"
+                                                                                    class="custom-select w-100"
+                                                                                    name="{{ $key }}[]"
+                                                                                    multiple>
+                                                                                @foreach ($value['options'] as $option)
+                                                                                    <option value="{{ $option }}"
+                                                                                        {{ strpos($value['value'],$option) !== false  ? 'selected' : '' }}>
+                                                                                        {{ __($option) }}
+                                                                                    </option>
+                                                                                @endforeach
+                                                                            </select>
+                                                                            @break
+
+                                                                        @case($value['type'] == 'textarea')
+                                                                            <textarea class="form-control"
+                                                                                      name="{{ $key }}"
+                                                                                      rows="3">{{ $value['value'] }}</textarea>
+                                                                            @break
+
+                                                                        @default
+                                                                    @endswitch
+                                                                    @error($key)
                                                                     <div class="text-danger ">
                                                                         {{ $message }}
                                                                     </div>
-                                                                @enderror
-                                                            </div>
+                                                                    @enderror
+                                                                </div>
 
 
-                                                        </div>
+                                                            </div>
 
+                                                        </div>
                                                     </div>
-                                                </div>
 
-                                            @endforeach
+                                                @endforeach
 
-                                            <!-- TODO: Display this only on the General tab
+                                                <!-- TODO: Display this only on the General tab
 
                                             <div class="row">
                                                 <div class="col-4 d-flex align-items-center">
@@ -230,10 +281,10 @@ class="custom-select w-100" name="{{ $key }}[]"
                                                         <div class="w-100">
                                                 <div class="input-group mb-3">
                                                     {!! htmlScriptTagJsApi() !!}
-                                                    {!! htmlFormSnippet() !!}
-                                                    @error('g-recaptcha-response')
-                                                    <span class="text-danger" role="alert">
-                                                                                <small><strong>{{ $message }}</strong></small>
+                                                {!! htmlFormSnippet() !!}
+                                                @error('g-recaptcha-response')
+                                                <span class="text-danger" role="alert">
+                                                                            <small><strong>{{ $message }}</strong></small>
                                                                                 </span>
                                                     @enderror
                                                 </div>
@@ -243,16 +294,18 @@ class="custom-select w-100" name="{{ $key }}[]"
                                                -->
 
 
-                                            <div class="row">
-                                                <div class="col-12 d-flex align-items-center justify-content-end">
-                                                    <button type="submit"
-                                                        class="btn btn-primary float-right ">Save</button>
-                                                    <button type="reset"
-                                                        class="btn btn-secondary float-right ml-2">Reset</button>
+                                                <div class="row">
+                                                    <div class="col-12 d-flex align-items-center justify-content-end">
+                                                        <button type="submit"
+                                                                class="btn btn-primary float-right ">Save
+                                                        </button>
+                                                        <button type="reset"
+                                                                class="btn btn-secondary float-right ml-2">Reset
+                                                        </button>
+                                                    </div>
                                                 </div>
-                                            </div>
-                                        </form>
-                                    </div>
+                                            </form>
+                                        </div>
                                     @endcanany
                                 @endforeach
 
@@ -261,9 +314,8 @@ class="btn btn-secondary float-right ml-2">Reset</button>
                     </div>
                 </div>
             </div>
-            </div>
         </div>
-
+        </div>
 
 
         <!-- END CUSTOM CONTENT -->
@@ -277,7 +329,7 @@ class="btn btn-secondary float-right ml-2">Reset</button>
             $('.nav-item a[href="' + tabPaneHash + '"]').tab('show');
         }
 
-        $('.nav-pills a').click(function(e) {
+        $('.nav-pills a').click(function (e) {
             $(this).tab('show');
             const scrollmem = $('body').scrollTop();
             window.location.hash = this.hash;

From b88727940cf3a4648eddea3eb1801e9887bd5282 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 11 May 2023 11:11:22 +0200
Subject: [PATCH 171/514] clean up

---
 themes/default/views/admin/settings/index.blade.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 3c396a8ce..7c9f59b5b 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -77,13 +77,13 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                         @endif
                                     @endforeach
                                 </ul>
-                                    <i class="fa-solid fa-up-right-from-square"></i>
+
                                     <button class="btn btn-outline-secondary" type="button" data-toggle="collapse"
                                             data-target="#collapseExtensions" aria-expanded="false"
-                                            aria-controls="collapseExample">
+                                            aria-controls="collapseExtensions">
                                         {{__("Extension Settings")}}
                                     </button>
-                                    </p>
+
                                     <div class="collapse" id="collapseExtensions">
                                         <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                             data-accordion="false">

From 21529ddf65326a0de12bb371365e347e93164a1b Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 12 May 2023 15:52:58 +0200
Subject: [PATCH 172/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Number=20Input=20?=
 =?UTF-8?q?steps?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../views/admin/products/create.blade.php     | 355 +++++++++---------
 .../views/admin/products/edit.blade.php       | 351 +++++++++--------
 2 files changed, 347 insertions(+), 359 deletions(-)

diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index 082c24541..c6c5427f6 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -6,15 +6,15 @@
         <div class="container-fluid">
             <div class="row mb-2">
                 <div class="col-sm-6">
-                    <h1>{{__('Products')}}</h1>
+                    <h1>{{ __('Products') }}</h1>
                 </div>
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a href="{{ route('admin.products.index') }}">{{__('Products')}}</a>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.products.index') }}">{{ __('Products') }}</a>
                         </li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{ route('admin.products.create') }}">{{__('Create')}}</a>
+                                href="{{ route('admin.products.create') }}">{{ __('Create') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -26,23 +26,23 @@
     <!-- MAIN CONTENT -->
     <section class="content">
         <div class="container-fluid">
-            <form action="{{route('admin.products.store')}}" method="POST">
+            <form action="{{ route('admin.products.store') }}" method="POST">
                 @csrf
                 <div class="row">
                     <div class="col-lg-6">
                         <div class="card">
                             <div class="card-header">
-                                <h5 class="card-title">{{__('Product Details')}}</h5>
+                                <h5 class="card-title">{{ __('Product Details') }}</h5>
                             </div>
                             <div class="card-body">
 
                                 <div class="d-flex flex-row-reverse">
                                     <div class="custom-control custom-switch">
                                         <input type="checkbox" name="disabled"
-                                               class="custom-control-input custom-control-input-danger" id="switch1">
-                                        <label class="custom-control-label" for="switch1">{{__('Disabled')}} <i
+                                            class="custom-control-input custom-control-input-danger" id="switch1">
+                                        <label class="custom-control-label" for="switch1">{{ __('Disabled') }} <i
                                                 data-toggle="popover" data-trigger="hover"
-                                                data-content="{{__('Will hide this option from being selected')}}"
+                                                data-content="{{ __('Will hide this option from being selected') }}"
                                                 class="fas fa-info-circle"></i></label>
                                     </div>
                                 </div>
@@ -50,219 +50,209 @@ class="fas fa-info-circle"></i></label>
                                 <div class="row">
                                     <div class="col-lg-6">
                                         <div class="form-group">
-                                            <label for="name">{{__('Name')}}</label>
-                                            <input value="{{$product->name ?? old('name')}}" id="name" name="name"
-                                                   type="text"
-                                                   class="form-control @error('name') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="name">{{ __('Name') }}</label>
+                                            <input value="{{ $product->name ?? old('name') }}" id="name"
+                                                name="name" type="text"
+                                                class="form-control @error('name') is-invalid @enderror"
+                                                required="required">
                                             @error('name')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="price">{{__('Price in')}} {{ $credits_display_name }}</label>
-                                            <input value="{{$product->price ??  old('price')}}" id="price" name="price" step=".01"
-                                                   type="number"
-                                                   step="0.0001"
-                                                   class="form-control @error('price') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="price">{{ __('Price in') }} {{ $credits_display_name }}</label>
+                                            <input value="{{ $product->price ?? old('price') }}" id="price"
+                                                name="price" step=".0001" type="number"
+                                                class="form-control @error('price') is-invalid @enderror"
+                                                required="required">
                                             @error('price')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
 
                                         <div class="form-group">
-                                            <label for="memory">{{__('Memory')}}</label>
-                                            <input value="{{$product->memory ?? old('memory')}}" id="memory"
-                                                   name="memory"
-                                                   type="number"
-                                                   class="form-control @error('memory') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="memory">{{ __('Memory') }}</label>
+                                            <input value="{{ $product->memory ?? old('memory') }}" id="memory"
+                                                name="memory" type="number"
+                                                class="form-control @error('memory') is-invalid @enderror"
+                                                required="required">
                                             @error('memory')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="cpu">{{__('Cpu')}}</label>
-                                            <input value="{{$product->cpu ?? old('cpu')}}" id="cpu" name="cpu"
-                                                   type="number"
-                                                   class="form-control @error('cpu') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="cpu">{{ __('Cpu') }}</label>
+                                            <input value="{{ $product->cpu ?? old('cpu') }}" id="cpu" name="cpu"
+                                                type="number" class="form-control @error('cpu') is-invalid @enderror"
+                                                required="required">
                                             @error('cpu')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="swap">{{__('Swap')}}</label>
-                                            <input value="{{$product->swap ?? old('swap')}}" id="swap" name="swap"
-                                                   type="number"
-                                                   class="form-control @error('swap') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="swap">{{ __('Swap') }}</label>
+                                            <input value="{{ $product->swap ?? old('swap') }}" id="swap"
+                                                name="swap" type="number"
+                                                class="form-control @error('swap') is-invalid @enderror"
+                                                required="required">
                                             @error('swap')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="allocations">{{__('Allocations')}}</label>
-                                            <input value="{{$product->allocations ?? old('allocations') ?? 0}}"
-                                                   id="allocations" name="allocations"
-                                                   type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="allocations">{{ __('Allocations') }}</label>
+                                            <input value="{{ $product->allocations ?? (old('allocations') ?? 0) }}"
+                                                id="allocations" name="allocations" type="number"
+                                                class="form-control @error('allocations') is-invalid @enderror"
+                                                required="required">
                                             @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="description">{{__('Description')}} <i data-toggle="popover"
-                                                                                              data-trigger="hover"
-                                                                                              data-content="{{__('This is what the users sees')}}"
-                                                                                              class="fas fa-info-circle"></i></label>
-                                            <textarea id="description" name="description"
-                                                      type="text"
-                                                      class="form-control @error('description') is-invalid @enderror"
-                                                      required="required">{{$product->description ?? old('description')}}</textarea>
+                                            <label for="description">{{ __('Description') }} <i data-toggle="popover"
+                                                    data-trigger="hover"
+                                                    data-content="{{ __('This is what the users sees') }}"
+                                                    class="fas fa-info-circle"></i></label>
+                                            <textarea id="description" name="description" type="text"
+                                                class="form-control @error('description') is-invalid @enderror" required="required">{{ $product->description ?? old('description') }}</textarea>
                                             @error('description')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <input type="checkbox"  value="1"  id="oom" name="oom_killer"
-                                                   class="">
+                                            <input type="checkbox" value="1" id="oom" name="oom_killer"
+                                                class="">
 
-                                            <label for="oom_killer">{{__('OOM Killer')}} <i
-                                                    data-toggle="popover" data-trigger="hover"
-                                                    data-content="{{__('Enable or Disable the OOM Killer for this Product.')}}"
+                                            <label for="oom_killer">{{ __('OOM Killer') }} <i data-toggle="popover"
+                                                    data-trigger="hover"
+                                                    data-content="{{ __('Enable or Disable the OOM Killer for this Product.') }}"
                                                     class="fas fa-info-circle"></i></label>
                                         </div>
                                     </div>
                                     <div class="col-lg-6">
                                         <div class="form-group">
-                                            <label for="disk">{{__('Disk')}}</label>
-                                            <input value="{{$product->disk ?? old('disk') ?? 1000}}" id="disk"
-                                                   name="disk"
-                                                   type="number"
-                                                   class="form-control @error('disk') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="disk">{{ __('Disk') }}</label>
+                                            <input value="{{ $product->disk ?? (old('disk') ?? 1000) }}" id="disk"
+                                                name="disk" type="number"
+                                                class="form-control @error('disk') is-invalid @enderror"
+                                                required="required">
                                             @error('disk')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="billing_period">{{__('Billing Period')}} <i
+                                            <label for="billing_period">{{ __('Billing Period') }} <i
                                                     data-toggle="popover" data-trigger="hover"
-                                                    data-content="{{__('Period when the user will be charged for the given price')}}"
+                                                    data-content="{{ __('Period when the user will be charged for the given price') }}"
                                                     class="fas fa-info-circle"></i></label>
 
-                                            <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
-                                                autocomplete="off" @error('billing_period') is-invalid @enderror>
-                                                    <option value="hourly" selected>
-                                                        {{__('Hourly')}}
-                                                    </option>
-                                                    <option value="daily">
-                                                        {{__('Daily')}}
-                                                    </option>
-                                                    <option value="weekly">
-                                                        {{__('Weekly')}}
-                                                    </option>
-                                                     <option value="monthly">
-                                                        {{__('Monthly')}}
-                                                    </option>
-                                                    <option value="quarterly">
-                                                        {{__('Quarterly')}}
-                                                    </option>
-                                                    <option value="half-annually">
-                                                        {{__('Half Annually')}}
-                                                    </option>
-                                                    <option value="annually">
-                                                        {{__('Annually')}}
-                                                    </option>
+                                            <select id="billing_period" style="width:100%" class="custom-select"
+                                                name="billing_period" required autocomplete="off"
+                                                @error('billing_period') is-invalid @enderror>
+                                                <option value="hourly" selected>
+                                                    {{ __('Hourly') }}
+                                                </option>
+                                                <option value="daily">
+                                                    {{ __('Daily') }}
+                                                </option>
+                                                <option value="weekly">
+                                                    {{ __('Weekly') }}
+                                                </option>
+                                                <option value="monthly">
+                                                    {{ __('Monthly') }}
+                                                </option>
+                                                <option value="quarterly">
+                                                    {{ __('Quarterly') }}
+                                                </option>
+                                                <option value="half-annually">
+                                                    {{ __('Half Annually') }}
+                                                </option>
+                                                <option value="annually">
+                                                    {{ __('Annually') }}
+                                                </option>
                                             </select>
                                             @error('billing_period')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="minimum_credits">{{__('Minimum')}} {{ $credits_display_name }} <i
-                                                    data-toggle="popover" data-trigger="hover"
-                                                    data-content="{{__('Setting to -1 will use the value from configuration.')}}"
+                                            <label for="minimum_credits">{{ __('Minimum') }} {{ $credits_display_name }}
+                                                <i data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{ __('Setting to -1 will use the value from configuration.') }}"
                                                     class="fas fa-info-circle"></i></label>
                                             <input
-                                                value="{{ $product->minimum_credits ?? old('minimum_credits') ?? -1 }}"
-                                                id="minimum_credits"
-                                                name="minimum_credits" type="number"
+                                                value="{{ $product->minimum_credits ?? (old('minimum_credits') ?? -1) }}"
+                                                id="minimum_credits" name="minimum_credits" type="number"
                                                 class="form-control @error('minimum_credits') is-invalid @enderror"
                                                 required="required">
                                             @error('minimum_credits')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="io">{{__('IO')}}</label>
-                                            <input value="{{$product->io ?? old('io') ?? 500}}" id="io" name="io"
-                                                   type="number"
-                                                   class="form-control @error('io') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="io">{{ __('IO') }}</label>
+                                            <input value="{{ $product->io ?? (old('io') ?? 500) }}" id="io"
+                                                name="io" type="number"
+                                                class="form-control @error('io') is-invalid @enderror"
+                                                required="required">
                                             @error('io')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="databases">{{__('Databases')}}</label>
-                                            <input value="{{$product->databases ?? old('databases') ?? 1}}"
-                                                   id="databases"
-                                                   name="databases"
-                                                   type="number"
-                                                   class="form-control @error('databases') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="databases">{{ __('Databases') }}</label>
+                                            <input value="{{ $product->databases ?? (old('databases') ?? 1) }}"
+                                                id="databases" name="databases" type="number"
+                                                class="form-control @error('databases') is-invalid @enderror"
+                                                required="required">
                                             @error('databases')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="backups">{{__('Backups')}}</label>
-                                            <input value="{{$product->backups ?? old('backups') ?? 1}}" id="backups"
-                                                   name="backups"
-                                                   type="number"
-                                                   class="form-control @error('backups') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="backups">{{ __('Backups') }}</label>
+                                            <input value="{{ $product->backups ?? (old('backups') ?? 1) }}"
+                                                id="backups" name="backups" type="number"
+                                                class="form-control @error('backups') is-invalid @enderror"
+                                                required="required">
                                             @error('backups')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                     </div>
@@ -270,7 +260,7 @@ class="form-control @error('backups') is-invalid @enderror"
 
                                 <div class="form-group text-right">
                                     <button type="submit" class="btn btn-primary">
-                                        {{__('Submit')}}
+                                        {{ __('Submit') }}
                                     </button>
                                 </div>
 
@@ -281,66 +271,69 @@ class="form-control @error('backups') is-invalid @enderror"
                     <div class="col-lg-6">
                         <div class="card">
                             <div class="card-header">
-                                <h5 class="card-title">{{__('Product Linking')}}
-                                    <i data-toggle="popover"
-                                       data-trigger="hover"
-                                       data-content="{{__('Link your products to nodes and eggs to create dynamic pricing for each option')}}"
-                                       class="fas fa-info-circle"></i></h5>
+                                <h5 class="card-title">{{ __('Product Linking') }}
+                                    <i data-toggle="popover" data-trigger="hover"
+                                        data-content="{{ __('Link your products to nodes and eggs to create dynamic pricing for each option') }}"
+                                        class="fas fa-info-circle"></i>
+                                </h5>
                             </div>
                             <div class="card-body">
 
                                 <div class="form-group">
-                                    <label for="nodes">{{__('Nodes')}}</label>
+                                    <label for="nodes">{{ __('Nodes') }}</label>
                                     <select id="nodes" style="width:100%"
-                                            class="custom-select @error('nodes') is-invalid @enderror"
-                                            name="nodes[]" multiple="multiple" autocomplete="off">
-                                        @foreach($locations as $location)
-                                            <optgroup label="{{$location->name}}">
-                                                @foreach($location->nodes as $node)
+                                        class="custom-select @error('nodes') is-invalid @enderror" name="nodes[]"
+                                        multiple="multiple" autocomplete="off">
+                                        @foreach ($locations as $location)
+                                            <optgroup label="{{ $location->name }}">
+                                                @foreach ($location->nodes as $node)
                                                     <option
-                                                        @if(isset($product)) @if($product->nodes->contains('id' , $node->id)) selected
-                                                        @endif @endif value="{{$node->id}}">{{$node->name}}</option>
+                                                        @if (isset($product)) @if ($product->nodes->contains('id', $node->id)) selected @endif
+                                                        @endif
+                                                        value="{{ $node->id }}">{{ $node->name }}</option>
                                                 @endforeach
                                             </optgroup>
                                         @endforeach
                                     </select>
                                     @error('nodes')
-                                    <div class="text-danger">
-                                        {{$message}}
-                                    </div>
+                                        <div class="text-danger">
+                                            {{ $message }}
+                                        </div>
                                     @enderror
                                     <div class="text-muted">
-                                        {{__('This product will only be available for these nodes')}}
+                                        {{ __('This product will only be available for these nodes') }}
                                     </div>
                                 </div>
 
 
                                 <div class="form-group">
-                                    <label for="eggs">{{__('Eggs')}}</label>
+                                    <label for="eggs">{{ __('Eggs') }}</label>
                                     <select id="eggs" style="width:100%"
-                                            class="custom-select @error('eggs') is-invalid @enderror"
-                                            name="eggs[]" multiple="multiple" autocomplete="off">
-                                        @foreach($nests as $nest)
-                                            <optgroup label="{{$nest->name}}">
-                                                @foreach($nest->eggs as $egg)
+                                        class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
+                                        multiple="multiple" autocomplete="off">
+                                        @foreach ($nests as $nest)
+                                            <optgroup label="{{ $nest->name }}">
+                                                @foreach ($nest->eggs as $egg)
                                                     <option
-                                                        @if(isset($product)) @if($product->eggs->contains('id' , $egg->id)) selected
-                                                        @endif @endif  value="{{$egg->id}}">{{$egg->name}}</option>
+                                                        @if (isset($product)) @if ($product->eggs->contains('id', $egg->id)) selected @endif
+                                                        @endif
+                                                        value="{{ $egg->id }}">{{ $egg->name }}</option>
                                                 @endforeach
                                             </optgroup>
                                         @endforeach
                                     </select>
                                     @error('eggs')
-                                    <div class="text-danger">
-                                        {{$message}}
-                                    </div>
+                                        <div class="text-danger">
+                                            {{ $message }}
+                                        </div>
                                     @enderror
                                     <div class="text-muted">
-                                        {{__('This product will only be available for these eggs')}}
+                                        {{ __('This product will only be available for these eggs') }}
                                     </div>
                                 </div>
                                 <div class="text-muted">
-                                    {{__('No Eggs or Nodes shown?')}} <a href="{{route('admin.overview.sync')}}">{{__("Sync now")}}</a>
+                                    {{ __('No Eggs or Nodes shown?') }} <a
+                                        href="{{ route('admin.overview.sync') }}">{{ __('Sync now') }}</a>
                                 </div>
                             </div>
                         </div>
@@ -354,7 +347,7 @@ class="custom-select @error('eggs') is-invalid @enderror"
     <!-- END CONTENT -->
 
     <script>
-        document.addEventListener('DOMContentLoaded', function () {
+        document.addEventListener('DOMContentLoaded', function() {
             $('[data-toggle="popover"]').popover();
             $('.custom-select').select2();
         });
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 7487df2e1..8f7649580 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -6,15 +6,15 @@
         <div class="container-fluid">
             <div class="row mb-2">
                 <div class="col-sm-6">
-                    <h1>{{__('Products')}}</h1>
+                    <h1>{{ __('Products') }}</h1>
                 </div>
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">{{__('Products')}}</a>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.products.index') }}">{{ __('Products') }}</a>
                         </li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('admin.products.edit' , $product->id)}}">{{__('Edit')}}</a>
+                                href="{{ route('admin.products.edit', $product->id) }}">{{ __('Edit') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -26,35 +26,39 @@
     <!-- MAIN CONTENT -->
     <section class="content">
         <div class="container-fluid">
-            <form action="{{route('admin.products.update' , $product->id)}}" method="POST">
+            <form action="{{ route('admin.products.update', $product->id) }}" method="POST">
                 @csrf
                 @method('PATCH')
 
                 <div class="row">
                     <div class="col-lg-6">
 
-                        @if($product->servers()->count() > 0)
+                        @if ($product->servers()->count() > 0)
                             <div class="callout callout-danger">
-                                <h4>{{__('Editing the resource options will not automatically update the servers on
-                                    pterodactyls side!')}}'</h4>
-                                <p class="text-muted">{{__('Automatically updating resource options on pterodactyl side is on
-                                    my todo list :)')}}</p>
+                                <h4>{{ __('Editing the resource options will not automatically update the servers on
+                                                                                                    pterodactyls side!') }}'
+                                </h4>
+                                <p class="text-muted">
+                                    {{ __('Automatically updating resource options on pterodactyl side is on
+                                                                                                            my todo list :)') }}
+                                </p>
                             </div>
                         @endif
 
                         <div class="card">
                             <div class="card-header">
-                                <h5 class="card-title">{{__('Product Details')}}</h5>
+                                <h5 class="card-title">{{ __('Product Details') }}</h5>
                             </div>
                             <div class="card-body">
 
                                 <div class="d-flex flex-row-reverse">
                                     <div class="custom-control custom-switch">
-                                        <input type="checkbox" @if($product->disabled) checked @endif name="disabled"
-                                               class="custom-control-input custom-control-input-danger" id="switch1">
-                                        <label class="custom-control-label" for="switch1">{{__('Disabled')}} <i
+                                        <input type="checkbox" @if ($product->disabled) checked @endif
+                                            name="disabled" class="custom-control-input custom-control-input-danger"
+                                            id="switch1">
+                                        <label class="custom-control-label" for="switch1">{{ __('Disabled') }} <i
                                                 data-toggle="popover" data-trigger="hover"
-                                                data-content="{{__('Will hide this option from being selected')}}"
+                                                data-content="{{ __('Will hide this option from being selected') }}"
                                                 class="fas fa-info-circle"></i></label>
                                     </div>
                                 </div>
@@ -63,211 +67,203 @@ class="fas fa-info-circle"></i></label>
                                     <div class="col-lg-6">
 
                                         <div class="form-group">
-                                            <label for="name">{{__('Name')}}</label>
-                                            <input value="{{ $product->name }}" id="name" name="name" type="text"
-                                                   class="form-control @error('name') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="name">{{ __('Name') }}</label>
+                                            <input value="{{ $product->name }}" id="name" name="name"
+                                                type="text" class="form-control @error('name') is-invalid @enderror"
+                                                required="required">
                                             @error('name')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="price">{{__('Price in')}} {{ $credits_display_name }}</label>
-                                            <input value="{{$product->price}}" id="price" name="price"
-                                                   type="number"
-                                                   step="0.0001"
-                                                   class="form-control @error('price') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="price">{{ __('Price in') }} {{ $credits_display_name }}</label>
+                                            <input value="{{ $product->price }}" id="price" name="price"
+                                                type="number" step=".0001"
+                                                class="form-control @error('price') is-invalid @enderror"
+                                                required="required">
                                             @error('price')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="memory">{{__('Memory')}}</label>
+                                            <label for="memory">{{ __('Memory') }}</label>
                                             <input value="{{ $product->memory }}" id="memory" name="memory"
-                                                   type="number"
-                                                   class="form-control @error('memory') is-invalid @enderror"
-                                                   required="required">
+                                                type="number" class="form-control @error('memory') is-invalid @enderror"
+                                                required="required">
                                             @error('memory')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="cpu">{{__('Cpu')}}</label>
+                                            <label for="cpu">{{ __('Cpu') }}</label>
                                             <input value="{{ $product->cpu }}" id="cpu" name="cpu" type="number"
-                                                   class="form-control @error('cpu') is-invalid @enderror"
-                                                   required="required">
+                                                class="form-control @error('cpu') is-invalid @enderror" required="required">
                                             @error('cpu')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="swap">{{__('Swap')}}</label>
-                                            <input value="{{ $product->swap }}" id="swap" name="swap" type="number"
-                                                   class="form-control @error('swap') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="swap">{{ __('Swap') }}</label>
+                                            <input value="{{ $product->swap }}" id="swap" name="swap"
+                                                type="number" class="form-control @error('swap') is-invalid @enderror"
+                                                required="required">
                                             @error('swap')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="allocations">{{__('Allocations')}}</label>
-                                            <input value="{{ $product->allocations }}" id="allocations"
-                                                   name="allocations" type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="allocations">{{ __('Allocations') }}</label>
+                                            <input value="{{ $product->allocations }}" id="allocations" name="allocations"
+                                                type="number"
+                                                class="form-control @error('allocations') is-invalid @enderror"
+                                                required="required">
                                             @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="description">{{__('Description')}} <i data-toggle="popover"
-                                                                                              data-trigger="hover"
-                                                                                              data-content="{{__('This is what the users sees')}}"
-                                                                                              class="fas fa-info-circle"></i></label>
-                                            <textarea id="description" name="description"
-                                                      type="text"
-                                                      class="form-control @error('description') is-invalid @enderror"
-                                                      required="required">{{$product->description}}</textarea>
+                                            <label for="description">{{ __('Description') }} <i data-toggle="popover"
+                                                    data-trigger="hover"
+                                                    data-content="{{ __('This is what the users sees') }}"
+                                                    class="fas fa-info-circle"></i></label>
+                                            <textarea id="description" name="description" type="text"
+                                                class="form-control @error('description') is-invalid @enderror" required="required">{{ $product->description }}</textarea>
                                             @error('description')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <input type="checkbox" @if($product->oom_killer) checked @endif value="1"  id="oom" name="oom_killer"
-                                                   class="">
+                                            <input type="checkbox" @if ($product->oom_killer) checked @endif
+                                                value="1" id="oom" name="oom_killer" class="">
 
-                                            <label for="oom_killer">{{__('OOM Killer')}} <i
-                                                    data-toggle="popover" data-trigger="hover"
-                                                    data-content="{{__('Enable or Disable the OOM Killer for this Product.')}}"
+                                            <label for="oom_killer">{{ __('OOM Killer') }} <i data-toggle="popover"
+                                                    data-trigger="hover"
+                                                    data-content="{{ __('Enable or Disable the OOM Killer for this Product.') }}"
                                                     class="fas fa-info-circle"></i></label>
                                         </div>
 
                                     </div>
                                     <div class="col-lg-6">
                                         <div class="form-group">
-                                            <label for="disk">{{__('Disk')}}</label>
-                                            <input value="{{ $product->disk }}" id="disk" name="disk" type="number"
-                                                   class="form-control @error('disk') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="disk">{{ __('Disk') }}</label>
+                                            <input value="{{ $product->disk }}" id="disk" name="disk"
+                                                type="number" class="form-control @error('disk') is-invalid @enderror"
+                                                required="required">
                                             @error('disk')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="billing_period">{{__('Billing Period')}} <i
+                                            <label for="billing_period">{{ __('Billing Period') }} <i
                                                     data-toggle="popover" data-trigger="hover"
-                                                    data-content="{{__('Period when the user will be charged for the given price')}}"
+                                                    data-content="{{ __('Period when the user will be charged for the given price') }}"
                                                     class="fas fa-info-circle"></i></label>
 
-                                            <select id="billing_period" style="width:100%" class="custom-select" name="billing_period" required
-                                                autocomplete="off" @error('billing_period') is-invalid @enderror>
-                                                    <option value="hourly" @if ($product->billing_period == 'hourly') selected
-                                                    @endif>
-                                                        {{__('Hourly')}}
-                                                    </option>
-                                                    <option value="daily" @if ($product->billing_period  == 'daily') selected
-                                                    @endif>
-                                                        {{__('Daily')}}
-                                                    </option>
-                                                    <option value="weekly" @if ($product->billing_period  == 'weekly') selected
-                                                    @endif>
-                                                        {{__('Weekly')}}
-                                                    </option>
-                                                     <option value="monthly" @if ($product->billing_period  == 'monthly') selected
-                                                     @endif>
-                                                        {{__('Monthly')}}
-                                                    </option>
-                                                    <option value="quarterly" @if ($product->billing_period  == 'quarterly') selected
-                                                    @endif>
-                                                        {{__('Quarterly')}}
-                                                    </option>
-                                                    <option value="half-annually" @if ($product->billing_period  == 'half-annually') selected
-                                                    @endif>
-                                                        {{__('Half Annually')}}
-                                                    </option>
-                                                    <option value="annually" @if ($product->billing_period  == 'annually') selected
-                                                    @endif>
-                                                        {{__('Annually')}}
-                                                    </option>
+                                            <select id="billing_period" style="width:100%" class="custom-select"
+                                                name="billing_period" required autocomplete="off"
+                                                @error('billing_period') is-invalid @enderror>
+                                                <option value="hourly" @if ($product->billing_period == 'hourly') selected @endif>
+                                                    {{ __('Hourly') }}
+                                                </option>
+                                                <option value="daily" @if ($product->billing_period == 'daily') selected @endif>
+                                                    {{ __('Daily') }}
+                                                </option>
+                                                <option value="weekly" @if ($product->billing_period == 'weekly') selected @endif>
+                                                    {{ __('Weekly') }}
+                                                </option>
+                                                <option value="monthly" @if ($product->billing_period == 'monthly') selected @endif>
+                                                    {{ __('Monthly') }}
+                                                </option>
+                                                <option value="quarterly"
+                                                    @if ($product->billing_period == 'quarterly') selected @endif>
+                                                    {{ __('Quarterly') }}
+                                                </option>
+                                                <option value="half-annually"
+                                                    @if ($product->billing_period == 'half-annually') selected @endif>
+                                                    {{ __('Half Annually') }}
+                                                </option>
+                                                <option value="annually"
+                                                    @if ($product->billing_period == 'annually') selected @endif>
+                                                    {{ __('Annually') }}
+                                                </option>
                                             </select>
                                             @error('billing_period')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
 
                                         <div class="form-group">
-                                            <label for="minimum_credits">{{__('Minimum')}} {{ $credits_display_name }} <i
-                                                    data-toggle="popover" data-trigger="hover"
-                                                    data-content="{{__('Setting to -1 will use the value from configuration.')}}"
+                                            <label for="minimum_credits">{{ __('Minimum') }} {{ $credits_display_name }}
+                                                <i data-toggle="popover" data-trigger="hover"
+                                                    data-content="{{ __('Setting to -1 will use the value from configuration.') }}"
                                                     class="fas fa-info-circle"></i></label>
                                             <input value="{{ $product->minimum_credits }}" id="minimum_credits"
-                                                   name="minimum_credits" type="number"
-                                                   class="form-control @error('minimum_credits') is-invalid @enderror"
-                                                   required="required">
+                                                name="minimum_credits" type="number"
+                                                class="form-control @error('minimum_credits') is-invalid @enderror"
+                                                required="required">
                                             @error('minimum_credits')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="io">{{__('IO')}}</label>
-                                            <input value="{{ $product->io }}" id="io" name="io" type="number"
-                                                   class="form-control @error('io') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="io">{{ __('IO') }}</label>
+                                            <input value="{{ $product->io }}" id="io" name="io"
+                                                type="number" class="form-control @error('io') is-invalid @enderror"
+                                                required="required">
                                             @error('io')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="databases">{{__('Databases')}}</label>
+                                            <label for="databases">{{ __('Databases') }}</label>
                                             <input value="{{ $product->databases }}" id="databases" name="databases"
-                                                   type="number"
-                                                   class="form-control @error('databases') is-invalid @enderror"
-                                                   required="required">
+                                                type="number"
+                                                class="form-control @error('databases') is-invalid @enderror"
+                                                required="required">
                                             @error('databases')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                         <div class="form-group">
-                                            <label for="backups">{{__('Backups')}}</label>
+                                            <label for="backups">{{ __('Backups') }}</label>
                                             <input value="{{ $product->backups }}" id="backups" name="backups"
-                                                   type="number"
-                                                   class="form-control @error('backups') is-invalid @enderror"
-                                                   required="required">
+                                                type="number"
+                                                class="form-control @error('backups') is-invalid @enderror"
+                                                required="required">
                                             @error('backups')
-                                            <div class="invalid-feedback">
-                                                {{ $message }}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                         </div>
                                     </div>
@@ -275,7 +271,7 @@ class="form-control @error('backups') is-invalid @enderror"
 
                                 <div class="form-group text-right">
                                     <button type="submit" class="btn btn-primary">
-                                        {{__('Submit')}}
+                                        {{ __('Submit') }}
                                     </button>
                                 </div>
 
@@ -286,59 +282,59 @@ class="form-control @error('backups') is-invalid @enderror"
                     <div class="col-lg-6">
                         <div class="card">
                             <div class="card-header">
-                                <h5 class="card-title">{{__('Product Linking')}}
-                                    <i data-toggle="popover"
-                                       data-trigger="hover"
-                                       data-content="{{__('Link your products to nodes and eggs to create dynamic pricing for each option')}}"
-                                       class="fas fa-info-circle"></i></h5>
+                                <h5 class="card-title">{{ __('Product Linking') }}
+                                    <i data-toggle="popover" data-trigger="hover"
+                                        data-content="{{ __('Link your products to nodes and eggs to create dynamic pricing for each option') }}"
+                                        class="fas fa-info-circle"></i>
+                                </h5>
                             </div>
                             <div class="card-body">
 
                                 <div class="form-group">
-                                    <label for="nodes">{{__('Nodes')}}</label>
+                                    <label for="nodes">{{ __('Nodes') }}</label>
                                     <select id="nodes" style="width:100%"
-                                            class="custom-select @error('nodes') is-invalid @enderror" name="nodes[]"
-                                            multiple="multiple" autocomplete="off">
-                                        @foreach($locations as $location)
-                                            <optgroup label="{{$location->name}}">
-                                                @foreach($location->nodes as $node)
-                                                    <option @if($product->nodes->contains('id' , $node->id)) selected
-                                                            @endif value="{{$node->id}}">{{$node->name}}</option>
+                                        class="custom-select @error('nodes') is-invalid @enderror" name="nodes[]"
+                                        multiple="multiple" autocomplete="off">
+                                        @foreach ($locations as $location)
+                                            <optgroup label="{{ $location->name }}">
+                                                @foreach ($location->nodes as $node)
+                                                    <option @if ($product->nodes->contains('id', $node->id)) selected @endif
+                                                        value="{{ $node->id }}">{{ $node->name }}</option>
                                                 @endforeach
                                             </optgroup>
                                         @endforeach
                                     </select>
                                     @error('nodes')
-                                    <div class="text-danger">
-                                        {{$message}}
-                                    </div>
+                                        <div class="text-danger">
+                                            {{ $message }}
+                                        </div>
                                     @enderror
                                     <div class="text-muted">
-                                        {{__('This product will only be available for these nodes')}}
+                                        {{ __('This product will only be available for these nodes') }}
                                     </div>
                                 </div>
 
                                 <div class="form-group">
                                     <label for="eggs">Eggs</label>
                                     <select id="eggs" style="width:100%"
-                                            class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
-                                            multiple="multiple" autocomplete="off">
-                                        @foreach($nests as $nest)
-                                            <optgroup label="{{$nest->name}}">
-                                                @foreach($nest->eggs as $egg)
-                                                    <option @if($product->eggs->contains('id' , $egg->id)) selected
-                                                            @endif value="{{$egg->id}}">{{$egg->name}}</option>
+                                        class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
+                                        multiple="multiple" autocomplete="off">
+                                        @foreach ($nests as $nest)
+                                            <optgroup label="{{ $nest->name }}">
+                                                @foreach ($nest->eggs as $egg)
+                                                    <option @if ($product->eggs->contains('id', $egg->id)) selected @endif
+                                                        value="{{ $egg->id }}">{{ $egg->name }}</option>
                                                 @endforeach
                                             </optgroup>
                                         @endforeach
                                     </select>
                                     @error('eggs')
-                                    <div class="text-danger">
-                                        {{$message}}
-                                    </div>
+                                        <div class="text-danger">
+                                            {{ $message }}
+                                        </div>
                                     @enderror
                                     <div class="text-muted">
-                                        {{__('This product will only be available for these eggs')}}
+                                        {{ __('This product will only be available for these eggs') }}
                                     </div>
                                 </div>
 
@@ -358,9 +354,8 @@ class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
         })
     </script>
     <script>
-        document.addEventListener('DOMContentLoaded', function () {
+        document.addEventListener('DOMContentLoaded', function() {
             $('[data-toggle="popover"]').popover();
         });
     </script>
-
 @endsection

From 67cbde2fa1f6e57894d30e9f9dd040829ac06c3d Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 21:32:04 +0200
Subject: [PATCH 173/514] ticket category permissions

---
 app/Http/Controllers/Admin/TicketCategoryController.php | 4 ++--
 config/permissions_web.php                              | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/TicketCategoryController.php b/app/Http/Controllers/Admin/TicketCategoryController.php
index 74fff87a7..3d4d8e879 100644
--- a/app/Http/Controllers/Admin/TicketCategoryController.php
+++ b/app/Http/Controllers/Admin/TicketCategoryController.php
@@ -9,8 +9,8 @@
 
 class TicketCategoryController extends Controller
 {
-    const READ_PERMISSION = "admin.tickets.read";
-    const WRITE_PERMISSION = "admin.tickets.write";
+    const READ_PERMISSION = "admin.tickets.category.read";
+    const WRITE_PERMISSION = "admin.tickets.category.write";
     /**
      *
      * Display a listing of the resource.
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 0ae789ca7..1c3828f70 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -17,6 +17,9 @@
     'admin.tickets.write',
     'admin.tickets.get_notification',
 
+    'admin.tickets.category.read',
+    'admin.tickets.category.write',
+
     'admin.ticket_blacklist.read',
     'admin.ticket_blacklist.write',
 

From f37b78d7502eebc52f5cc361beccf29790b0fb90 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 21:32:04 +0200
Subject: [PATCH 174/514] ticket category permissions

---
 app/Http/Controllers/Admin/TicketCategoryController.php | 4 ++--
 config/permissions_web.php                              | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/TicketCategoryController.php b/app/Http/Controllers/Admin/TicketCategoryController.php
index 74fff87a7..3d4d8e879 100644
--- a/app/Http/Controllers/Admin/TicketCategoryController.php
+++ b/app/Http/Controllers/Admin/TicketCategoryController.php
@@ -9,8 +9,8 @@
 
 class TicketCategoryController extends Controller
 {
-    const READ_PERMISSION = "admin.tickets.read";
-    const WRITE_PERMISSION = "admin.tickets.write";
+    const READ_PERMISSION = "admin.tickets.category.read";
+    const WRITE_PERMISSION = "admin.tickets.category.write";
     /**
      *
      * Display a listing of the resource.
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 0ae789ca7..1c3828f70 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -17,6 +17,9 @@
     'admin.tickets.write',
     'admin.tickets.get_notification',
 
+    'admin.tickets.category.read',
+    'admin.tickets.category.write',
+
     'admin.ticket_blacklist.read',
     'admin.ticket_blacklist.write',
 

From 2c9b933c6d0942888e74205b6593f2cc5e25fc34 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 21:36:59 +0200
Subject: [PATCH 175/514] fix server upgrade

---
 app/Http/Controllers/ServerController.php | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 6324f870e..d6c344f5f 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -389,13 +389,6 @@ public function upgrade(Server $server, Request $request)
             $server->allocation = $serverAttributes['allocation'];
             $response = $this->pterodactyl->updateServer($server, $newProduct);
             if ($response->failed()) return redirect()->route('servers.index')->with('error', __("The system was unable to update your server product. Please try again later or contact support."));
-            //update user balance
-            $user->decrement('credits', $priceupgrade);
-            //restart the server
-            $response = $this->pterodactyl->powerAction($server, 'restart');
-            if ($response->failed()) {
-                return redirect()->route('servers.index')->with('error', $response->json()['errors'][0]['detail']);
-            }
 
             // Remove the allocation property from the server object as it is not a column in the database
             unset($server->allocation);
@@ -414,7 +407,7 @@ public function upgrade(Server $server, Request $request)
             $user->decrement('credits', $newProduct->price);
 
             //restart the server
-            $response = Pterodactyl::powerAction($server, "restart");
+            $response = $this->pterodactyl->powerAction($server, 'restart');
             if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   ' . $response->json()['errors'][0]['detail']);
             return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
         } else {

From 2b0321733e9029ef5c5a01412ec7b08b42eb24a9 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 21:36:59 +0200
Subject: [PATCH 176/514] fix server upgrade

---
 app/Http/Controllers/ServerController.php | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 6324f870e..d6c344f5f 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -389,13 +389,6 @@ public function upgrade(Server $server, Request $request)
             $server->allocation = $serverAttributes['allocation'];
             $response = $this->pterodactyl->updateServer($server, $newProduct);
             if ($response->failed()) return redirect()->route('servers.index')->with('error', __("The system was unable to update your server product. Please try again later or contact support."));
-            //update user balance
-            $user->decrement('credits', $priceupgrade);
-            //restart the server
-            $response = $this->pterodactyl->powerAction($server, 'restart');
-            if ($response->failed()) {
-                return redirect()->route('servers.index')->with('error', $response->json()['errors'][0]['detail']);
-            }
 
             // Remove the allocation property from the server object as it is not a column in the database
             unset($server->allocation);
@@ -414,7 +407,7 @@ public function upgrade(Server $server, Request $request)
             $user->decrement('credits', $newProduct->price);
 
             //restart the server
-            $response = Pterodactyl::powerAction($server, "restart");
+            $response = $this->pterodactyl->powerAction($server, 'restart');
             if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   ' . $response->json()['errors'][0]['detail']);
             return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
         } else {

From fd1ce85723bdf36852021262d307ccc835ffbb03 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 21:47:34 +0200
Subject: [PATCH 177/514] remove OOM killer from product info

---
 themes/default/views/servers/create.blade.php | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index fbc15466d..5b8a3f3c3 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -201,12 +201,6 @@ class="custom-select">
                                                         {{ __('Databases') }}</span>
                                                     <span class="d-inline-block" x-text="product.databases"></span>
                                                 </li>
-                                                <li class="d-flex justify-content-between">
-                                                    <span class="d-inline-block"><i class="fas fa-skull-crossbones"></i>
-                                                        {{ __('OOM Killer') }}</span>
-                                                    <span class="d-inline-block"
-                                                          x-text="product.oom_killer == 1 ? 'enabled' : 'disabled'"></span>
-                                                </li>
                                                 <li class="d-flex justify-content-between">
                                                     <span class="d-inline-block"><i class="fas fa-network-wired"></i>
                                                         {{ __('Allocations') }}

From dd962a0afbc7014e8efd5addabb1877d768cc99b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 21:58:05 +0200
Subject: [PATCH 178/514] fix admin overview total credits counter

---
 app/Http/Controllers/Admin/OverViewController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/OverViewController.php b/app/Http/Controllers/Admin/OverViewController.php
index 90cd9307a..f3d883e87 100644
--- a/app/Http/Controllers/Admin/OverViewController.php
+++ b/app/Http/Controllers/Admin/OverViewController.php
@@ -38,7 +38,7 @@ public function index(GeneralSettings $general_settings)
         $counters = collect();
         //Set basic variables in the collection
         $counters->put('users', User::query()->count());
-        $counters->put('credits', number_format(User::query()->where('role', '!=', 'admin')->sum('credits'), 2, '.', ''));
+        $counters->put('credits', number_format(User::query()->whereHas("roles", function($q){ $q->where("id", "!=", "1"); })->sum('credits'), 2, '.', ''));
         $counters->put('payments', Payment::query()->count());
         $counters->put('eggs', Egg::query()->count());
         $counters->put('nests', Nest::query()->count());

From 680ffefb1e3cd785f49f938e076ed03ba2cc6bb9 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 16 May 2023 22:03:52 +0200
Subject: [PATCH 179/514] fix server upgrade while installation

---
 app/Http/Controllers/ServerController.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index d6c344f5f..9a00ee1bc 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -389,6 +389,9 @@ public function upgrade(Server $server, Request $request)
             $server->allocation = $serverAttributes['allocation'];
             $response = $this->pterodactyl->updateServer($server, $newProduct);
             if ($response->failed()) return redirect()->route('servers.index')->with('error', __("The system was unable to update your server product. Please try again later or contact support."));
+            //restart the server
+            $response = $this->pterodactyl->powerAction($server, 'restart');
+            if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Upgrade Failed! Could not restart the server:   ' . $response->json()['errors'][0]['detail']);
 
             // Remove the allocation property from the server object as it is not a column in the database
             unset($server->allocation);
@@ -406,9 +409,6 @@ public function upgrade(Server $server, Request $request)
             // Withdraw the credits for the new product
             $user->decrement('credits', $newProduct->price);
 
-            //restart the server
-            $response = $this->pterodactyl->powerAction($server, 'restart');
-            if ($response->failed()) return redirect()->route('servers.index')->with('error', 'Server upgraded successfully! Could not restart the server:   ' . $response->json()['errors'][0]['detail']);
             return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
         } else {
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('Not Enough Balance for Upgrade'));

From 33b402bdeecf31cda7f3b2099378385a09e2ea36 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 17 May 2023 09:15:46 +0200
Subject: [PATCH 180/514] add select 2 to roles-permissions

---
 themes/default/views/admin/roles/edit.blade.php | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/themes/default/views/admin/roles/edit.blade.php b/themes/default/views/admin/roles/edit.blade.php
index 453233f67..91fef77df 100644
--- a/themes/default/views/admin/roles/edit.blade.php
+++ b/themes/default/views/admin/roles/edit.blade.php
@@ -58,4 +58,11 @@
         </div>
 
     </div>
+
+    <script>
+        document.addEventListener('DOMContentLoaded', (event) => {
+            $('#permissions').select2();
+        })
+    </script>
 @endsection
+

From 9da53bd02f6a2214cf8acea48ba02734cb08955d Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 17 May 2023 09:44:19 +0200
Subject: [PATCH 181/514] Monthly calculation on server index

---
 app/Models/Product.php                       | 22 ++++++++++++++++++--
 themes/default/views/servers/index.blade.php |  7 +++++--
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/app/Models/Product.php b/app/Models/Product.php
index 200e9ef8f..f8b5936b3 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -64,9 +64,27 @@ public function getHourlyPrice()
         }
     }
 
-    public function getDailyPrice()
+    public function getMonthlyPrice()
     {
-        return $this->price / 30;
+        // calculate the hourly price with the billing period
+        switch($this->billing_period) {
+            case 'hourly':
+                return $this->price * 24 * 30;
+            case 'daily':
+                return $this->price * 30;
+            case 'weekly':
+                return $this->price * 4;
+            case 'monthly':
+                return $this->price;
+            case 'quarterly':
+                return $this->price / 3;
+            case 'half-annually':
+                return $this->price / 6;
+            case 'annually':
+                return $this->price / 12;
+            default:
+                return $this->price;
+        }
     }
 
     public function getWeeklyPrice()
diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index dd417eac2..09858c676 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -62,8 +62,8 @@ class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span>
                                         </a>
                                         <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
                                             aria-labelledby="dropdownMenuLink">
-                                            @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
-                                                <a href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
+                                            @if (!empty($phpmyadmin_url)))
+                                                <a href="{{ $phpmyadmin_url }}"
                                                     class="dropdown-item text-info" target="__blank"><i title="manage"
                                                         class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
                                             @endif
@@ -194,6 +194,9 @@ class="fas fa-info-circle"></i>
                                         @elseif($server->product->billing_period == 'hourly')
                                             {{ __('per Hour') }}
                                         @endif
+                                            <i data-toggle="popover" data-trigger="hover"
+                                               data-content="{{ __('Your') ." " . $credits_display_name . " ". __('are reduced') ." ". $server->product->billing_period . ". " . __("This however calculates to ") . number_format($server->product->getMonthlyPrice(),2,",",".") . " ". $credits_display_name . " ". __('per Month')}}"
+                                               class="fas fa-info-circle"></i>
                                             </div>
                                         <span>
                                             {{ $server->product->price == round($server->product->price) ? round($server->product->price) : $server->product->price }}

From da29ead3cd0d274c5f217cfe8b7910db874694bf Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 17 May 2023 09:49:51 +0200
Subject: [PATCH 182/514] fix overview credit erarnings

---
 app/Http/Controllers/Admin/OverViewController.php   | 3 ++-
 themes/default/views/admin/overview/index.blade.php | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/OverViewController.php b/app/Http/Controllers/Admin/OverViewController.php
index f3d883e87..866d8ece3 100644
--- a/app/Http/Controllers/Admin/OverViewController.php
+++ b/app/Http/Controllers/Admin/OverViewController.php
@@ -173,7 +173,8 @@ public function index(GeneralSettings $general_settings)
             $nodeId = $server['attributes']['node'];
 
             if ($CPServer = Server::query()->where('pterodactyl_id', $server['attributes']['id'])->first()) {
-                $price = Product::query()->where('id', $CPServer->product_id)->first()->price;
+                $product = Product::query()->where('id', $CPServer->product_id)->first();
+                $price = $product->getMonthlyPrice();
                 if (! $CPServer->suspended) {
                     $counters['earnings']->active += $price;
                     $counters['servers']->active++;
diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index 1e54c6f6a..6b5bd4112 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -240,7 +240,7 @@ class="fas fa-sync mr-2"></i>{{__('Sync servers')}}</a>
                                     <th>{{__('Node')}}</th>
                                     <th>{{__('Server count')}}</th>
                                     <th>{{__('Resource usage')}}</th>
-                                    <th>{{ $credits_display_name . ' ' . __('Usage')}}</th>
+                                    <th>{{ $credits_display_name . ' ' . __('Usage') ." (".__('per month').")"}}</th>
                                 </tr>
                                 </thead>
                                 <tbody>

From b97bc8edf78e672412522d2acfee07edf49363f3 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 4 Jun 2023 15:41:51 +0200
Subject: [PATCH 183/514] =?UTF-8?q?fix:=20=F0=9F=9A=9A=20Move=20and=20remo?=
 =?UTF-8?q?ve=20some=20settings?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Settings/InvoiceSettings.php                         | 2 +-
 app/Settings/MailSettings.php                            | 6 ------
 app/Settings/ServerSettings.php                          | 7 -------
 app/Settings/UserSettings.php                            | 4 ++--
 .../2022_01_05_144858_rename_configurations_table.php    | 2 --
 .../settings/2023_02_01_181453_create_mail_settings.php  | 9 +--------
 .../2023_02_01_181950_create_server_settings.php         | 8 --------
 7 files changed, 4 insertions(+), 34 deletions(-)

diff --git a/app/Settings/InvoiceSettings.php b/app/Settings/InvoiceSettings.php
index c7b0068bf..62ba6f1e3 100644
--- a/app/Settings/InvoiceSettings.php
+++ b/app/Settings/InvoiceSettings.php
@@ -6,13 +6,13 @@
 
 class InvoiceSettings extends Settings
 {
+    public bool $enabled;
     public ?string $company_address;
     public ?string $company_mail;
     public ?string $company_name;
     public ?string $company_phone;
     public ?string $company_vat;
     public ?string $company_website;
-    public bool $enabled;
     public ?string $prefix;
 
     public static function group(): string
diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php
index 8b37f632f..1ea8309da 100644
--- a/app/Settings/MailSettings.php
+++ b/app/Settings/MailSettings.php
@@ -14,7 +14,6 @@ class MailSettings extends Settings
     public ?string $mail_from_address;
     public ?string $mail_from_name;
     public ?string $mail_mailer;
-    public bool $mail_enabled;
 
     public static function group(): string
     {
@@ -52,7 +51,6 @@ public static function getValidations()
             'mail_from_address' => 'nullable|string',
             'mail_from_name' => 'nullable|string',
             'mail_mailer' => 'nullable|string',
-            'mail_enabled' => 'nullable|string',
         ];
     }
 
@@ -105,10 +103,6 @@ public static function getOptionInputData()
                 'type' => 'string',
                 'description' => 'The mailer of your mail server.',
             ],
-            'mail_enabled' => [
-                'label' => 'Mail Enabled',
-                'type' => 'boolean',
-            ],
         ];
     }
 }
diff --git a/app/Settings/ServerSettings.php b/app/Settings/ServerSettings.php
index f56418765..3043066ad 100644
--- a/app/Settings/ServerSettings.php
+++ b/app/Settings/ServerSettings.php
@@ -9,7 +9,6 @@ class ServerSettings extends Settings
     public int $allocation_limit;
     public bool $creation_enabled;
     public bool $enable_upgrade;
-    public bool $charge_first_hour;
 
     public static function group(): string
     {
@@ -26,7 +25,6 @@ public static function getValidations()
             'allocation_limit' => 'required|integer|min:0',
             'creation_enabled' => 'nullable|string',
             'enable_upgrade' => 'nullable|string',
-            'charge_first_hour' => 'nullable|string',
         ];
     }
 
@@ -54,11 +52,6 @@ public static function getOptionInputData()
                 'type' => 'boolean',
                 'description' => 'Whether or not users can upgrade their servers.',
             ],
-            'charge_first_hour' => [
-                'label' => 'Charge First Hour',
-                'type' => 'boolean',
-                'description' => 'Whether or not the first hour of a server is charged.',
-            ],
         ];
     }
 }
diff --git a/app/Settings/UserSettings.php b/app/Settings/UserSettings.php
index 5c1b65dba..df85053eb 100644
--- a/app/Settings/UserSettings.php
+++ b/app/Settings/UserSettings.php
@@ -6,6 +6,8 @@
 
 class UserSettings extends Settings
 {
+    public bool $register_ip_check;
+    public bool $creation_enabled;
     public float $credits_reward_after_verify_discord;
     public float $credits_reward_after_verify_email;
     public bool $force_discord_verification;
@@ -16,8 +18,6 @@ class UserSettings extends Settings
     public int $server_limit_after_irl_purchase;
     public int $server_limit_after_verify_discord;
     public int $server_limit_after_verify_email;
-    public bool $register_ip_check;
-    public bool $creation_enabled;
 
     public static function group(): string
     {
diff --git a/database/migrations/2022_01_05_144858_rename_configurations_table.php b/database/migrations/2022_01_05_144858_rename_configurations_table.php
index 4785ed01e..1090a0223 100644
--- a/database/migrations/2022_01_05_144858_rename_configurations_table.php
+++ b/database/migrations/2022_01_05_144858_rename_configurations_table.php
@@ -28,7 +28,6 @@ public function up()
         DB::table('settings')->where('key', 'REGISTER_IP_CHECK')->update(['key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK']);
         DB::table('settings')->where('key', 'CREDITS_DISPLAY_NAME')->update(['key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME']);
         DB::table('settings')->where('key', 'ALLOCATION_LIMIT')->update(['key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT']);
-        DB::table('settings')->where('key', 'SERVER_CREATE_CHARGE_FIRST_HOUR')->update(['key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR']);
         DB::table('settings')->where('key', 'SALES_TAX')->update(['key' => 'SETTINGS::PAYMENTS:SALES_TAX']);
     }
 
@@ -52,7 +51,6 @@ public function down()
         DB::table('configurations')->where('key', 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION')->update(['key' => 'FORCE_EMAIL_VERIFICATION']);
         DB::table('configurations')->where('key', 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION')->update(['key' => 'FORCE_DISCORD_VERIFICATION']);
         DB::table('configurations')->where('key', 'SETTINGS::SYSTEM:REGISTER_IP_CHECK')->update(['key' => 'REGISTER_IP_CHECK']);
-        DB::table('configurations')->where('key', 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR')->update(['key' => 'SERVER_CREATE_CHARGE_FIRST_HOUR']);
         DB::table('configurations')->where('key', 'SETTINGS::SERVER:ALLOCATION_LIMIT')->update(['key' => 'ALLOCATION_LIMIT']);
         DB::table('configurations')->where('key', 'SETTINGS::SERVER:CREDITS_DISPLAY_NAME')->update(['key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME']);
         DB::table('configurations')->where('key', 'SETTINGS::PAYMENTS:SALES_TAX')->update(['key' => 'SALES_TAX']);
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index cc609b44a..56953b780 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -18,7 +18,6 @@ public function up(): void
         $this->migrator->add('mail.mail_from_address', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_ADDRESS') : env('MAIL_FROM_ADDRESS', 'example@example.com'));
         $this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'CtrlPanel.gg'));
         $this->migrator->add('mail.mail_mailer', $table_exists ? $this->getOldValue('SETTINGS::MAIL:MAILER') : env('MAIL_MAILER', 'smtp'));
-        $this->migrator->add('mail.mail_enabled', true);
     }
 
     public function down(): void
@@ -72,12 +71,7 @@ public function down(): void
                 'type' => 'string',
                 'description' => 'The mailer of the mail server.',
             ],
-            [
-                'key' => 'SETTINGS::MAIL:ENABLED',
-                'value' => $this->getNewValue('mail_enabled'),
-                'type' => 'boolean',
-                'description' => 'The enabled state of the mail server.',
-            ],
+
         ]);
 
         $this->migrator->delete('mail.mail_host');
@@ -88,7 +82,6 @@ public function down(): void
         $this->migrator->delete('mail.mail_from_address');
         $this->migrator->delete('mail.mail_from_name');
         $this->migrator->delete('mail.mail_mailer');
-        $this->migrator->delete('mail.mail_enabled');
     }
 
 
diff --git a/database/settings/2023_02_01_181950_create_server_settings.php b/database/settings/2023_02_01_181950_create_server_settings.php
index 8f9c38124..7198adcb6 100644
--- a/database/settings/2023_02_01_181950_create_server_settings.php
+++ b/database/settings/2023_02_01_181950_create_server_settings.php
@@ -13,7 +13,6 @@ public function up(): void
         $this->migrator->add('server.allocation_limit', $table_exists ? $this->getOldValue('SETTINGS::SERVER:ALLOCATION_LIMIT') : 200);
         $this->migrator->add('server.creation_enabled', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS') : true);
         $this->migrator->add('server.enable_upgrade', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:ENABLE_UPGRADE') : false);
-        $this->migrator->add('server.charge_first_hour', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR') : false);
     }
 
     public function down(): void
@@ -37,18 +36,11 @@ public function down(): void
                 'type' => 'boolean',
                 'description' => 'Whether or not users can upgrade their servers.',
             ],
-            [
-                'key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR',
-                'value' => $this->getNewValue('charge_first_hour'),
-                'type' => 'boolean',
-                'description' => 'Whether or not to charge the user for the first hour of their server.',
-            ],
         ]);
 
         $this->migrator->delete('server.allocation_limit');
         $this->migrator->delete('server.creation_enabled');
         $this->migrator->delete('server.enable_upgrade');
-        $this->migrator->delete('server.charge_first_hour');
     }
 
     public function getNewValue(string $name)

From 83e153058cf69a28fa478c092c2563e6342dd87d Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 4 Jun 2023 16:08:22 +0200
Subject: [PATCH 184/514] =?UTF-8?q?fix:=20=F0=9F=90=9Blocale=20default=20l?=
 =?UTF-8?q?anguage=20selection?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Controllers/Admin/SettingsController.php  |   5 +-
 app/Settings/LocaleSettings.php               |   1 +
 .../views/admin/settings/index.blade.php      | 227 +++++++++---------
 3 files changed, 114 insertions(+), 119 deletions(-)

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 47cc4207d..988603220 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -64,6 +64,7 @@ public function index()
                     'type' => $optionInputData[$key]['type'] ?? 'string',
                     'description' => $optionInputData[$key]['description'] ?? '',
                     'options' => $optionInputData[$key]['options'] ?? [],
+                    'identifier' => $optionInputData[$key]['identifier'] ?? 'option'
                 ];
             }
 
@@ -96,7 +97,7 @@ public function update(Request $request)
     {
         $category = request()->get('category');
 
-        $this->checkPermission("settings.".strtolower($category).".write");
+        $this->checkPermission("settings." . strtolower($category) . ".write");
 
         $settings_class = request()->get('settings_class');
 
@@ -125,7 +126,7 @@ public function update(Request $request)
                 continue;
             }
             if ($rp->name == 'available') {
-                $settingsClass->$key = implode(",",$request->$key);
+                $settingsClass->$key = implode(",", $request->$key);
                 continue;
             }
 
diff --git a/app/Settings/LocaleSettings.php b/app/Settings/LocaleSettings.php
index 61934bc17..81cf2b642 100644
--- a/app/Settings/LocaleSettings.php
+++ b/app/Settings/LocaleSettings.php
@@ -62,6 +62,7 @@ public static function getOptionInputData()
                 'type' => 'select',
                 'description' => 'The default locale to use.',
                 'options' => config('app.available_locales'),
+                'identifier' => 'display'
             ],
             'dynamic' => [
                 'label' => 'Dynamic Locale',
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 006e1f4cb..65d552e88 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -12,7 +12,7 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a>
+                                href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -48,24 +48,21 @@
                                 <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                     data-accordion="false">
                                     <li class="nav-item border-bottom-0">
-                                        <a href="#icons"
-                                           class="nav-link" data-toggle="pill"
-                                           role="tab">
-                                            <i
-                                                class="nav-icon fas fa-image"></i>
+                                        <a href="#icons" class="nav-link" data-toggle="pill" role="tab">
+                                            <i class="nav-icon fas fa-image"></i>
                                             <p>
-                                                {{ __("Images / Icons") }}
+                                                {{ __('Images / Icons') }}
                                             </p>
                                         </a>
                                     </li>
                                     @foreach ($settings as $category => $options)
-                                        @if(!str_contains($options['settings_class'],"Extension"))
-                                            @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
+                                        @if (!str_contains($options['settings_class'], 'Extension'))
+                                            @canany(['settings.' . strtolower($category) . '.read', 'settings.' .
+                                                strtolower($category) . '.write'])
                                                 <li class="nav-item border-bottom-0">
                                                     <a href="#{{ $category }}"
-                                                       class="nav-link {{ $loop->first ? 'active' : '' }}"
-                                                       data-toggle="pill"
-                                                       role="tab">
+                                                        class="nav-link {{ $loop->first ? 'active' : '' }}" data-toggle="pill"
+                                                        role="tab">
                                                         <i
                                                             class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                                         <p>
@@ -79,35 +76,34 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                 </ul>
 
 
-                                    <button class="btn btn-outline-secondary" type="button" data-toggle="collapse"
-                                            data-target="#collapseExtensions" aria-expanded="false"
-                                            aria-controls="collapseExtensions">
-                                        {{__("Extension Settings")}}
-                                    </button>
+                                <button class="btn btn-outline-secondary" type="button" data-toggle="collapse"
+                                    data-target="#collapseExtensions" aria-expanded="false"
+                                    aria-controls="collapseExtensions">
+                                    {{ __('Extension Settings') }}
+                                </button>
 
 
-                                    <div class="collapse" id="collapseExtensions">
-                                        <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
-                                            data-accordion="false">
+                                <div class="collapse" id="collapseExtensions">
+                                    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
+                                        data-accordion="false">
                                         @foreach ($settings as $category => $options)
-                                            @if(str_contains($options['settings_class'],"Extension"))
-
-                                                @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
-                                                        <li class="nav-item border-bottom-0">
-                                                            <a href="#{{ $category }}"
-                                                               class="nav-link"
-                                                               data-toggle="pill"
-                                                               role="tab">
-                                                                <i class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
-                                                                <p>
-                                                                    {{ $category }}
-                                                                </p>
-                                                            </a>
-                                                        </li>
+                                            @if (str_contains($options['settings_class'], 'Extension'))
+                                                @canany(['settings.' . strtolower($category) . '.read', 'settings.' .
+                                                    strtolower($category) . '.write'])
+                                                    <li class="nav-item border-bottom-0">
+                                                        <a href="#{{ $category }}" class="nav-link" data-toggle="pill"
+                                                            role="tab">
+                                                            <i
+                                                                class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
+                                                            <p>
+                                                                {{ $category }}
+                                                            </p>
+                                                        </a>
+                                                    </li>
                                                 @endcanany
                                             @endif
                                         @endforeach
-                                    </div>
+                                </div>
                                 </ul>
                             </nav>
                         </div>
@@ -115,50 +111,44 @@ class="nav-link"
                         <!-- Content in $settings -->
                         <div class="col-10 p-0">
                             <div class="tab-content ml-3" style="width: 100%;">
-                                <div container class="tab-pane fade container"
-                                     id="icons" role="tabpanel">
+                                <div container class="tab-pane fade container" id="icons" role="tabpanel">
 
                                     <form method="POST" enctype="multipart/form-data" class="mb-3"
-                                          action="{{ route('admin.settings.updateIcons') }}">
+                                        action="{{ route('admin.settings.updateIcons') }}">
                                         @csrf
                                         @method('POST')
                                         <div class="row">
                                             <div class="card ml-5" style="width: 18rem;">
-                                                <span class="h3 text-center">{{__("FavIcon")}} </span>
+                                                <span class="h3 text-center">{{ __('FavIcon') }} </span>
                                                 <div class="card-body">
 
                                                 </div>
                                                 <input type="file" accept="image/x-icon" class="form-control"
-                                                       name="favicon"
-                                                       id="favicon">
+                                                    name="favicon" id="favicon">
                                             </div>
 
                                             <div class="card ml-5" style="width: 18rem;">
-                                                <span class="h3 text-center">{{__("Icon")}} </span>
-                                                <img
-                                                    src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
+                                                <span class="h3 text-center">{{ __('Icon') }} </span>
+                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
                                                     style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                     class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
                                                 <input type="file" accept="image/png,image/jpeg,image/jpg"
-                                                       class="form-control"
-                                                       name="icon" id="icon">
+                                                    class="form-control" name="icon" id="icon">
                                             </div>
 
                                             <div class="card ml-5" style="width: 18rem;">
-                                                <span class="h3 text-center">{{__("Login-page Logo")}} </span>
-                                                <img
-                                                    src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
+                                                <span class="h3 text-center">{{ __('Login-page Logo') }} </span>
+                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
                                                     style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                     class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
                                                 <input type="file" accept="image/png,image/jpeg,image/jpg"
-                                                       class="form-control"
-                                                       name="logo" id="logo">
+                                                    class="form-control" name="logo" id="logo">
                                             </div>
                                         </div>
                                         <div class="row">
@@ -167,16 +157,16 @@ class="form-control"
                                     </form>
                                 </div>
                                 @foreach ($settings as $category => $options)
-                                    @canany(["settings.".strtolower($category).".read","settings.".strtolower($category).".write"])
-                                        <div
-                                             class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
-                                             id="{{ $category }}" role="tabpanel">
+                                    @canany(['settings.' . strtolower($category) . '.read', 'settings.' .
+                                        strtolower($category) . '.write'])
+                                        <div class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
+                                            id="{{ $category }}" role="tabpanel">
 
                                             <form action="{{ route('admin.settings.update') }}" method="POST">
                                                 @csrf
                                                 @method('POST')
                                                 <input type="hidden" name="settings_class"
-                                                       value="{{ $options['settings_class'] }}">
+                                                    value="{{ $options['settings_class'] }}">
                                                 <input type="hidden" name="category" value="{{ $category }}">
 
                                                 @foreach ($options as $key => $value)
@@ -191,11 +181,10 @@ class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
                                                         <div class="col-8">
                                                             <div class="custom-control mb-3 d-flex align-items-center">
                                                                 @if ($value['description'])
-                                                                    <i class="fas fa-info-circle mr-4"
-                                                                       data-toggle="popover"
-                                                                       data-trigger="hover" data-placement="top"
-                                                                       data-html="true"
-                                                                       data-content="{{ $value['description'] }}"></i>
+                                                                    <i class="fas fa-info-circle mr-4" data-toggle="popover"
+                                                                        data-trigger="hover" data-placement="top"
+                                                                        data-html="true"
+                                                                        data-content="{{ $value['description'] }}"></i>
                                                                 @else
                                                                     <i class="fas fa-info-circle mr-4 invisible"></i>
                                                                 @endif
@@ -204,62 +193,68 @@ class="tab-pane fade container {{ $loop->first ? 'active show' : '' }}"
                                                                     @switch($value)
                                                                         @case($value['type'] == 'string')
                                                                             <input type="text" class="form-control"
-                                                                                   name="{{ $key }}"
-                                                                                   value="{{ $value['value'] }}">
-                                                                            @break
+                                                                                name="{{ $key }}"
+                                                                                value="{{ $value['value'] }}">
+                                                                        @break
 
                                                                         @case($value['type'] == 'boolean')
                                                                             <input type="checkbox" name="{{ $key }}"
-                                                                                   value="{{ $value['value'] }}"
+                                                                                value="{{ $value['value'] }}"
                                                                                 {{ $value['value'] ? 'checked' : '' }}>
-                                                                            @break
+                                                                        @break
 
                                                                         @case($value['type'] == 'number')
                                                                             <input type="number" class="form-control"
-                                                                                   name="{{ $key }}"
-                                                                                   value="{{ $value['value'] }}">
-                                                                            @break
+                                                                                name="{{ $key }}"
+                                                                                value="{{ $value['value'] }}">
+                                                                        @break
 
                                                                         @case($value['type'] == 'select')
                                                                             <select id="{{ $key }}"
-                                                                                    class="custom-select w-100"
-                                                                                    name="{{ $key }}">
-
-                                                                                @foreach ($value['options'] as $option=>$display)
-                                                                                    <option value="{{ $option }}"
-                                                                                        {{ $value['value'] == $option ? 'selected' : '' }}>
-                                                                                        {{ __($display) }}
-                                                                                    </option>
-                                                                                @endforeach
+                                                                                class="custom-select w-100"
+                                                                                name="{{ $key }}">
+                                                                                @if ($value['identifier'] == 'display')
+                                                                                    {{ error_log($key . 'True, IAM A DISPLAY') }}
+                                                                                    @foreach ($value['options'] as $option => $display)
+                                                                                        <option value="{{ $display }}"
+                                                                                            {{ $value['value'] == $display ? 'selected' : '' }}>
+                                                                                            {{ __($display) }}
+                                                                                        </option>
+                                                                                    @endforeach
+                                                                                @else
+                                                                                    @foreach ($value['options'] as $option => $display)
+                                                                                        <option value="{{ $option }}"
+                                                                                            {{ $value['value'] == $option ? 'selected' : '' }}>
+                                                                                            {{ __($display) }}
+                                                                                        </option>
+                                                                                    @endforeach
+                                                                                @endif
                                                                             </select>
-                                                                            @break
+                                                                        @break
 
                                                                         @case($value['type'] == 'multiselect')
                                                                             <select id="{{ $key }}"
-                                                                                    class="custom-select w-100"
-                                                                                    name="{{ $key }}[]"
-                                                                                    multiple>
+                                                                                class="custom-select w-100"
+                                                                                name="{{ $key }}[]" multiple>
                                                                                 @foreach ($value['options'] as $option)
                                                                                     <option value="{{ $option }}"
-                                                                                        {{ strpos($value['value'],$option) !== false  ? 'selected' : '' }}>
+                                                                                        {{ strpos($value['value'], $option) !== false ? 'selected' : '' }}>
                                                                                         {{ __($option) }}
                                                                                     </option>
                                                                                 @endforeach
                                                                             </select>
-                                                                            @break
+                                                                        @break
 
                                                                         @case($value['type'] == 'textarea')
-                                                                            <textarea class="form-control"
-                                                                                      name="{{ $key }}"
-                                                                                      rows="3">{{ $value['value'] }}</textarea>
-                                                                            @break
+                                                                            <textarea class="form-control" name="{{ $key }}" rows="3">{{ $value['value'] }}</textarea>
+                                                                        @break
 
                                                                         @default
                                                                     @endswitch
                                                                     @error($key)
-                                                                    <div class="text-danger ">
-                                                                        {{ $message }}
-                                                                    </div>
+                                                                        <div class="text-danger ">
+                                                                            {{ $message }}
+                                                                        </div>
                                                                     @enderror
                                                                 </div>
 
@@ -268,41 +263,39 @@ class="custom-select w-100"
 
                                                         </div>
                                                     </div>
-
                                                 @endforeach
 
                                                 <!-- TODO: Display this only on the General tab
 
-                                            <div class="row">
-                                                <div class="col-4 d-flex align-items-center">
-                                                    <label for="recaptcha_preview">{{__("ReCAPTCHA Preview")}}</label>
-                                                </div>
-
-                                                <div class="col-8">
-
-                                                        <div class="w-100">
-                                                <div class="input-group mb-3">
-                                                    {!! htmlScriptTagJsApi() !!}
-                                                {!! htmlFormSnippet() !!}
-                                                @error('g-recaptcha-response')
-                                                <span class="text-danger" role="alert">
-                                                                            <small><strong>{{ $message }}</strong></small>
-                                                                                </span>
-                                                    @enderror
-                                                </div>
-                                                        </div>
-                                                </div>
-                                            </div>
-                                               -->
+                                                                                                                                                            <div class="row">
+                                                                                                                                                                <div class="col-4 d-flex align-items-center">
+                                                                                                                                                                    <label for="recaptcha_preview">{{ __('ReCAPTCHA Preview') }}</label>
+                                                                                                                                                                </div>
+
+                                                                                                                                                                <div class="col-8">
+
+                                                                                                                                                                        <div class="w-100">
+                                                                                                                                                                <div class="input-group mb-3">
+                                                                                                                                                                    {!! htmlScriptTagJsApi() !!}
+                                                                                                                                                                {!! htmlFormSnippet() !!}
+                                                                                                                                                                @error('g-recaptcha-response')
+            <span class="text-danger" role="alert">
+                                                                                                                                                                                                                                                    <small><strong>{{ $message }}</strong></small>
+                                                                                                                                                                                                                                                        </span>
+        @enderror
+                                                                                                                                                                </div>
+                                                                                                                                                                        </div>
+                                                                                                                                                                </div>
+                                                                                                                                                            </div>
+                                                                                                                                                               -->
 
 
                                                 <div class="row">
                                                     <div class="col-12 d-flex align-items-center justify-content-end">
-                                                        <button type="submit"
-                                                                class="btn btn-primary float-right ">Save
+                                                        <button type="submit" class="btn btn-primary float-right ">Save
                                                         </button>
                                                         <button type="reset"
-                                                                class="btn btn-secondary float-right ml-2">Reset
+                                                            class="btn btn-secondary float-right ml-2">Reset
                                                         </button>
                                                     </div>
                                                 </div>
@@ -331,7 +324,7 @@ class="btn btn-secondary float-right ml-2">Reset
             $('.nav-item a[href="' + tabPaneHash + '"]').tab('show');
         }
 
-        $('.nav-pills a').click(function (e) {
+        $('.nav-pills a').click(function(e) {
             $(this).tab('show');
             const scrollmem = $('body').scrollTop();
             window.location.hash = this.hash;

From 957da3dc786b523cc8bdb9ed7b6976a86c27450f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 4 Jun 2023 16:08:47 +0200
Subject: [PATCH 185/514] =?UTF-8?q?chore:=20=F0=9F=94=A5=20remove=20error?=
 =?UTF-8?q?=5Flog?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../views/admin/settings/index.blade.php      | 33 +++++++++----------
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 65d552e88..dce0bbb30 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -214,7 +214,6 @@ class="form-control" name="logo" id="logo">
                                                                                 class="custom-select w-100"
                                                                                 name="{{ $key }}">
                                                                                 @if ($value['identifier'] == 'display')
-                                                                                    {{ error_log($key . 'True, IAM A DISPLAY') }}
                                                                                     @foreach ($value['options'] as $option => $display)
                                                                                         <option value="{{ $display }}"
                                                                                             {{ $value['value'] == $display ? 'selected' : '' }}>
@@ -267,27 +266,27 @@ class="custom-select w-100"
 
                                                 <!-- TODO: Display this only on the General tab
 
-                                                                                                                                                            <div class="row">
-                                                                                                                                                                <div class="col-4 d-flex align-items-center">
-                                                                                                                                                                    <label for="recaptcha_preview">{{ __('ReCAPTCHA Preview') }}</label>
-                                                                                                                                                                </div>
+                                                                                                                                                                    <div class="row">
+                                                                                                                                                                        <div class="col-4 d-flex align-items-center">
+                                                                                                                                                                            <label for="recaptcha_preview">{{ __('ReCAPTCHA Preview') }}</label>
+                                                                                                                                                                        </div>
 
-                                                                                                                                                                <div class="col-8">
+                                                                                                                                                                        <div class="col-8">
 
-                                                                                                                                                                        <div class="w-100">
-                                                                                                                                                                <div class="input-group mb-3">
-                                                                                                                                                                    {!! htmlScriptTagJsApi() !!}
-                                                                                                                                                                {!! htmlFormSnippet() !!}
-                                                                                                                                                                @error('g-recaptcha-response')
+                                                                                                                                                                                <div class="w-100">
+                                                                                                                                                                        <div class="input-group mb-3">
+                                                                                                                                                                            {!! htmlScriptTagJsApi() !!}
+                                                                                                                                                                        {!! htmlFormSnippet() !!}
+                                                                                                                                                                        @error('g-recaptcha-response')
             <span class="text-danger" role="alert">
-                                                                                                                                                                                                                                                    <small><strong>{{ $message }}</strong></small>
-                                                                                                                                                                                                                                                        </span>
+                                                                                                                                                                                                                                                                <small><strong>{{ $message }}</strong></small>
+                                                                                                                                                                                                                                                                    </span>
         @enderror
-                                                                                                                                                                </div>
                                                                                                                                                                         </div>
-                                                                                                                                                                </div>
-                                                                                                                                                            </div>
-                                                                                                                                                               -->
+                                                                                                                                                                                </div>
+                                                                                                                                                                        </div>
+                                                                                                                                                                    </div>
+                                                                                                                                                                       -->
 
 
                                                 <div class="row">

From 820f47738d1e8988075fb6212854161ee9167c35 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 4 Jun 2023 16:10:09 +0200
Subject: [PATCH 186/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20typo?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Settings/ReferralSettings.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Settings/ReferralSettings.php b/app/Settings/ReferralSettings.php
index f56b71883..b08923fde 100644
--- a/app/Settings/ReferralSettings.php
+++ b/app/Settings/ReferralSettings.php
@@ -27,7 +27,7 @@ public static function getValidations()
             'always_give_commission' => 'nullable|string',
             'enabled' => 'nullable|string',
             'reward' => 'nullable|numeric',
-            'mode' => 'required|in:comission,sign-up,both',
+            'mode' => 'required|in:commission,sign-up,both',
             'percentage' => 'nullable|numeric',
         ];
     }

From e8a6adb4e6ad93c7bdfd54ab2aae4a365b6688da Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Thu, 8 Jun 2023 16:10:42 +0200
Subject: [PATCH 187/514] =?UTF-8?q?fix:=20=F0=9F=9A=9A=20Typo=20cancelled?=
 =?UTF-8?q?=20->=20canceled?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Console/Commands/ChargeServers.php             |  6 +++---
 app/Http/Controllers/Admin/ServerController.php    | 14 +++++++-------
 app/Http/Controllers/ServerController.php          |  6 +++---
 app/Models/Server.php                              |  2 +-
 app/Models/User.php                                | 14 ++++++--------
 ..._08_234527_add_cancelation_to_servers_table.php |  5 ++++-
 themes/default/views/servers/index.blade.php       |  6 +++---
 7 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 014af9636..8c7b9d4de 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -24,7 +24,7 @@ class ChargeServers extends Command
      */
     protected $description = 'Charge all users with severs that are due to be charged';
 
-        /**
+    /**
      * A list of users that have to be notified
      * @var array
      */
@@ -60,7 +60,7 @@ public function handle()
 
                 // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
                 $newBillingDate = null;
-                switch($billing_period) {
+                switch ($billing_period) {
                     case 'annually':
                         $newBillingDate = Carbon::parse($server->last_billed)->addYear();
                         break;
@@ -91,7 +91,7 @@ public function handle()
                 }
 
                 // check if the server is canceled or if user has enough credits to charge the server or
-                if ( $server->cancelled || $user->credits <= $product->price) {
+                if ($server->canceled || $user->credits <= $product->price) {
                     try {
                         // suspend server
                         $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index 9efd70f01..97ee15535 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -25,7 +25,7 @@ class ServerController extends Controller
     const WRITE_PERMISSION = "admin.servers.write";
     const SUSPEND_PERMISSION = "admin.servers.suspend";
     const CHANGEOWNER_PERMISSION = "admin.servers.write.owner";
-    const CHANGE_IDENTIFIER_PERMISSION ="admin.servers.write.identifier";
+    const CHANGE_IDENTIFIER_PERMISSION = "admin.servers.write.identifier";
     const DELETE_PERMISSION = "admin.servers.delete";
     private $pterodactyl;
 
@@ -100,7 +100,7 @@ public function update(Request $request, Server $server)
         }
 
         // update the identifier
-        if($this->can(self::CHANGE_IDENTIFIER_PERMISSION)) {
+        if ($this->can(self::CHANGE_IDENTIFIER_PERMISSION)) {
 
             $server->identifier = $request->get('identifier');
         }
@@ -133,13 +133,13 @@ public function destroy(Server $server)
      * @param Server $server
      * @return RedirectResponse|Response
      */
-    public function cancel (Server $server)
+    public function cancel(Server $server)
     {
         try {
-            error_log($server->update([
-                'cancelled' => now(),
-            ]));
-            return redirect()->route('servers.index')->with('success', __('Server cancelled'));
+            $server->update([
+                'canceled' => now(),
+            ]);
+            return redirect()->route('servers.index')->with('success', __('Server canceled'));
         } catch (Exception $e) {
             return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
         }
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 5380e10b8..d291e2986 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -281,9 +281,9 @@ public function cancel(Server $server)
         }
         try {
             $server->update([
-                'cancelled' => now(),
+                'canceled' => now(),
             ]);
-            return redirect()->route('servers.index')->with('success', __('Server cancelled'));
+            return redirect()->route('servers.index')->with('success', __('Server canceled'));
         } catch (Exception $e) {
             return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to cancel the server"') . $e->getMessage() . '"');
         }
@@ -401,7 +401,7 @@ public function upgrade(Server $server, Request $request)
                 'product_id' => $newProduct->id,
                 'updated_at' => now(),
                 'last_billed' => now(),
-                'cancelled' => null,
+                'canceled' => null,
             ]);
 
             // Refund the user the overpayed credits
diff --git a/app/Models/Server.php b/app/Models/Server.php
index 07acc08a9..bd70c5367 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -60,7 +60,7 @@ public function getActivitylogOptions(): LogOptions
         "product_id",
         "pterodactyl_id",
         "last_billed",
-        "cancelled"
+        "canceled"
     ];
 
     /**
diff --git a/app/Models/User.php b/app/Models/User.php
index 6d14f585a..2c632e3cd 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -98,8 +98,6 @@ public function __construct()
 
         $ptero_settings = new PterodactylSettings();
         $this->pterodactyl = new PterodactylClient($ptero_settings);
-
-
     }
 
     public static function boot()
@@ -252,7 +250,7 @@ private function getServersWithProduct()
     {
         return $this->servers()
             ->whereNull('suspended')
-            ->whereNull('cancelled')
+            ->whereNull('canceled')
             ->with('product')
             ->get();
     }
@@ -289,15 +287,15 @@ public function reVerifyEmail()
         ])->save();
     }
 
-    public function referredBy(){
-        $referee = DB::table('user_referrals')->where("registered_user_id",$this->id)->first();
+    public function referredBy()
+    {
+        $referee = DB::table('user_referrals')->where("registered_user_id", $this->id)->first();
 
-        if($referee){
-            $referee = User::where("id",$referee->referral_id)->firstOrFail();
+        if ($referee) {
+            $referee = User::where("id", $referee->referral_id)->firstOrFail();
             return $referee;
         }
         return Null;
-
     }
 
     public function getActivitylogOptions(): LogOptions
diff --git a/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php b/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
index 0d0f4e203..b26b19cc5 100644
--- a/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
+++ b/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
@@ -15,6 +15,9 @@ public function up()
     {
         // User already has installed the addon before
         if (Schema::hasColumn("servers", "cancelled")) {
+            Schema::table('servers', function (Blueprint $table) {
+                $table->renameColumn('cancelled', 'canceled');
+            });
             return;
         }
 
@@ -31,7 +34,7 @@ public function up()
     public function down()
     {
         Schema::table('servers', function (Blueprint $table) {
-            $table->dropColumn('cancelled');
+            $table->dropColumn('canceled');
         });
     }
 }
diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index 09858c676..f7c2cec5b 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -82,8 +82,8 @@ class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }
                                     <div class="col-7 my-auto">
                                         @if($server->suspended)
                                             <span class="badge badge-danger">{{ __('Suspended') }}</span>
-                                        @elseif($server->cancelled)
-                                            <span class="badge badge-warning">{{ __('Cancelled') }}</span>
+                                        @elseif($server->canceled)
+                                            <span class="badge badge-warning">{{ __('Canceled') }}</span>
                                         @else
                                             <span class="badge badge-success">{{ __('Active') }}</span>
                                         @endif
@@ -220,7 +220,7 @@ class="btn btn-info text-center mr-3"
                             </a>
                             <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
                                 class="btn btn-warning  text-center"
-                                {{ $server->suspended || $server->cancelled ? "disabled" : "" }}
+                                {{ $server->suspended || $server->canceled ? "disabled" : "" }}
                                 data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
                                 <i class="fas fa-ban mx-2"></i>
                             </button>

From e03ac5dae0097b999104450bf8751ca904cf2d2a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Thu, 8 Jun 2023 20:23:06 +0200
Subject: [PATCH 188/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20missed=20one=20li?=
 =?UTF-8?q?ne=20for=20typo=20fix?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../2023_05_08_234527_add_cancelation_to_servers_table.php      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php b/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
index b26b19cc5..94efae378 100644
--- a/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
+++ b/database/migrations/2023_05_08_234527_add_cancelation_to_servers_table.php
@@ -22,7 +22,7 @@ public function up()
         }
 
         Schema::table('servers', function (Blueprint $table) {
-            $table->dateTime('cancelled')->nullable();
+            $table->dateTime('canceled')->nullable();
         });
     }
 

From 72f3decd3f97b9e1236b7cd42ead513b8eb624ba Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Wed, 17 May 2023 16:17:51 +0000
Subject: [PATCH 189/514] Feat: Let's implement the coupons now

---
 .editorconfig                                 |  25 +-
 .gitignore                                    |   1 +
 .../PayPal/PayPalExtension.php                |  25 +-
 .../Controllers/Admin/CouponController.php    | 159 ++++++++++
 .../Controllers/Admin/PaymentController.php   |  30 ++
 app/Http/Controllers/ProfileController.php    |   3 +-
 app/Models/Coupon.php                         | 162 ++++++++++
 app/Models/User.php                           |  10 +-
 app/Settings/CouponSettings.php               |  43 +++
 app/Traits/Coupon.php                         |  86 ++++++
 bootstrap/cache/.gitignore                    |   0
 config/permissions_web.php                    |   3 +
 config/settings.php                           |   2 +
 ...2023_05_11_153719_create_coupons_table.php |  37 +++
 ...05_14_152604_create_user_coupons_table.php |  32 ++
 ...23_05_12_170041_create_coupon_settings.php |  16 +
 package-lock.json                             |   2 +-
 routes/web.php                                |   5 +
 storage/app/.gitignore                        |   0
 storage/app/public/.gitignore                 |   0
 storage/debugbar/.gitignore                   |   0
 storage/framework/.gitignore                  |   0
 storage/framework/cache/.gitignore            |   0
 storage/framework/sessions/.gitignore         |   0
 storage/framework/testing/.gitignore          |   0
 storage/framework/views/.gitignore            |   0
 storage/logs/.gitignore                       |   0
 .../views/admin/coupons/create.blade.php      | 289 ++++++++++++++++++
 .../views/admin/coupons/index.blade.php       |  65 ++++
 themes/default/views/layouts/main.blade.php   |  14 +-
 themes/default/views/store/checkout.blade.php | 128 +++++++-
 31 files changed, 1122 insertions(+), 15 deletions(-)
 create mode 100644 app/Http/Controllers/Admin/CouponController.php
 create mode 100644 app/Models/Coupon.php
 create mode 100644 app/Settings/CouponSettings.php
 create mode 100644 app/Traits/Coupon.php
 mode change 100644 => 100755 bootstrap/cache/.gitignore
 create mode 100644 database/migrations/2023_05_11_153719_create_coupons_table.php
 create mode 100644 database/migrations/2023_05_14_152604_create_user_coupons_table.php
 create mode 100644 database/settings/2023_05_12_170041_create_coupon_settings.php
 mode change 100644 => 100755 storage/app/.gitignore
 mode change 100644 => 100755 storage/app/public/.gitignore
 mode change 100644 => 100755 storage/debugbar/.gitignore
 mode change 100644 => 100755 storage/framework/.gitignore
 mode change 100644 => 100755 storage/framework/cache/.gitignore
 mode change 100644 => 100755 storage/framework/sessions/.gitignore
 mode change 100644 => 100755 storage/framework/testing/.gitignore
 mode change 100644 => 100755 storage/framework/views/.gitignore
 mode change 100644 => 100755 storage/logs/.gitignore
 create mode 100644 themes/default/views/admin/coupons/create.blade.php
 create mode 100644 themes/default/views/admin/coupons/index.blade.php

diff --git a/.editorconfig b/.editorconfig
index 6537ca467..78326873f 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -3,9 +3,9 @@ root = true
 [*]
 charset = utf-8
 end_of_line = lf
-insert_final_newline = true
+indent_size = 2
 indent_style = space
-indent_size = 4
+insert_final_newline = true
 trim_trailing_whitespace = true
 
 [*.md]
@@ -13,3 +13,24 @@ trim_trailing_whitespace = false
 
 [*.{yml,yaml}]
 indent_size = 2
+
+[docker-compose.yml]
+indent_size = 2
+
+[*.php]
+indent_size = 4
+
+[*.blade.php]
+indent_size = 2
+
+[*.js]
+indent_size = 4
+
+[*.jsx]
+indent_size = 2
+
+[*.tsx]
+indent_size = 2
+
+[*.json]
+indent_size = 4
diff --git a/.gitignore b/.gitignore
index 58212a1db..ad9d095b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ storage/debugbar
 .env.backup
 .idea
 .phpunit.result.cache
+.editorconfig
 docker-compose.override.yml
 Homestead.json
 Homestead.yaml
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index 6b1c335e8..73d632df7 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -10,6 +10,7 @@
 use App\Models\Payment;
 use App\Models\ShopProduct;
 use App\Models\User;
+use App\Models\Coupon;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Redirect;
@@ -41,6 +42,17 @@ static function PaypalPay(Request $request): void
         $user = Auth::user();
         $shopProduct = ShopProduct::findOrFail($request->shopProduct);
         $discount = PartnerDiscount::getDiscount();
+        $discountPrice = $request->get('discountPrice');
+
+        dd($discountPrice);
+
+        // Partner Discount.
+        $price = $shopProduct->price - ($shopProduct->price * $discount / 100);
+
+        // Coupon Discount.
+        // if ($discountPrice) {
+        //     $price = $price - ($price * floatval($coupon_percentage) / 100);
+        // }
 
         // create a new payment
         $payment = Payment::create([
@@ -50,7 +62,7 @@ static function PaypalPay(Request $request): void
             'type' => $shopProduct->type,
             'status' => 'open',
             'amount' => $shopProduct->quantity,
-            'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
+            'price' => $price,
             'tax_value' => $shopProduct->getTaxValue(),
             'tax_percent' => $shopProduct->getTaxPercent(),
             'total_price' => $shopProduct->getTotalPrice(),
@@ -73,7 +85,7 @@ static function PaypalPay(Request $request): void
                             'item_total' =>
                             [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
-                                'value' => $shopProduct->getPriceAfterDiscount(),
+                                'value' => number_format($price, 2),
                             ],
                             'tax_total' =>
                             [
@@ -86,7 +98,7 @@ static function PaypalPay(Request $request): void
             ],
             "application_context" => [
                 "cancel_url" => route('payment.Cancel'),
-                "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id]),
+                "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id, 'couponCode' => $coupon_code]),
                 'brand_name' =>  config('app.name', 'CtrlPanel.GG'),
                 'shipping_preference'  => 'NO_SHIPPING'
             ]
@@ -126,6 +138,7 @@ static function PaypalSuccess(Request $laravelRequest): void
 
         $payment = Payment::findOrFail($laravelRequest->payment);
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
+				$coupon_code = $laravelRequest->input('couponCode');
 
         $request = new OrdersCaptureRequest($laravelRequest->input('token'));
         $request->prefer('return=representation');
@@ -140,6 +153,12 @@ static function PaypalSuccess(Request $laravelRequest): void
                     'payment_id' => $response->result->id,
                 ]);
 
+								// increase the use of the coupon when the payment is confirmed.
+								if ($coupon_code) {
+									$coupon = new Coupon;
+									$coupon->incrementUses($coupon_code);
+								}
+
                 event(new UserUpdateCreditsEvent($user));
                 event(new PaymentEvent($user, $payment, $shopProduct));
 
diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php
new file mode 100644
index 000000000..44c3d6181
--- /dev/null
+++ b/app/Http/Controllers/Admin/CouponController.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Http\Controllers\Controller;
+use App\Models\Coupon;
+use App\Traits\Coupon as CouponTrait;
+use Illuminate\Http\Request;
+use Carbon\Carbon;
+
+class CouponController extends Controller
+{
+    const READ_PERMISSION = "admin.coupons.read";
+    const WRITE_PERMISSION = "admin.coupons.write";
+
+    use CouponTrait;
+
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        $this->checkPermission(self::READ_PERMISSION);
+
+        return view('admin.coupons.index');
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        $this->checkPermission(self::WRITE_PERMISSION);
+
+        return view('admin.coupons.create');
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        $coupon_code = $request->input('coupon_code');
+        $coupon_type = $request->input('coupon_type');
+        $coupon_value = $request->input('coupon_value');
+        $coupon_max_uses = $request->input('coupon_uses');
+        $coupon_datepicker = $request->input('datepicker');
+        $random_codes_amount = $request->input('range_codes');
+        $rules = [
+            "coupon_type" => "required|string|in:percentage,amount",
+            "coupon_uses" => "required|integer|digits_between:1,100",
+            "coupon_value" => "required|numeric|between:0,100",
+            "datepicker" => "required|date|after:" . Carbon::now()->format(Coupon::formatDate())
+        ];
+
+        // If for some reason you pass both fields at once.
+        if ($coupon_code && $random_codes_amount) {
+            return redirect()->back()->with('error', __('Only one of the two code inputs must be provided.'))->withInput($request->all());
+        }
+
+        if (!$coupon_code && !$random_codes_amount) {
+            return redirect()->back()->with('error', __('At least one of the two code inputs must be provided.'))->withInput($request->all());
+        }
+
+        if ($coupon_code) {
+            $rules['coupon_code'] = 'required|string|min:4';
+        } elseif ($random_codes_amount) {
+            $rules['range_codes'] = 'required|integer|digits_between:1,100';
+        }
+
+        $request->validate($rules);
+
+        if (array_key_exists('range_codes', $rules)) {
+            $data = [];
+            $coupons = Coupon::generateRandomCoupon($random_codes_amount);
+
+            // Scroll through all the randomly generated coupons.
+            foreach ($coupons as $coupon) {
+                $data[] = [
+                    'code' => $coupon,
+                    'type' => $coupon_type,
+                    'value' => $coupon_value,
+                    'max_uses' => $coupon_max_uses,
+                    'expires_at' => $coupon_datepicker,
+                    'created_at' => Carbon::now(), // Does not fill in by itself when using the 'insert' method.
+                    'updated_at' => Carbon::now()
+                ];
+            }
+            Coupon::insert($data);
+        } else {
+            Coupon::create([
+                'code' => $coupon_code,
+                'type' => $coupon_type,
+                'value' => $coupon_value,
+                'max_uses' => $coupon_max_uses,
+                'expires_at' => $coupon_datepicker,
+            ]);
+        }
+
+        return redirect()->route('admin.coupons.index')->with('success', __("The coupon's was registered successfully."));
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\Models\Coupon  $coupon
+     * @return \Illuminate\Http\Response
+     */
+    public function show(Coupon $coupon)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\Models\Coupon  $coupon
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(Coupon $coupon)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\Models\Coupon  $coupon
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, Coupon $coupon)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\Models\Coupon  $coupon
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(Coupon $coupon)
+    {
+        //
+    }
+
+    public function redeem(Request $request)
+    {
+        return $this->validateCoupon($request);
+    }
+}
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 543cdcf69..7c85d44e3 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -9,6 +9,8 @@
 use App\Models\Payment;
 use App\Models\User;
 use App\Models\ShopProduct;
+use App\Models\Coupon;
+use App\Traits\Coupon as CouponTrait;
 use Exception;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\View\Factory;
@@ -20,11 +22,16 @@
 use App\Helpers\ExtensionHelper;
 use App\Settings\GeneralSettings;
 use App\Settings\LocaleSettings;
+use Carbon\Carbon;
+use Illuminate\Support\Str;
 
 class PaymentController extends Controller
 {
     const BUY_PERMISSION = 'user.shop.buy';
     const VIEW_PERMISSION = "admin.payments.read";
+
+    use CouponTrait;
+
     /**
      * @return Application|Factory|View
      */
@@ -123,6 +130,8 @@ public function pay(Request $request)
     {
         $product = ShopProduct::find($request->product_id);
         $paymentGateway = $request->payment_method;
+        $coupon_data = null;
+        $coupon_code = $request->coupon_code;
 
         // on free products, we don't need to use a payment gateway
         $realPrice = $product->price - ($product->price * PartnerDiscount::getDiscount() / 100);
@@ -130,6 +139,22 @@ public function pay(Request $request)
             return $this->handleFreeProduct($product);
         }
 
+        if ($coupon_code) {
+            $isValidCoupon = $this->validateCoupon($request);
+
+            if ($isValidCoupon->getStatusCode() == 200) {
+                $coupon_data = $isValidCoupon;
+                $discountPrice = $this->calcDiscount($product, $isValidCoupon->getData());
+            }
+        }
+
+        if ($coupon_data) {
+            return redirect()->route('payment.' . $paymentGateway . 'Pay', [
+                'shopProduct' => $product->id,
+                'discountPrice' => $discountPrice
+            ]);
+        }
+
         return redirect()->route('payment.' . $paymentGateway . 'Pay', ['shopProduct' => $product->id]);
     }
 
@@ -141,6 +166,11 @@ public function Cancel(Request $request)
         return redirect()->route('store.index')->with('info', 'Payment was Canceled');
     }
 
+    protected function getCouponDiscount(float $productPrice, string $discount)
+    {
+        return $productPrice - ($productPrice * $discount / 100);
+    }
+
     /**
      * @return JsonResponse|mixed
      *
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 8a0425016..52cb0bffe 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -34,8 +34,7 @@ public function index(UserSettings $user_settings, DiscordSettings $discord_sett
             'force_discord_verification' => $user_settings->force_discord_verification,
             'discord_client_id' => $discord_settings->client_id,
             'discord_client_secret' => $discord_settings->client_secret,
-            'referral_enabled' => $referral_settings->enabled,
-            'referral_allowed' => $referral_settings->allowed
+            'referral_enabled' => $referral_settings->enabled
         ]);
     }
 
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
new file mode 100644
index 000000000..9b8497515
--- /dev/null
+++ b/app/Models/Coupon.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Carbon\Carbon;
+
+class Coupon extends Model
+{
+    use HasFactory;
+
+    protected $fillable = [
+        'code',
+        'type',
+        'value',
+        'uses',
+        'max_uses',
+        'expires_at'
+    ];
+
+    /**
+     * Returns the date format used by the coupons.
+     *
+     * @return string
+     */
+    public static function formatDate(): string
+    {
+        return 'Y-MM-DD HH:mm:ss';
+    }
+
+    /**
+     * Returns the current state of the coupon.
+     *
+     * @return string
+     */
+    public function getStatus()
+    {
+        if ($this->uses >= $this->max_uses) {
+            return 'USES_LIMIT_REACHED';
+        }
+
+        if (! is_null($this->expires_at)) {
+            $expires_at = Carbon::createFromTimeString($this->expires_at)->timestamp;
+
+            if ($expires_at <= Carbon::now()->timestamp) {
+                return __('EXPIRED');
+            }
+        }
+
+        return __('VALID');
+    }
+
+    /**
+     * Check if a user has already exceeded the uses of a coupon.
+     *
+     * @param Request $request The request being made.
+     * @param CouponSettings $coupon_settings The instance of the coupon settings.
+     *
+     * @return bool
+     */
+    public function isLimitsUsesReached($request, $coupon_settings): bool
+    {
+        $coupon_uses = $request->user()->coupons()->where('id', $this->id)->count();
+
+        return $coupon_uses >= $coupon_settings->max_uses_per_user ? true : false;
+    }
+
+    /**
+     * Generate a specified quantity of coupon codes.
+     *
+     * @param int $amount Amount of coupons to be generated.
+     *
+     * @return array
+     */
+    public static function generateRandomCoupon(int $amount = 10): array
+    {
+        $coupons = [];
+
+        for ($i = 0; $i < $amount; $i++) {
+            $random_coupon = strtoupper(bin2hex(random_bytes(3)));
+
+            $coupons[] = $random_coupon;
+        }
+
+        return $coupons;
+    }
+
+    /**
+     * Standardize queries into one single function.
+     *
+     * @param string $code Coupon Code.
+     * @param array $attributes Attributes to be returned.
+     *
+     * @return mixed
+     */
+    protected function getQueryData(string $code, array $attributes): mixed
+    {
+        $query = (Coupon::where('code', $code)
+            ->where('expires_at', '>', Carbon::now())
+            ->whereColumn('uses', '<=', 'max_uses')
+            ->get($attributes)->toArray()
+        );
+
+        // When there are results, it comes nested arrays, idk why. This is the solution for now.
+        $results = count($query) > 0 ? $query[0] : $query;
+
+        if (empty($results)) {
+            return [];
+        }
+
+        return $results;
+    }
+
+    /**
+     * Get the data from a coupon.
+     *
+     * @param string $code Coupon Code.
+     * @param array $attributes Attributes of a coupon.
+     *
+     * @return mixed
+     */
+    public function getCoupon(string $code, array $attributes = ['percentage']): mixed
+    {
+        $coupon = $this->getQueryData($code, $attributes);
+
+        if (is_null($coupon)) {
+            return null;
+        }
+
+        return $coupon;
+    }
+
+    /**
+     * Increments the use of a coupon.
+     *
+     * @param string $code Coupon Code.
+     * @param int $amount Amount to increment.
+     *
+     * @return null|bool
+     */
+    public function incrementUses(string $code, int $amount = 1): null|bool
+    {
+        $coupon = $this->getQueryData($code, ['uses', 'max_uses']);
+
+        if (empty($coupon) || $coupon['uses'] == $coupon['max_uses']) {
+            return null;
+        }
+
+        $this->where('code', $code)->increment('uses', $amount);
+
+        return true;
+    }
+
+    /**
+     * @return BelongsToMany
+     */
+    public function users()
+    {
+        return $this->belongsToMany(User::class, 'user_coupons');
+    }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index 2c632e3cd..7c04a65bb 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -4,8 +4,6 @@
 
 use App\Notifications\Auth\QueuedVerifyEmail;
 use App\Notifications\WelcomeMessage;
-use App\Settings\GeneralSettings;
-use App\Settings\UserSettings;
 use App\Classes\PterodactylClient;
 use App\Settings\PterodactylSettings;
 use Illuminate\Contracts\Auth\MustVerifyEmail;
@@ -170,6 +168,14 @@ public function vouchers()
         return $this->belongsToMany(Voucher::class);
     }
 
+    /**
+     * @return BelongsToMany
+     */
+    public function coupons()
+    {
+        return $this->belongsToMany(Coupon::class, 'user_coupons');
+    }
+
     /**
      * @return HasOne
      */
diff --git a/app/Settings/CouponSettings.php b/app/Settings/CouponSettings.php
new file mode 100644
index 000000000..45f9c25bf
--- /dev/null
+++ b/app/Settings/CouponSettings.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Settings;
+
+use Spatie\LaravelSettings\Settings;
+
+class CouponSettings extends Settings
+{
+	public ?int $max_uses_per_user;
+
+    public static function group(): string
+    {
+        return 'coupon';
+    }
+
+		/**
+     * Summary of validations array
+     * @return array<string, string>
+     */
+    public static function getValidations()
+    {
+        return [
+            'max_uses_per_user' => 'required|integer'
+        ];
+    }
+
+		/**
+     * Summary of optionInputData array
+     * Only used for the settings page
+     * @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
+     */
+    public static function getOptionInputData()
+    {
+        return [
+            "category_icon" => "fas fa-ticket-alt",
+            'max_uses_per_user' => [
+                'label' => 'Max Uses Per User',
+                'type' => 'number',
+                'description' => 'Maximum number of uses that a user can make of the same coupon.',
+            ]
+        ];
+    }
+}
diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php
new file mode 100644
index 000000000..319fd890e
--- /dev/null
+++ b/app/Traits/Coupon.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Traits;
+
+use App\Settings\CouponSettings;
+use App\Models\Coupon as CouponModel;
+use App\Models\ShopProduct;
+use Illuminate\Http\Request;
+use Illuminate\Http\JsonResponse;
+use stdClass;
+
+trait Coupon
+{
+    public function validateCoupon(Request $request): JsonResponse
+    {
+        $coupon = CouponModel::where('code', $request->input('coupon_code'))->first();
+        $coupon_settings = new CouponSettings;
+        $response = response()->json([
+            'isValid' => false,
+            'error' => __('This coupon does not exist.')
+        ], 404);
+
+        if (!is_null($coupon)) {
+            if ($coupon->getStatus() == 'USES_LIMIT_REACHED') {
+                $response = response()->json([
+                    'isValid' => false,
+                    'error' => __('This coupon has reached the maximum amount of uses.')
+                ], 422);
+
+                return $response;
+            }
+
+            if ($coupon->getStatus() == 'EXPIRED') {
+                $response = response()->json([
+                    'isValid' => false,
+                    'error' => __('This coupon has expired.')
+                ], 422);
+
+                return $response;
+            }
+
+            if ($coupon->isLimitsUsesReached($request, $coupon_settings)) {
+                $response = response()->json([
+                    'isValid' => false,
+                    'error' => __('You have reached the maximum uses of this coupon.')
+                ], 422);
+
+                return $response;
+            }
+
+            $response = response()->json([
+                'isValid' => true,
+                'couponCode' => $coupon->code,
+                'couponType' => $coupon->type,
+                'couponValue' => $coupon->value
+            ]);
+        }
+
+        return $response;
+    }
+
+    public function calcDiscount(ShopProduct $product, stdClass $data)
+    {
+
+        if ($data->isValid) {
+            $productPrice = $product->price;
+
+            if (is_string($productPrice)) {
+                $productPrice = floatval($product->price);
+            }
+
+            if ($data->couponType === 'percentage') {
+                return $productPrice - ($productPrice * $data->couponValue / 100);
+            }
+
+            if ($data->couponType === 'amount') {
+                // There is no discount if the value of the coupon is greater than or equal to the value of the product.
+                if ($data->couponValue >= $productPrice) {
+                    return $productPrice;
+                }
+            }
+
+            return $productPrice - $data->couponValue;
+        }
+    }
+}
diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore
old mode 100644
new mode 100755
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 1c3828f70..f0918375b 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -74,6 +74,9 @@
     'admin.partners.read',
     'admin.partners.write',
 
+    'admin.coupons.read',
+    'admin.coupons.write',
+
     'admin.logs.read',
 
     /*
diff --git a/config/settings.php b/config/settings.php
index 67838a5c8..6b6ae4b72 100644
--- a/config/settings.php
+++ b/config/settings.php
@@ -12,6 +12,7 @@
 use App\Settings\UserSettings;
 use App\Settings\WebsiteSettings;
 use App\Settings\TicketSettings;
+use App\Settings\CouponSettings;
 
 return [
 
@@ -31,6 +32,7 @@
         UserSettings::class,
         WebsiteSettings::class,
         TicketSettings::class,
+				CouponSettings::class,
     ],
 
     /*
diff --git a/database/migrations/2023_05_11_153719_create_coupons_table.php b/database/migrations/2023_05_11_153719_create_coupons_table.php
new file mode 100644
index 000000000..48048f6ab
--- /dev/null
+++ b/database/migrations/2023_05_11_153719_create_coupons_table.php
@@ -0,0 +1,37 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('coupons', function (Blueprint $table) {
+            $table->id();
+            $table->string('code')->unique();
+            $table->enum('type', ['percentage', 'amount']);
+            $table->integer('value');
+            $table->integer('uses')->default(0);
+            $table->integer('max_uses');
+            $table->timestamp('expires_at');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('coupons');
+    }
+};
diff --git a/database/migrations/2023_05_14_152604_create_user_coupons_table.php b/database/migrations/2023_05_14_152604_create_user_coupons_table.php
new file mode 100644
index 000000000..10f584aec
--- /dev/null
+++ b/database/migrations/2023_05_14_152604_create_user_coupons_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user_coupons', function (Blueprint $table) {
+            $table->foreignId('user_id')->constrained();
+            $table->foreignId('coupon_id')->constrained();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user_coupons');
+    }
+};
diff --git a/database/settings/2023_05_12_170041_create_coupon_settings.php b/database/settings/2023_05_12_170041_create_coupon_settings.php
new file mode 100644
index 000000000..77505cea8
--- /dev/null
+++ b/database/settings/2023_05_12_170041_create_coupon_settings.php
@@ -0,0 +1,16 @@
+<?php
+
+use Spatie\LaravelSettings\Migrations\SettingsMigration;
+
+return new class extends SettingsMigration
+{
+    public function up(): void
+    {
+        $this->migrator->add('coupon.max_uses_per_user', 1);
+    }
+
+    public function down(): void
+    {
+        $this->migrator->delete('coupon.max_uses_per_user');
+    }
+};
diff --git a/package-lock.json b/package-lock.json
index c687dafdf..89d691a53 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
 {
-    "name": "controllpanelgg",
+    "name": "controlpanel",
     "lockfileVersion": 2,
     "requires": true,
     "packages": {
diff --git a/routes/web.php b/routes/web.php
index 5e09c048b..bdfd06f5c 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -22,6 +22,7 @@
 use App\Http\Controllers\Admin\UsefulLinkController;
 use App\Http\Controllers\Admin\UserController;
 use App\Http\Controllers\Admin\VoucherController;
+use App\Http\Controllers\Admin\CouponController;
 use App\Http\Controllers\Auth\SocialiteController;
 use App\Http\Controllers\HomeController;
 use App\Http\Controllers\NotificationController;
@@ -199,6 +200,10 @@
         Route::get('partners/{voucher}/users', [PartnerController::class, 'users'])->name('partners.users');
         Route::resource('partners', PartnerController::class);
 
+        //coupons
+        Route::post('coupons/redeem', [CouponController::class, 'redeem'])->name('coupon.redeem');
+        Route::resource('coupons', CouponController::class);
+
         //api-keys
         Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable');
         Route::resource('api', ApplicationApiController::class)->parameters([
diff --git a/storage/app/.gitignore b/storage/app/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/debugbar/.gitignore b/storage/debugbar/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/framework/.gitignore b/storage/framework/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/framework/sessions/.gitignore b/storage/framework/sessions/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/framework/testing/.gitignore b/storage/framework/testing/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/framework/views/.gitignore b/storage/framework/views/.gitignore
old mode 100644
new mode 100755
diff --git a/storage/logs/.gitignore b/storage/logs/.gitignore
old mode 100644
new mode 100755
diff --git a/themes/default/views/admin/coupons/create.blade.php b/themes/default/views/admin/coupons/create.blade.php
new file mode 100644
index 000000000..2b19d6a77
--- /dev/null
+++ b/themes/default/views/admin/coupons/create.blade.php
@@ -0,0 +1,289 @@
+@extends('layouts.main')
+
+@section('content')
+   <!-- CONTENT HEADER -->
+   <section class="content-header">
+    <div class="container-fluid">
+        <div class="row mb-2">
+            <div class="col-sm-6">
+                <h1>{{__('Coupon')}}</h1>
+            </div>
+            <div class="col-sm-6">
+                <ol class="breadcrumb float-sm-right">
+                    <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
+                    <li class="breadcrumb-item"><a href="{{route('admin.coupons.index')}}">{{__('Coupons')}}</a>
+                    </li>
+                    <li class="breadcrumb-item"><a class="text-muted"
+                                                   href="{{route('admin.coupons.create')}}">{{__('Create')}}</a>
+                    </li>
+                </ol>
+            </div>
+        </div>
+    </div>
+  </section>
+  <!-- END CONTENT HEADER -->
+
+  <!-- MAIN CONTENT -->
+  <section class="content">
+    <div class="container-fluid">
+      <div class="row">
+        <div class="col-lg-6">
+          <div class="card">
+            <div class="card-header">
+              <h5 class="card-title">
+                <i class="nav-icon fas fa-ticket-alt"></i>
+                {{__('Coupon Details')}}
+              </h5>
+            </div>
+            <div class="card-body">
+              <form action="{{ route('admin.coupons.store') }}" method="POST">
+                @csrf
+
+                <div class="d-flex flex-row-reverse">
+                  <div class="custom-control custom-switch">
+                    <input
+                      type="checkbox"
+                      id="random_codes"
+                      name="random_codes"
+                      class="custom-control-input"
+                    >
+                    <label for="random_codes" class="custom-control-label">
+                      {{ __('Random Codes') }}
+                      <i
+                        data-toggle="popover"
+                        data-trigger="hover"
+                        data-content="{{__('Replace the creation of a single code with several at once with a custom field.')}}"
+                        class="fas fa-info-circle">
+                      </i>
+                    </label>
+                  </div>
+                </div>
+                <div id="range_codes_element" style="display: none;" class="form-group">
+                  <label for="range_codes">
+                    {{ __('Range Codes') }}
+                    <i
+                      data-toggle="popover"
+                      data-trigger="hover"
+                      data-content="{{__('Generate a number of random codes.')}}"
+                      class="fas fa-info-circle">
+                    </i>
+                  </label>
+                  <input
+                    type="number"
+                    id="range_codes"
+                    name="range_codes"
+                    step="any"
+                    min="1"
+                    max="100"
+                    class="form-control @error('range_codes') is-invalid @enderror"
+                  >
+                  @error('range_codes')
+                    <div class="text-danger">
+                      {{ $message }}
+                    </div>
+                  @enderror
+                </div>
+                <div id="coupon_code_element" class="form-group">
+                  <label for="coupon_code">
+                    {{ __('Coupon Code') }}
+                    <i
+                      data-toggle="popover"
+                      data-trigger="hover"
+                      data-content="{{__('The coupon code to be registered.')}}"
+                      class="fas fa-info-circle">
+                    </i>
+                  </label>
+                  <input
+                    type="text"
+                    id="coupon_code"
+                    name="coupon_code"
+                    placeholder="SUMMER"
+                    class="form-control @error('coupon_code') is-invalid @enderror"
+                    value="{{ old('coupon_code') }}"
+                  >
+                  @error('coupon_code')
+                    <div class="text-danger">
+                      {{ $message }}
+                    </div>
+                  @enderror
+                </div>
+                <div class="form-group">
+                  <div class="custom-control mb-3 p-0">
+                    <label for="coupon_type">
+                      {{ __('Coupon Type') }}
+                      <i
+                        data-toggle="popover"
+                        data-trigger="hover"
+                        data-content="{{__('The way the coupon should discount.')}}"
+                        class="fas fa-info-circle">
+                      </i>
+                    </label>
+                    <select
+                      name="coupon_type"
+                      id="coupon_type"
+                      class="custom-select @error('coupon_type') is_invalid @enderror"
+                      style="width: 100%; cursor: pointer;"
+                      autocomplete="off"
+                      required
+                    >
+                      <option value="percentage" @if(old('coupon_type') == 'percentage') selected @endif>{{ __('Percentage') }}</option>
+                      <option value="amount" @if(old('coupon_type') == 'amount') selected @endif>{{ __('Amount') }}</option>
+                    </select>
+                    @error('coupon_type')
+                      <div class="text-danger">
+                        {{ $message }}
+                      </div>
+                    @enderror
+                  </div>
+                </div>
+                <div class="form-group">
+                  <div class="input-group d-flex flex-column">
+                    <label for="coupon_value">
+                      {{ __('Coupon Value') }}
+                      <i
+                        data-toggle="popover"
+                        data-trigger="hover"
+                        data-content="{{__('The value that the coupon will represent.')}}"
+                        class="fas fa-info-circle">
+                      </i>
+                    </label>
+                    <div class="d-flex">
+                      <input
+                        name="coupon_value"
+                        id="coupon_value"
+                        type="number"
+                        step="any"
+                        min="1"
+                        max="100"
+                        class="form-control @error('coupon_value') is-invalid @enderror"
+                        value="{{ old('coupon_value') }}"
+                      >
+                      <span id="input_percentage" class="input-group-text">%</span>
+                    </div>
+                    @error('coupon_value')
+                      <div class="text-danger">
+                        {{ $message }}
+                      </div>
+                    @enderror
+                  </div>
+                </div>
+                <div class="form-group">
+                  <label for="coupon_uses">
+                    {{ __('Max uses') }}
+                    <i
+                      data-toggle="popover"
+                      data-trigger="hover"
+                      data-content="{{__('The maximum number of times the coupon can be used.')}}"
+                      class="fas fa-info-circle">
+                    </i>
+                  </label>
+                  <input
+                    name="coupon_uses"
+                    id="coupon_uses"
+                    type="number"
+                    step="any"
+                    min="1"
+                    max="100"
+                    class="form-control @error('coupon_uses') is-invalid @enderror"
+                    value="{{ old('coupon_uses') }}"
+                  >
+                  @error('coupon_uses')
+                    <div class="text-danger">
+                      {{ $message }}
+                    </div>
+                  @enderror
+                </div>
+                <div class="d-flex flex-column input-group form-group date" id="datepicker" data-target-input="nearest">
+                  <label for="datepicker">
+                    {{ __('Expires at') }}
+                    <i
+                      data-toggle="popover"
+                      data-trigger="hover"
+                      data-content="{{__('The date when the coupon will expire.')}}"
+                      class="fas fa-info-circle">
+                    </i>
+                  </label>
+                  <div class="d-flex">
+                    <input
+                      value="{{old('datepicker')}}"
+                      name="datepicker"
+                      placeholder="yyyy-mm-dd hh:mm:ss"
+                      type="text"
+                      class="form-control @error('datepicker') is-invalid @enderror datetimepicker-input"
+                      data-target="#datepicker"
+                    />
+                    <div
+                      class="input-group-append"
+                      data-target="#datepicker"
+                      data-toggle="datetimepicker"
+                    >
+                      <div class="input-group-text">
+                        <i class="fa fa-calendar"></i>
+                      </div>
+                    </div>
+                  </div>
+                  @error('datepicker')
+                    <div class="text-danger">
+                      {{ $message }}
+                    </div>
+                  @enderror
+                </div>
+                <div class="form-group text-right mb-0">
+                  <button type="submit" class="btn btn-primary">
+                    {{__('Submit')}}
+                  </button>
+                </div>
+              </form>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </section>
+   <!-- END CONTENT -->
+
+  <script>
+    $(document).ready(function() {
+      $('#datepicker').datetimepicker({
+        format: 'Y-MM-DD HH:mm:ss',
+        icons: {
+          time: 'far fa-clock',
+          date: 'far fa-calendar',
+          up: 'fas fa-arrow-up',
+          down: 'fas fa-arrow-down',
+          previous: 'fas fa-chevron-left',
+          next: 'fas fa-chevron-right',
+          today: 'fas fa-calendar-check',
+          clear: 'far fa-trash-alt',
+          close: 'far fa-times-circle'
+        }
+      });
+      $('#random_codes').change(function() {
+        if ($(this).is(':checked')) {
+          $('#coupon_code_element').prop('disabled', true).hide()
+          $('#range_codes_element').prop('disabled', false).show()
+
+          if ($('#coupon_code').val()) {
+            $('#coupon_code').prop('value', null)
+          }
+
+        } else {
+          $('#coupon_code_element').prop('disabled', false).show()
+          $('#range_codes_element').prop('disabled', true).hide()
+
+          if ($('#range_codes').val()) {
+            $('#range_codes').prop('value', null)
+          }
+        }
+      })
+
+      $('#coupon_type').change(function() {
+        if ($(this).val() == 'percentage') {
+          $('#input_percentage').prop('disabled', false).show()
+        } else {
+          $('#input_percentage').prop('disabled', true).hide()
+        }
+      })
+    })
+  </script>
+@endsection
diff --git a/themes/default/views/admin/coupons/index.blade.php b/themes/default/views/admin/coupons/index.blade.php
new file mode 100644
index 000000000..814b41ab6
--- /dev/null
+++ b/themes/default/views/admin/coupons/index.blade.php
@@ -0,0 +1,65 @@
+@extends('layouts.main')
+
+@section('content')
+  <!-- CONTENT HEADER -->
+  <section class="content-header">
+    <div class="container-fluid">
+        <div class="row mb-2">
+            <div class="col-sm-6">
+                <h1>{{__('Coupons')}}</h1>
+            </div>
+            <div class="col-sm-6">
+                <ol class="breadcrumb float-sm-right">
+                    <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
+                    <li class="breadcrumb-item"><a class="text-muted"
+                                                   href="{{route('admin.coupons.index')}}">{{__('Coupons')}}</a></li>
+                </ol>
+            </div>
+        </div>
+    </div>
+  </section>
+  <!-- END CONTENT HEADER -->
+
+  <!-- MAIN CONTENT -->
+  <section class="content">
+    <div class="container-fluid">
+        <div class="card">
+            <div class="card-header">
+                <div class="d-flex justify-content-between">
+                    <h5 class="card-title">
+                      <i class="nav-icon fas fa-ticket-alt"></i>
+                      {{__('Coupons')}}
+                    </h5>
+                    <a href="{{route('admin.coupons.create')}}" class="btn btn-sm btn-primary">
+                      <i class="fas fa-plus mr-1"></i>
+                      {{__('Create new')}}
+                    </a>
+                </div>
+            </div>
+
+            <div class="card-body table-responsive">
+
+                <table id="datatable" class="table table-striped">
+                    <thead>
+                    <tr>
+                        <th>{{__('Partner discount')}}</th>
+                        <th>{{__('Registered user discount')}}</th>
+                        <th>{{__('Referral system commission')}}</th>
+                        <th>{{__('Created')}}</th>
+                        <th>{{__('Actions')}}</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    </tbody>
+                </table>
+
+            </div>
+        </div>
+
+
+    </div>
+    <!-- END CUSTOM CONTENT -->
+
+</section>
+<!-- END CONTENT -->
+@endsection
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 994f2bfc6..9631ef64d 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -424,7 +424,7 @@ class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
                                 </a>
                             </li>
                         @endcanany
-                        @canany(["admin.voucher.read","admin.voucher.read"])
+                        @canany(["admin.voucher.read","admin.voucher.write"])
                             <li class="nav-item">
                                 <a href="{{ route('admin.vouchers.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.vouchers.*')) active @endif">
@@ -433,7 +433,7 @@ class="nav-link @if (Request::routeIs('admin.vouchers.*')) active @endif">
                                 </a>
                             </li>
                         @endcanany
-                        @canany(["admin.partners.read","admin.partners.read"])
+                        @canany(["admin.partners.read","admin.partners.write"])
                             <li class="nav-item">
                                 <a href="{{ route('admin.partners.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
@@ -443,6 +443,16 @@ class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
                             </li>
                         @endcanany
 
+												@canany(["admin.coupons.read", "admin.coupons.write"])
+                            <li class="nav-item">
+                                <a href="{{ route('admin.coupons.index') }}"
+                                    class="nav-link @if (Request::routeIs('admin.coupons.*')) active @endif">
+                                    <i class="nav-icon fas fa-ticket-alt"></i>
+                                    <p>{{ __('Coupons') }}</p>
+                                </a>
+                            </li>
+                        @endcanany
+
                             @canany(["admin.useful_links.read","admin.legal.read"])
                                 <li class="nav-header">{{ __('Other') }}</li>
                             @endcanany
diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index a6ca68860..690e6c044 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -24,7 +24,19 @@
     <!-- MAIN CONTENT -->
     <section class="content">
         <div class="container-fluid">
-            <form x-data="{ payment_method: '', clicked: false }" action="{{ route('payment.pay') }}" method="POST">
+            <form
+							id="payment_form"
+              action="{{ route('payment.pay') }}"
+              method="POST"
+              x-data="{
+                payment_method: '',
+                coupon_code: '',
+                clicked: false,
+                setCouponCode(event) {
+                  this.coupon_code = event.target.value
+                }
+              }"
+            >
                 @csrf
                 @method('post')
                 <div class="row d-flex justify-content-center flex-wrap">
@@ -67,6 +79,45 @@
                                 </div>
                             </div>
                         </div>
+												<div class="col-xl-4">
+													<div class="card">
+														<div class="card-header">
+															<h4 class="mb-0">
+																Coupon Code
+															</h4>
+														</div>
+														<div class="card-body">
+															<div class="d-flex">
+                                <input
+                                  type="text"
+                                  id="coupon_code"
+                                  name="coupon_code"
+                                  value="{{ old('coupon_code') }}"
+                                  :value="coupon_code"
+                                  class="form-control @error('coupon_code') is_invalid @enderror"
+                                  placeholder="SUMMER"
+                                  x-on:change.debounce="setCouponCode($event)"
+                                  x-model="coupon_code"
+                                />
+                              <button
+                                type="button"
+                                id="send_coupon_code"
+                                class="btn btn-success ml-3"
+                                :disabled="!coupon_code.length"
+                                :class="!coupon_code.length ? 'disabled' : ''"
+                                :value="coupon_code"
+                              >
+                                {{ __('Submit') }}
+                              </button>
+                              </div>
+                              @error('coupon_code')
+                                <div class="text-danger">
+                                  {{ $message }}
+                                </div>
+                              @enderror
+														</div>
+													</div>
+												</div>
                     @endif
                     <div class="col-xl-3">
                         <div class="card">
@@ -131,6 +182,12 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                                 <span class="text-muted d-inline-block">
                                                     + {{ $product->formatToCurrency($taxvalue) }}</span>
                                             </div>
+                                            <div id="coupon_discount_details" class="d-flex justify-content-between" style="display: none !important;">
+                                              <span class="text-muted d-inline-block">
+                                                {{ __('Coupon Discount') }}
+
+                                              </span>
+                                            </div>
                                             @if ($discountpercent && $discountvalue)
                                                 <div class="d-flex justify-content-between">
                                                     <span class="text-muted d-inline-block">{{ __('Discount') }}
@@ -155,9 +212,12 @@ class="text-muted d-inline-block">{{ $product->formatToCurrency($total) }}</span
                                     </li>
                                 </ul>
 
-                                <button :disabled="(!payment_method || !clicked) && {{ !$productIsFree }}"
-                                    :class="(!payment_method || !clicked) && {{ !$productIsFree }} ? 'disabled' : ''"
+                                <button :disabled="(!payment_method || !clicked || coupon_code ? true : false) && {{ !$productIsFree }}"
+                                    id="submit_form_button"
+                                    :class="(!payment_method || !clicked || coupon_code ? true : false) && {{ !$productIsFree }} ? 'disabled' : ''"
+                                    :x-text="coupon_code"
                                     class="btn btn-success float-right w-100">
+
                                     <i class="far fa-credit-card mr-2" @click="clicked == true"></i>
                                     @if ($productIsFree)
                                         {{ __('Get for free') }}
@@ -166,6 +226,8 @@ class="btn btn-success float-right w-100">
                                     @endif
 
                                 </button>
+                                <script>
+                                </script>
                             </div>
                         </div>
                     </div>
@@ -175,4 +237,64 @@ class="btn btn-success float-right w-100">
 
     </section>
     <!-- END CONTENT -->
+
+    <script>
+      $(document).ready(function() {
+        let hasCouponCodeValue = $('#coupon_code').val().trim() !== ''
+
+        $('#coupon_code').on('change', function(e) {
+          hasCouponCodeValue = e.target.value !== ''
+        })
+
+				function checkCoupon() {
+					const couponCode = $('#coupon_code').val()
+
+					$.ajax({
+						url: "{{ route('admin.coupon.redeem') }}",
+						method: 'POST',
+						data: { coupon_code: couponCode },
+						success: function(response) {
+							if (response.isValid && response.couponCode) {
+                Swal.fire({
+                  icon: 'success',
+                  text: `The coupon '${response.couponCode}' was successfully inserted in your purchase.`,
+                }).then(function(isConfirmed) {
+                  console.log('confirmou')
+
+                  $('#submit_form_button').prop('disabled', false).removeClass('disabled')
+                  $('#send_coupon_code').prop('disabled', true)
+                  $('#coupon_discount_details').prop('disabled', false).show()
+                })
+
+							} else {
+								console.log('Invalid Coupon')
+							}
+						},
+						error: function(response) {
+              const responseJson = response.responseJSON
+
+              if (!responseJson.isValid) {
+                  Swal.fire({
+                  icon: 'error',
+                  title: 'Oops...',
+                  text: responseJson.error,
+                })
+              }
+						}
+					})
+				}
+
+				$('#payment_form').on('submit', function(e) {
+					if (hasCouponCodeValue) {
+						checkCoupon()
+					}
+				})
+
+        $('#send_coupon_code').click(function(e) {
+          if (hasCouponCodeValue) {
+						checkCoupon()
+					}
+        })
+      })
+    </script>
 @endsection

From 8f7ad95506fedacf7bbba0cff8887bd12e36e66d Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Thu, 18 May 2023 01:13:10 +0000
Subject: [PATCH 190/514] Some improvements, and some not so much...

---
 .../PayPal/PayPalExtension.php                | 49 ++++++++++---------
 .../PaymentGateways/PayPal/web_routes.php     |  4 +-
 .../Controllers/Admin/CouponController.php    |  2 +-
 .../Controllers/Admin/PaymentController.php   | 17 +------
 app/Models/Coupon.php                         |  6 +--
 app/Traits/Coupon.php                         | 32 +++++++++---
 ...2023_05_11_153719_create_coupons_table.php |  4 +-
 themes/default/views/store/checkout.blade.php | 36 ++++++++++++--
 8 files changed, 92 insertions(+), 58 deletions(-)

diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index 73d632df7..1586804b5 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -11,6 +11,7 @@
 use App\Models\ShopProduct;
 use App\Models\User;
 use App\Models\Coupon;
+use App\Traits\Coupon as CouponTrait;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Redirect;
@@ -28,6 +29,8 @@
  */
 class PayPalExtension extends AbstractExtension
 {
+    use CouponTrait;
+
     public static function getConfig(): array
     {
         return [
@@ -36,23 +39,27 @@ public static function getConfig(): array
         ];
     }
 
-    static function PaypalPay(Request $request): void
+    public function PaypalPay(Request $request): void
     {
         /** @var User $user */
         $user = Auth::user();
         $shopProduct = ShopProduct::findOrFail($request->shopProduct);
         $discount = PartnerDiscount::getDiscount();
-        $discountPrice = $request->get('discountPrice');
+        $couponCode = $request->input('couponCode');
+        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
 
-        dd($discountPrice);
+        if (is_string($shopProduct->price)) {
+            $shopProduct->price = floatval($shopProduct->price);
+        }
 
-        // Partner Discount.
-        $price = $shopProduct->price - ($shopProduct->price * $discount / 100);
+        $price = $shopProduct->price;
 
-        // Coupon Discount.
-        // if ($discountPrice) {
-        //     $price = $price - ($price * floatval($coupon_percentage) / 100);
-        // }
+        if ($isValidCoupon->getStatusCode() == 200) {
+            $price = $this->calcDiscount($price, $isValidCoupon->getData());
+        }
+
+        // Partner Discount.
+        $price = $price - ($price * $discount / 100);
 
         // create a new payment
         $payment = Payment::create([
@@ -78,17 +85,15 @@ static function PaypalPay(Request $request): void
                 [
                     "reference_id" => uniqid(),
                     "description" => $shopProduct->display . ($discount ? (" (" . __('Discount') . " " . $discount . '%)') : ""),
-                    "amount"       => [
-                        "value"         => $shopProduct->getTotalPrice(),
+                    "amount" => [
+                        "value" => $shopProduct->getTotalPrice(),
                         'currency_code' => strtoupper($shopProduct->currency_code),
                         'breakdown' => [
-                            'item_total' =>
-                            [
+                            'item_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
                                 'value' => number_format($price, 2),
                             ],
-                            'tax_total' =>
-                            [
+                            'tax_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
                                 'value' => $shopProduct->getTaxValue(),
                             ]
@@ -98,7 +103,7 @@ static function PaypalPay(Request $request): void
             ],
             "application_context" => [
                 "cancel_url" => route('payment.Cancel'),
-                "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id, 'couponCode' => $coupon_code]),
+                "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id, 'couponCode' => $couponCode]),
                 'brand_name' =>  config('app.name', 'CtrlPanel.GG'),
                 'shipping_preference'  => 'NO_SHIPPING'
             ]
@@ -138,7 +143,7 @@ static function PaypalSuccess(Request $laravelRequest): void
 
         $payment = Payment::findOrFail($laravelRequest->payment);
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-				$coupon_code = $laravelRequest->input('couponCode');
+		$coupon_code = $laravelRequest->input('couponCode');
 
         $request = new OrdersCaptureRequest($laravelRequest->input('token'));
         $request->prefer('return=representation');
@@ -153,11 +158,11 @@ static function PaypalSuccess(Request $laravelRequest): void
                     'payment_id' => $response->result->id,
                 ]);
 
-								// increase the use of the coupon when the payment is confirmed.
-								if ($coupon_code) {
-									$coupon = new Coupon;
-									$coupon->incrementUses($coupon_code);
-								}
+                // increase the use of the coupon when the payment is confirmed.
+                if ($coupon_code) {
+                    $coupon = new Coupon;
+                    $coupon->incrementUses($coupon_code);
+                }
 
                 event(new UserUpdateCreditsEvent($user));
                 event(new PaymentEvent($user, $payment, $shopProduct));
diff --git a/app/Extensions/PaymentGateways/PayPal/web_routes.php b/app/Extensions/PaymentGateways/PayPal/web_routes.php
index 95ef6ef2e..17d1ed028 100644
--- a/app/Extensions/PaymentGateways/PayPal/web_routes.php
+++ b/app/Extensions/PaymentGateways/PayPal/web_routes.php
@@ -4,8 +4,8 @@
 use App\Extensions\PaymentGateways\PayPal\PayPalExtension;
 
 Route::middleware(['web', 'auth'])->group(function () {
-    Route::get('payment/PayPalPay/{shopProduct}', function () {
-        PayPalExtension::PaypalPay(request());
+    Route::get('payment/PayPalPay/{shopProduct}', function (PayPalExtension $payPalExtension) {
+        $payPalExtension->PaypalPay(request());
     })->name('payment.PayPalPay');
 
     Route::get(
diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php
index 44c3d6181..396e29366 100644
--- a/app/Http/Controllers/Admin/CouponController.php
+++ b/app/Http/Controllers/Admin/CouponController.php
@@ -154,6 +154,6 @@ public function destroy(Coupon $coupon)
 
     public function redeem(Request $request)
     {
-        return $this->validateCoupon($request);
+        return $this->validateCoupon($request->user(), $request->input('couponCode'), $request->input('productId'));
     }
 }
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 7c85d44e3..5ab740d9f 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -130,7 +130,6 @@ public function pay(Request $request)
     {
         $product = ShopProduct::find($request->product_id);
         $paymentGateway = $request->payment_method;
-        $coupon_data = null;
         $coupon_code = $request->coupon_code;
 
         // on free products, we don't need to use a payment gateway
@@ -140,18 +139,9 @@ public function pay(Request $request)
         }
 
         if ($coupon_code) {
-            $isValidCoupon = $this->validateCoupon($request);
-
-            if ($isValidCoupon->getStatusCode() == 200) {
-                $coupon_data = $isValidCoupon;
-                $discountPrice = $this->calcDiscount($product, $isValidCoupon->getData());
-            }
-        }
-
-        if ($coupon_data) {
             return redirect()->route('payment.' . $paymentGateway . 'Pay', [
                 'shopProduct' => $product->id,
-                'discountPrice' => $discountPrice
+                'couponCode' => $coupon_code
             ]);
         }
 
@@ -166,11 +156,6 @@ public function Cancel(Request $request)
         return redirect()->route('store.index')->with('info', 'Payment was Canceled');
     }
 
-    protected function getCouponDiscount(float $productPrice, string $discount)
-    {
-        return $productPrice - ($productPrice * $discount / 100);
-    }
-
     /**
      * @return JsonResponse|mixed
      *
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index 9b8497515..d7f0efb38 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -40,7 +40,7 @@ public function getStatus()
             return 'USES_LIMIT_REACHED';
         }
 
-        if (! is_null($this->expires_at)) {
+        if (!is_null($this->expires_at)) {
             $expires_at = Carbon::createFromTimeString($this->expires_at)->timestamp;
 
             if ($expires_at <= Carbon::now()->timestamp) {
@@ -59,9 +59,9 @@ public function getStatus()
      *
      * @return bool
      */
-    public function isLimitsUsesReached($request, $coupon_settings): bool
+    public function isLimitsUsesReached($requestUser, $coupon_settings): bool
     {
-        $coupon_uses = $request->user()->coupons()->where('id', $this->id)->count();
+        $coupon_uses = $requestUser->coupons()->where('id', $this->id)->count();
 
         return $coupon_uses >= $coupon_settings->max_uses_per_user ? true : false;
     }
diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php
index 319fd890e..be4da4ad8 100644
--- a/app/Traits/Coupon.php
+++ b/app/Traits/Coupon.php
@@ -11,9 +11,10 @@
 
 trait Coupon
 {
-    public function validateCoupon(Request $request): JsonResponse
+    public function validateCoupon($requestUser, $couponCode, $productId): JsonResponse
     {
-        $coupon = CouponModel::where('code', $request->input('coupon_code'))->first();
+        $coupon = CouponModel::where('code', $couponCode)->first();
+        $shopProduct = ShopProduct::findOrFail($productId);
         $coupon_settings = new CouponSettings;
         $response = response()->json([
             'isValid' => false,
@@ -21,6 +22,14 @@ public function validateCoupon(Request $request): JsonResponse
         ], 404);
 
         if (!is_null($coupon)) {
+            if (is_string($coupon->value)) {
+                $coupon->value = floatval($coupon->value);
+            }
+
+            if (is_string($shopProduct->price)) {
+                $shopProduct->price = floatval($shopProduct->price);
+            }
+
             if ($coupon->getStatus() == 'USES_LIMIT_REACHED') {
                 $response = response()->json([
                     'isValid' => false,
@@ -39,7 +48,7 @@ public function validateCoupon(Request $request): JsonResponse
                 return $response;
             }
 
-            if ($coupon->isLimitsUsesReached($request, $coupon_settings)) {
+            if ($coupon->isLimitsUsesReached($requestUser, $coupon_settings)) {
                 $response = response()->json([
                     'isValid' => false,
                     'error' => __('You have reached the maximum uses of this coupon.')
@@ -48,6 +57,15 @@ public function validateCoupon(Request $request): JsonResponse
                 return $response;
             }
 
+            if ($coupon->type === 'amount' && $coupon->value >= $shopProduct->price) {
+                $response = response()->json([
+                    'isValid' => false,
+                    'error' => __('The coupon you are trying to use would give you 100% off, so it cannot be used for this product, sorry.')
+                ], 422);
+
+                return $response;
+            }
+
             $response = response()->json([
                 'isValid' => true,
                 'couponCode' => $coupon->code,
@@ -59,14 +77,12 @@ public function validateCoupon(Request $request): JsonResponse
         return $response;
     }
 
-    public function calcDiscount(ShopProduct $product, stdClass $data)
+    public function calcDiscount($productPrice, stdClass $data)
     {
 
         if ($data->isValid) {
-            $productPrice = $product->price;
-
             if (is_string($productPrice)) {
-                $productPrice = floatval($product->price);
+                $productPrice = floatval($productPrice);
             }
 
             if ($data->couponType === 'percentage') {
@@ -82,5 +98,7 @@ public function calcDiscount(ShopProduct $product, stdClass $data)
 
             return $productPrice - $data->couponValue;
         }
+
+        return $productPrice;
     }
 }
diff --git a/database/migrations/2023_05_11_153719_create_coupons_table.php b/database/migrations/2023_05_11_153719_create_coupons_table.php
index 48048f6ab..db26a65b5 100644
--- a/database/migrations/2023_05_11_153719_create_coupons_table.php
+++ b/database/migrations/2023_05_11_153719_create_coupons_table.php
@@ -17,10 +17,10 @@ public function up()
             $table->id();
             $table->string('code')->unique();
             $table->enum('type', ['percentage', 'amount']);
-            $table->integer('value');
+            $table->decimal('value', 10);
             $table->integer('uses')->default(0);
             $table->integer('max_uses');
-            $table->timestamp('expires_at');
+            $table->timestamp('expires_at')->nullable();
             $table->timestamps();
         });
     }
diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index 690e6c044..59ea53c18 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -185,6 +185,8 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                             <div id="coupon_discount_details" class="d-flex justify-content-between" style="display: none !important;">
                                               <span class="text-muted d-inline-block">
                                                 {{ __('Coupon Discount') }}
+                                              </span>
+                                              <span id="coupon_discount_value" class="text-muted d-inline-block">
 
                                               </span>
                                             </div>
@@ -199,8 +201,13 @@ class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue)
                                             <hr class="text-white border-secondary">
                                             <div class="d-flex justify-content-between">
                                                 <span class="text-muted d-inline-block">{{ __('Total') }}</span>
+                                                <input id="total_price_input" type="hidden" value="{{ $product->getTotalPrice() }}">
                                                 <span
-                                                    class="text-muted d-inline-block">{{ $product->formatToCurrency($total) }}</span>
+                                                  id="total_price"
+                                                  class="text-muted d-inline-block"
+                                                >
+                                                  {{ $product->formatToCurrency($total) }}
+                                                </span>
                                             </div>
                                             <template x-if="payment_method">
                                                 <div class="d-flex justify-content-between">
@@ -240,27 +247,46 @@ class="btn btn-success float-right w-100">
 
     <script>
       $(document).ready(function() {
+        const productId = $("[name='product_id']").val()
         let hasCouponCodeValue = $('#coupon_code').val().trim() !== ''
 
         $('#coupon_code').on('change', function(e) {
           hasCouponCodeValue = e.target.value !== ''
         })
 
+        function calcPriceWithCouponDiscount(couponValue, couponType) {
+          let totalPrice = $('#total_price_input').val()
+
+          if (typeof totalPrice == 'string') {
+            totalPrice = parseFloat(totalPrice)
+          }
+
+          if (couponType === 'percentage') {
+            totalPrice = totalPrice - (totalPrice * couponValue / 100)
+            $('#coupon_discount_value').text("- " + couponValue + "%")
+          } else if (couponType === 'amount') {
+            totalPrice = totalPrice - couponValue
+            $('#coupon_discount_value').text(totalPrice)
+          }
+
+          $('#total_price').text(totalPrice)
+          $('#total_price_input').val(totalPrice)
+        }
+
 				function checkCoupon() {
 					const couponCode = $('#coupon_code').val()
 
 					$.ajax({
 						url: "{{ route('admin.coupon.redeem') }}",
 						method: 'POST',
-						data: { coupon_code: couponCode },
+						data: { couponCode: couponCode, productId: productId },
 						success: function(response) {
 							if (response.isValid && response.couponCode) {
                 Swal.fire({
                   icon: 'success',
-                  text: `The coupon '${response.couponCode}' was successfully inserted in your purchase.`,
+                  text: 'The coupon was successfully added to your purchase.',
                 }).then(function(isConfirmed) {
-                  console.log('confirmou')
-
+                  calcPriceWithCouponDiscount(response.couponValue, response.couponType)
                   $('#submit_form_button').prop('disabled', false).removeClass('disabled')
                   $('#send_coupon_code').prop('disabled', true)
                   $('#coupon_discount_details').prop('disabled', false).show()

From 490e11572d73b1d5daf1e133356a33e29cd20aec Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Thu, 18 May 2023 14:33:42 +0000
Subject: [PATCH 191/514] Use casts instead of converting values

---
 .../PaymentGateways/PayPal/PayPalExtension.php  |  6 +-----
 app/Models/Coupon.php                           | 17 ++++++++++++++---
 app/Models/ShopProduct.php                      |  7 +++++++
 app/Traits/Coupon.php                           | 12 ------------
 4 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index 1586804b5..7667c08d9 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -47,13 +47,9 @@ public function PaypalPay(Request $request): void
         $discount = PartnerDiscount::getDiscount();
         $couponCode = $request->input('couponCode');
         $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
-
-        if (is_string($shopProduct->price)) {
-            $shopProduct->price = floatval($shopProduct->price);
-        }
-
         $price = $shopProduct->price;
 
+		// Coupon Discount.
         if ($isValidCoupon->getStatusCode() == 200) {
             $price = $this->calcDiscount($price, $isValidCoupon->getData());
         }
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index d7f0efb38..20657db5b 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -10,6 +10,9 @@ class Coupon extends Model
 {
     use HasFactory;
 
+    /**
+     * @var string[]
+     */
     protected $fillable = [
         'code',
         'type',
@@ -19,6 +22,16 @@ class Coupon extends Model
         'expires_at'
     ];
 
+    /**
+     * @var string[]
+     */
+    protected $casts = [
+        'value' => 'float',
+        'uses' => 'integer',
+        'max_uses' => 'integer',
+        'expires_at' => 'timestamp'
+    ];
+
     /**
      * Returns the date format used by the coupons.
      *
@@ -41,9 +54,7 @@ public function getStatus()
         }
 
         if (!is_null($this->expires_at)) {
-            $expires_at = Carbon::createFromTimeString($this->expires_at)->timestamp;
-
-            if ($expires_at <= Carbon::now()->timestamp) {
+            if ($this->expires_at <= Carbon::now()->timestamp) {
                 return __('EXPIRED');
             }
         }
diff --git a/app/Models/ShopProduct.php b/app/Models/ShopProduct.php
index cfe3f7838..12b870a28 100644
--- a/app/Models/ShopProduct.php
+++ b/app/Models/ShopProduct.php
@@ -36,6 +36,13 @@ public function getActivitylogOptions(): LogOptions
         'disabled',
     ];
 
+    /**
+     * @var string[]
+     */
+    protected $casts = [
+        'price' => 'float'
+    ];
+
     public static function boot()
     {
         parent::boot();
diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php
index be4da4ad8..091fa855b 100644
--- a/app/Traits/Coupon.php
+++ b/app/Traits/Coupon.php
@@ -22,14 +22,6 @@ public function validateCoupon($requestUser, $couponCode, $productId): JsonRespo
         ], 404);
 
         if (!is_null($coupon)) {
-            if (is_string($coupon->value)) {
-                $coupon->value = floatval($coupon->value);
-            }
-
-            if (is_string($shopProduct->price)) {
-                $shopProduct->price = floatval($shopProduct->price);
-            }
-
             if ($coupon->getStatus() == 'USES_LIMIT_REACHED') {
                 $response = response()->json([
                     'isValid' => false,
@@ -81,10 +73,6 @@ public function calcDiscount($productPrice, stdClass $data)
     {
 
         if ($data->isValid) {
-            if (is_string($productPrice)) {
-                $productPrice = floatval($productPrice);
-            }
-
             if ($data->couponType === 'percentage') {
                 return $productPrice - ($productPrice * $data->couponValue / 100);
             }

From 640468acbee4cb5724545645c828089d7c022508 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Thu, 18 May 2023 19:51:10 +0000
Subject: [PATCH 192/514] Finish the coupon base.

---
 app/Console/Commands/DeleteExpiredCoupons.php |  42 +++
 app/Console/Kernel.php                        |   2 +
 app/Events/CouponUsedEvent.php                |  25 ++
 .../PayPal/PayPalExtension.php                |   8 +-
 .../Controllers/Admin/CouponController.php    | 149 ++++++---
 app/Listeners/CouponUsed.php                  |  47 +++
 app/Providers/EventServiceProvider.php        |   5 +
 app/Settings/CouponSettings.php               |  18 +-
 ...23_05_12_170041_create_coupon_settings.php |   4 +
 routes/web.php                                |   1 +
 .../views/admin/coupons/create.blade.php      |  76 ++---
 .../views/admin/coupons/edit.blade.php        | 291 ++++++++++++++++++
 .../views/admin/coupons/index.blade.php       |  39 ++-
 13 files changed, 626 insertions(+), 81 deletions(-)
 create mode 100644 app/Console/Commands/DeleteExpiredCoupons.php
 create mode 100644 app/Events/CouponUsedEvent.php
 create mode 100644 app/Listeners/CouponUsed.php
 create mode 100644 themes/default/views/admin/coupons/edit.blade.php

diff --git a/app/Console/Commands/DeleteExpiredCoupons.php b/app/Console/Commands/DeleteExpiredCoupons.php
new file mode 100644
index 000000000..9d3ded87a
--- /dev/null
+++ b/app/Console/Commands/DeleteExpiredCoupons.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Settings\CouponSettings;
+use App\Models\Coupon;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+
+
+class DeleteExpiredCoupons extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'coupons:delete';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Delete expired coupons from DB.';
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle(CouponSettings $couponSettings)
+    {
+        if ($couponSettings->delete_coupon_on_expires) {
+            $expired_coupons = Coupon::where('expires_at', '<=', Carbon::now(config('app.timezone')))->get();
+
+            foreach ($expired_coupons as $expired_coupon) {
+                $expired_coupon->delete();
+            }
+        }
+    }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 64af565f9..a1bd37d22 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel
     protected $commands = [
         Commands\ChargeCreditsCommand::class,
         Commands\ChargeServers::class,
+        Commands\DeleteExpiredCoupons::class,
     ];
 
     /**
@@ -29,6 +30,7 @@ protected function schedule(Schedule $schedule)
         $schedule->command('servers:charge')->everyMinute();
         $schedule->command('cp:versioncheck:get')->daily();
         $schedule->command('payments:open:clear')->daily();
+        $schedule->command('coupons:delete')->daily();
 
         //log cronjob activity
         $schedule->call(function () {
diff --git a/app/Events/CouponUsedEvent.php b/app/Events/CouponUsedEvent.php
new file mode 100644
index 000000000..49168b602
--- /dev/null
+++ b/app/Events/CouponUsedEvent.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Events;
+
+use App\Models\Coupon;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class CouponUsedEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public Coupon $coupon;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(Coupon $coupon)
+    {
+        $this->coupon = $coupon;
+    }
+}
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index 7667c08d9..07771e486 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -2,6 +2,7 @@
 
 namespace App\Extensions\PaymentGateways\PayPal;
 
+use App\Events\CouponUsedEvent;
 use App\Helpers\AbstractExtension;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
@@ -56,6 +57,7 @@ public function PaypalPay(Request $request): void
 
         // Partner Discount.
         $price = $price - ($price * $discount / 100);
+        $price = number_format($price, 2);
 
         // create a new payment
         $payment = Payment::create([
@@ -82,12 +84,12 @@ public function PaypalPay(Request $request): void
                     "reference_id" => uniqid(),
                     "description" => $shopProduct->display . ($discount ? (" (" . __('Discount') . " " . $discount . '%)') : ""),
                     "amount" => [
-                        "value" => $shopProduct->getTotalPrice(),
+                        "value" => $price,
                         'currency_code' => strtoupper($shopProduct->currency_code),
                         'breakdown' => [
                             'item_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
-                                'value' => number_format($price, 2),
+                                'value' => $price
                             ],
                             'tax_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
@@ -158,6 +160,8 @@ static function PaypalSuccess(Request $laravelRequest): void
                 if ($coupon_code) {
                     $coupon = new Coupon;
                     $coupon->incrementUses($coupon_code);
+
+                    event(new CouponUsedEvent($coupon));
                 }
 
                 event(new UserUpdateCreditsEvent($user));
diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php
index 396e29366..1287a57c7 100644
--- a/app/Http/Controllers/Admin/CouponController.php
+++ b/app/Http/Controllers/Admin/CouponController.php
@@ -4,6 +4,7 @@
 
 use App\Http\Controllers\Controller;
 use App\Models\Coupon;
+use App\Settings\LocaleSettings;
 use App\Traits\Coupon as CouponTrait;
 use Illuminate\Http\Request;
 use Carbon\Carbon;
@@ -20,11 +21,13 @@ class CouponController extends Controller
      *
      * @return \Illuminate\Http\Response
      */
-    public function index()
+    public function index(LocaleSettings $localeSettings)
     {
         $this->checkPermission(self::READ_PERMISSION);
 
-        return view('admin.coupons.index');
+        return view('admin.coupons.index', [
+            'locale_datatables' => $localeSettings->datatables
+        ]);
     }
 
     /**
@@ -47,21 +50,12 @@ public function create()
      */
     public function store(Request $request)
     {
-        $coupon_code = $request->input('coupon_code');
-        $coupon_type = $request->input('coupon_type');
-        $coupon_value = $request->input('coupon_value');
-        $coupon_max_uses = $request->input('coupon_uses');
-        $coupon_datepicker = $request->input('datepicker');
+        $coupon_code = $request->input('code');
         $random_codes_amount = $request->input('range_codes');
-        $rules = [
-            "coupon_type" => "required|string|in:percentage,amount",
-            "coupon_uses" => "required|integer|digits_between:1,100",
-            "coupon_value" => "required|numeric|between:0,100",
-            "datepicker" => "required|date|after:" . Carbon::now()->format(Coupon::formatDate())
-        ];
+        $rules = $this->requestRules($request);
 
-        // If for some reason you pass both fields at once.
-        if ($coupon_code && $random_codes_amount) {
+         // If for some reason you pass both fields at once.
+         if ($coupon_code && $random_codes_amount) {
             return redirect()->back()->with('error', __('Only one of the two code inputs must be provided.'))->withInput($request->all());
         }
 
@@ -69,12 +63,6 @@ public function store(Request $request)
             return redirect()->back()->with('error', __('At least one of the two code inputs must be provided.'))->withInput($request->all());
         }
 
-        if ($coupon_code) {
-            $rules['coupon_code'] = 'required|string|min:4';
-        } elseif ($random_codes_amount) {
-            $rules['range_codes'] = 'required|integer|digits_between:1,100';
-        }
-
         $request->validate($rules);
 
         if (array_key_exists('range_codes', $rules)) {
@@ -85,23 +73,17 @@ public function store(Request $request)
             foreach ($coupons as $coupon) {
                 $data[] = [
                     'code' => $coupon,
-                    'type' => $coupon_type,
-                    'value' => $coupon_value,
-                    'max_uses' => $coupon_max_uses,
-                    'expires_at' => $coupon_datepicker,
+                    'type' => $request->input('type'),
+                    'value' => $request->input('value'),
+                    'max_uses' => $request->input('max_uses'),
+                    'expires_at' => $request->input('expires_at'),
                     'created_at' => Carbon::now(), // Does not fill in by itself when using the 'insert' method.
                     'updated_at' => Carbon::now()
                 ];
             }
             Coupon::insert($data);
         } else {
-            Coupon::create([
-                'code' => $coupon_code,
-                'type' => $coupon_type,
-                'value' => $coupon_value,
-                'max_uses' => $coupon_max_uses,
-                'expires_at' => $coupon_datepicker,
-            ]);
+            Coupon::create($request->except('_token'));
         }
 
         return redirect()->route('admin.coupons.index')->with('success', __("The coupon's was registered successfully."));
@@ -126,7 +108,12 @@ public function show(Coupon $coupon)
      */
     public function edit(Coupon $coupon)
     {
-        //
+        $this->checkPermission(self::WRITE_PERMISSION);
+
+        return view('admin.coupons.edit', [
+            'coupon' => $coupon,
+            'expired_at' => $coupon->expires_at ? Carbon::createFromTimestamp($coupon->expires_at) : null
+        ]);
     }
 
     /**
@@ -138,7 +125,23 @@ public function edit(Coupon $coupon)
      */
     public function update(Request $request, Coupon $coupon)
     {
-        //
+        $coupon_code = $request->input('code');
+        $random_codes_amount = $request->input('range_codes');
+        $rules = $this->requestRules($request);
+
+        // If for some reason you pass both fields at once.
+        if ($coupon_code && $random_codes_amount) {
+            return redirect()->back()->with('error', __('Only one of the two code inputs must be provided.'))->withInput($request->all());
+        }
+
+        if (!$coupon_code && !$random_codes_amount) {
+            return redirect()->back()->with('error', __('At least one of the two code inputs must be provided.'))->withInput($request->all());
+        }
+
+        $request->validate($rules);
+        $coupon->update($request->except('_token'));
+
+        return redirect()->route('admin.coupons.index')->with('success', __('coupon has been updated!'));
     }
 
     /**
@@ -149,11 +152,87 @@ public function update(Request $request, Coupon $coupon)
      */
     public function destroy(Coupon $coupon)
     {
-        //
+        $this->checkPermission(self::WRITE_PERMISSION);
+        $coupon->delete();
+
+        return redirect()->back()->with('success', __('coupon has been removed!'));
+    }
+
+    private function requestRules(Request $request)
+    {
+        $coupon_code = $request->input('code');
+        $random_codes_amount = $request->input('range_codes');
+        $rules = [
+            "type" => "required|string|in:percentage,amount",
+            "max_uses" => "required|integer|digits_between:1,100",
+            "value" => "required|numeric|between:0,100",
+            "expires_at" => "nullable|date|after:" . Carbon::now()->format(Coupon::formatDate())
+        ];
+
+        if ($coupon_code) {
+            $rules['code'] = "required|string|min:4";
+        } elseif ($random_codes_amount) {
+            $rules['range_codes'] = 'required|integer|digits_between:1,100';
+        }
+
+        return $rules;
     }
 
     public function redeem(Request $request)
     {
         return $this->validateCoupon($request->user(), $request->input('couponCode'), $request->input('productId'));
     }
+
+    public function dataTable()
+    {
+        $query = Coupon::query();
+
+        return datatables($query)
+            ->addColumn('actions', function(Coupon $coupon) {
+                return '
+                    <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.coupons.edit', $coupon->id).'" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+
+                    <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.coupons.destroy', $coupon->id).'">
+                        '.csrf_field().'
+                        '.method_field('DELETE').'
+                        <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                    </form>
+                ';
+            })
+            ->addColumn('status', function(Coupon $coupon) {
+                $color = 'success';
+                $status = $coupon->getStatus();
+
+                if ($status != __('VALID')) {
+                    $color = 'danger';
+                }
+
+                return '<span class="badge badge-'.$color.'">'.str_replace('_', ' ', $status).'</span>';
+            })
+            ->editColumn('uses', function (Coupon $coupon) {
+                return "{$coupon->uses} / {$coupon->max_uses}";
+            })
+            ->editColumn('value', function (Coupon $coupon) {
+                if ($coupon->type === 'percentage') {
+                    return $coupon->value . "%";
+                }
+
+                return number_format($coupon->value, 2, '.', '');
+            })
+            ->editColumn('expires_at', function (Coupon $coupon) {
+                if (!$coupon->expires_at) {
+                    return __('Never');
+                }
+
+                return Carbon::createFromTimestamp($coupon->expires_at);
+            })
+            ->editColumn('created_at', function(Coupon $coupon) {
+                return Carbon::createFromTimeString($coupon->created_at);
+            })
+            ->editColumn('code', function (Coupon $coupon) {
+                return "<code>{$coupon->code}</code>";
+            })
+            ->rawColumns(['actions', 'code', 'status'])
+            ->make();
+    }
 }
diff --git a/app/Listeners/CouponUsed.php b/app/Listeners/CouponUsed.php
new file mode 100644
index 000000000..75ced4eb4
--- /dev/null
+++ b/app/Listeners/CouponUsed.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\CouponUsedEvent;
+use App\Settings\CouponSettings;
+use Carbon\Carbon;
+
+class CouponUsed
+{
+    private $delete_coupon_on_expires;
+    private $delete_coupon_on_uses_reached;
+
+    /**
+     * Create the event listener.
+     *
+     * @return void
+     */
+    public function __construct(CouponSettings $couponSettings)
+    {
+        $this->delete_coupon_on_expires = $couponSettings->delete_coupon_on_expires;
+        $this->delete_coupon_on_uses_reached = $couponSettings->delete_coupon_on_uses_reached;
+    }
+
+    /**
+     * Handle the event.
+     *
+     * @param  \App\Events\CouponUsedEvent  $event
+     * @return void
+     */
+    public function handle(CouponUsedEvent $event)
+    {
+        if ($this->delete_coupon_on_expires) {
+            if (!is_null($event->coupon->expired_at)) {
+                if ($event->coupon->expires_at <= Carbon::now()->timestamp) {
+                    $event->coupon->delete();
+                }
+            }
+        }
+
+        if ($this->delete_coupon_on_uses_reached) {
+            if ($event->coupon->uses >= $event->coupon->max_uses) {
+                $event->coupon->delete();
+            }
+        }
+    }
+}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index bdd71a3ae..2ac9182dd 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -4,6 +4,8 @@
 
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
+use App\Events\CouponUsedEvent;
+use App\Listeners\CouponUsed;
 use App\Listeners\CreateInvoice;
 use App\Listeners\UnsuspendServers;
 use App\Listeners\UserPayment;
@@ -31,6 +33,9 @@ class EventServiceProvider extends ServiceProvider
             CreateInvoice::class,
             UserPayment::class,
         ],
+        CouponUsedEvent::class => [
+            CouponUsed::class
+        ],
         SocialiteWasCalled::class => [
             // ... other providers
             'SocialiteProviders\\Discord\\DiscordExtendSocialite@handle',
diff --git a/app/Settings/CouponSettings.php b/app/Settings/CouponSettings.php
index 45f9c25bf..29ec33320 100644
--- a/app/Settings/CouponSettings.php
+++ b/app/Settings/CouponSettings.php
@@ -7,6 +7,8 @@
 class CouponSettings extends Settings
 {
 	public ?int $max_uses_per_user;
+    public ?bool $delete_coupon_on_expires;
+    public ?bool $delete_coupon_on_uses_reached;
 
     public static function group(): string
     {
@@ -20,7 +22,9 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'max_uses_per_user' => 'required|integer'
+            'max_uses_per_user' => 'required|integer',
+            'delete_coupon_on_expires' => 'required|boolean',
+            'delete_coupon_on_uses_reached' => 'required|boolean',
         ];
     }
 
@@ -36,7 +40,17 @@ public static function getOptionInputData()
             'max_uses_per_user' => [
                 'label' => 'Max Uses Per User',
                 'type' => 'number',
-                'description' => 'Maximum number of uses that a user can make of the same coupon.',
+                'description' => 'Maximum number of uses that a user can make of the same coupon.'
+            ],
+            'delete_coupon_on_expires' => [
+                'label' => 'Delete Coupon On Expires',
+                'type' => 'boolean',
+                'description' => 'Automatically deletes the coupon if it expires.'
+            ],
+            'delete_coupon_on_uses_reached' => [
+                'label' => 'Delete Coupon When Max Uses Reached',
+                'type' => 'boolean',
+                'description' => 'Delete a coupon as soon as its maximum usage is reached.'
             ]
         ];
     }
diff --git a/database/settings/2023_05_12_170041_create_coupon_settings.php b/database/settings/2023_05_12_170041_create_coupon_settings.php
index 77505cea8..9ff792ce5 100644
--- a/database/settings/2023_05_12_170041_create_coupon_settings.php
+++ b/database/settings/2023_05_12_170041_create_coupon_settings.php
@@ -7,10 +7,14 @@
     public function up(): void
     {
         $this->migrator->add('coupon.max_uses_per_user', 1);
+        $this->migrator->add('coupon.delete_coupon_on_expires', false);
+        $this->migrator->add('coupon.delete_coupon_on_uses_reached', false);
     }
 
     public function down(): void
     {
         $this->migrator->delete('coupon.max_uses_per_user');
+        $this->migrator->delete('coupon.delete_coupon_on_expires');
+        $this->migrator->delete('coupon.delete_coupon_on_uses_reached');
     }
 };
diff --git a/routes/web.php b/routes/web.php
index bdfd06f5c..a6a2ab3cc 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -201,6 +201,7 @@
         Route::resource('partners', PartnerController::class);
 
         //coupons
+        Route::get('coupons/datatable', [CouponController::class, 'dataTable'])->name('coupons.datatable');
         Route::post('coupons/redeem', [CouponController::class, 'redeem'])->name('coupon.redeem');
         Route::resource('coupons', CouponController::class);
 
diff --git a/themes/default/views/admin/coupons/create.blade.php b/themes/default/views/admin/coupons/create.blade.php
index 2b19d6a77..7cef744e7 100644
--- a/themes/default/views/admin/coupons/create.blade.php
+++ b/themes/default/views/admin/coupons/create.blade.php
@@ -84,7 +84,7 @@ class="form-control @error('range_codes') is-invalid @enderror"
                   @enderror
                 </div>
                 <div id="coupon_code_element" class="form-group">
-                  <label for="coupon_code">
+                  <label for="code">
                     {{ __('Coupon Code') }}
                     <i
                       data-toggle="popover"
@@ -95,13 +95,13 @@ class="fas fa-info-circle">
                   </label>
                   <input
                     type="text"
-                    id="coupon_code"
-                    name="coupon_code"
+                    id="code"
+                    name="code"
                     placeholder="SUMMER"
-                    class="form-control @error('coupon_code') is-invalid @enderror"
-                    value="{{ old('coupon_code') }}"
+                    class="form-control @error('code') is-invalid @enderror"
+                    value="{{ old('code') }}"
                   >
-                  @error('coupon_code')
+                  @error('code')
                     <div class="text-danger">
                       {{ $message }}
                     </div>
@@ -109,7 +109,7 @@ class="form-control @error('coupon_code') is-invalid @enderror"
                 </div>
                 <div class="form-group">
                   <div class="custom-control mb-3 p-0">
-                    <label for="coupon_type">
+                    <label for="type">
                       {{ __('Coupon Type') }}
                       <i
                         data-toggle="popover"
@@ -119,17 +119,17 @@ class="fas fa-info-circle">
                       </i>
                     </label>
                     <select
-                      name="coupon_type"
-                      id="coupon_type"
-                      class="custom-select @error('coupon_type') is_invalid @enderror"
+                      name="type"
+                      id="type"
+                      class="custom-select @error('type') is_invalid @enderror"
                       style="width: 100%; cursor: pointer;"
                       autocomplete="off"
                       required
                     >
-                      <option value="percentage" @if(old('coupon_type') == 'percentage') selected @endif>{{ __('Percentage') }}</option>
-                      <option value="amount" @if(old('coupon_type') == 'amount') selected @endif>{{ __('Amount') }}</option>
+                      <option value="percentage" @if(old('type') == 'percentage') selected @endif>{{ __('Percentage') }}</option>
+                      <option value="amount" @if(old('type') == 'amount') selected @endif>{{ __('Amount') }}</option>
                     </select>
-                    @error('coupon_type')
+                    @error('type')
                       <div class="text-danger">
                         {{ $message }}
                       </div>
@@ -138,7 +138,7 @@ class="custom-select @error('coupon_type') is_invalid @enderror"
                 </div>
                 <div class="form-group">
                   <div class="input-group d-flex flex-column">
-                    <label for="coupon_value">
+                    <label for="value">
                       {{ __('Coupon Value') }}
                       <i
                         data-toggle="popover"
@@ -149,18 +149,18 @@ class="fas fa-info-circle">
                     </label>
                     <div class="d-flex">
                       <input
-                        name="coupon_value"
-                        id="coupon_value"
+                        name="value"
+                        id="value"
                         type="number"
                         step="any"
                         min="1"
                         max="100"
-                        class="form-control @error('coupon_value') is-invalid @enderror"
-                        value="{{ old('coupon_value') }}"
+                        class="form-control @error('value') is-invalid @enderror"
+                        value="{{ old('value') }}"
                       >
                       <span id="input_percentage" class="input-group-text">%</span>
                     </div>
-                    @error('coupon_value')
+                    @error('value')
                       <div class="text-danger">
                         {{ $message }}
                       </div>
@@ -168,7 +168,7 @@ class="form-control @error('coupon_value') is-invalid @enderror"
                   </div>
                 </div>
                 <div class="form-group">
-                  <label for="coupon_uses">
+                  <label for="max_uses">
                     {{ __('Max uses') }}
                     <i
                       data-toggle="popover"
@@ -178,43 +178,43 @@ class="fas fa-info-circle">
                     </i>
                   </label>
                   <input
-                    name="coupon_uses"
-                    id="coupon_uses"
+                    name="max_uses"
+                    id="max_uses"
                     type="number"
                     step="any"
                     min="1"
                     max="100"
-                    class="form-control @error('coupon_uses') is-invalid @enderror"
-                    value="{{ old('coupon_uses') }}"
+                    class="form-control @error('max_uses') is-invalid @enderror"
+                    value="{{ old('max_uses') }}"
                   >
-                  @error('coupon_uses')
+                  @error('max_uses')
                     <div class="text-danger">
                       {{ $message }}
                     </div>
                   @enderror
                 </div>
-                <div class="d-flex flex-column input-group form-group date" id="datepicker" data-target-input="nearest">
-                  <label for="datepicker">
+                <div class="d-flex flex-column input-group form-group date" id="expires_at" data-target-input="nearest">
+                  <label for="expires_at">
                     {{ __('Expires at') }}
                     <i
                       data-toggle="popover"
                       data-trigger="hover"
-                      data-content="{{__('The date when the coupon will expire.')}}"
+                      data-content="{{__('The date when the coupon will expire (If no date is provided, the coupon never expires).')}}"
                       class="fas fa-info-circle">
                     </i>
                   </label>
                   <div class="d-flex">
                     <input
-                      value="{{old('datepicker')}}"
-                      name="datepicker"
+                      value="{{ old('expires_at') }}"
+                      name="expires_at"
                       placeholder="yyyy-mm-dd hh:mm:ss"
                       type="text"
-                      class="form-control @error('datepicker') is-invalid @enderror datetimepicker-input"
-                      data-target="#datepicker"
+                      class="form-control @error('expires_at') is-invalid @enderror datetimepicker-input"
+                      data-target="#expires_at"
                     />
                     <div
                       class="input-group-append"
-                      data-target="#datepicker"
+                      data-target="#expires_at"
                       data-toggle="datetimepicker"
                     >
                       <div class="input-group-text">
@@ -222,7 +222,7 @@ class="input-group-append"
                       </div>
                     </div>
                   </div>
-                  @error('datepicker')
+                  @error('expires_at')
                     <div class="text-danger">
                       {{ $message }}
                     </div>
@@ -244,7 +244,7 @@ class="input-group-append"
 
   <script>
     $(document).ready(function() {
-      $('#datepicker').datetimepicker({
+      $('#expires_at').datetimepicker({
         format: 'Y-MM-DD HH:mm:ss',
         icons: {
           time: 'far fa-clock',
@@ -263,8 +263,8 @@ class="input-group-append"
           $('#coupon_code_element').prop('disabled', true).hide()
           $('#range_codes_element').prop('disabled', false).show()
 
-          if ($('#coupon_code').val()) {
-            $('#coupon_code').prop('value', null)
+          if ($('#code').val()) {
+            $('#code').prop('value', null)
           }
 
         } else {
@@ -277,7 +277,7 @@ class="input-group-append"
         }
       })
 
-      $('#coupon_type').change(function() {
+      $('#type').change(function() {
         if ($(this).val() == 'percentage') {
           $('#input_percentage').prop('disabled', false).show()
         } else {
diff --git a/themes/default/views/admin/coupons/edit.blade.php b/themes/default/views/admin/coupons/edit.blade.php
new file mode 100644
index 000000000..aa3c81eec
--- /dev/null
+++ b/themes/default/views/admin/coupons/edit.blade.php
@@ -0,0 +1,291 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{__('Coupon')}}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
+                        <li class="breadcrumb-item"><a href="{{route('admin.coupons.index')}}">{{__('Coupon')}}</a>
+                        </li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{route('admin.coupons.edit' , $coupon->id)}}">{{__('Edit')}}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+
+            <div class="row">
+                <div class="col-lg-6">
+                    <div class="card">
+                        <div class="card-header">
+                            <h5 class="card-title">
+                                <i class="fas fa-money-check-alt mr-2"></i>{{__('Coupon details')}}
+                            </h5>
+                        </div>
+                        <div class="card-body">
+                          <form action="{{ route('admin.coupons.update', $coupon->id) }}" method="POST">
+                            @csrf
+                            @method('PATCH')
+
+                            <div class="d-flex flex-row-reverse">
+                              <div class="custom-control custom-switch">
+                                <input
+                                  type="checkbox"
+                                  id="random_codes"
+                                  name="random_codes"
+                                  class="custom-control-input"
+                                >
+                                <label for="random_codes" class="custom-control-label">
+                                  {{ __('Random Codes') }}
+                                  <i
+                                    data-toggle="popover"
+                                    data-trigger="hover"
+                                    data-content="{{__('Replace the creation of a single code with several at once with a custom field.')}}"
+                                    class="fas fa-info-circle">
+                                  </i>
+                                </label>
+                              </div>
+                            </div>
+                            <div id="range_codes_element" style="display: none;" class="form-group">
+                              <label for="range_codes">
+                                {{ __('Range Codes') }}
+                                <i
+                                  data-toggle="popover"
+                                  data-trigger="hover"
+                                  data-content="{{__('Generate a number of random codes.')}}"
+                                  class="fas fa-info-circle">
+                                </i>
+                              </label>
+                              <input
+                                type="number"
+                                id="range_codes"
+                                name="range_codes"
+                                step="any"
+                                min="1"
+                                max="100"
+                                class="form-control @error('range_codes') is-invalid @enderror"
+                              >
+                              @error('range_codes')
+                                <div class="text-danger">
+                                  {{ $message }}
+                                </div>
+                              @enderror
+                            </div>
+                            <div id="coupon_code_element" class="form-group">
+                              <label for="code">
+                                {{ __('Coupon Code') }}
+                                <i
+                                  data-toggle="popover"
+                                  data-trigger="hover"
+                                  data-content="{{__('The coupon code to be registered.')}}"
+                                  class="fas fa-info-circle">
+                                </i>
+                              </label>
+                              <input
+                                type="text"
+                                id="code"
+                                name="code"
+                                placeholder="SUMMER"
+                                class="form-control @error('code') is-invalid @enderror"
+                                value="{{ $coupon->code }}"
+                              >
+                              @error('code')
+                                <div class="text-danger">
+                                  {{ $message }}
+                                </div>
+                              @enderror
+                            </div>
+                            <div class="form-group">
+                              <div class="custom-control mb-3 p-0">
+                                <label for="type">
+                                  {{ __('Coupon Type') }}
+                                  <i
+                                    data-toggle="popover"
+                                    data-trigger="hover"
+                                    data-content="{{__('The way the coupon should discount.')}}"
+                                    class="fas fa-info-circle">
+                                  </i>
+                                </label>
+                                <select
+                                  name="type"
+                                  id="type"
+                                  class="custom-select @error('type') is_invalid @enderror"
+                                  style="width: 100%; cursor: pointer;"
+                                  autocomplete="off"
+                                  required
+                                >
+                                  <option value="percentage" @if($coupon->type == 'percentage') selected @endif>{{ __('Percentage') }}</option>
+                                  <option value="amount" @if($coupon->type == 'amount') selected @endif>{{ __('Amount') }}</option>
+                                </select>
+                                @error('type')
+                                  <div class="text-danger">
+                                    {{ $message }}
+                                  </div>
+                                @enderror
+                              </div>
+                            </div>
+                            <div class="form-group">
+                              <div class="input-group d-flex flex-column">
+                                <label for="value">
+                                  {{ __('Coupon Value') }}
+                                  <i
+                                    data-toggle="popover"
+                                    data-trigger="hover"
+                                    data-content="{{__('The value that the coupon will represent.')}}"
+                                    class="fas fa-info-circle">
+                                  </i>
+                                </label>
+                                <div class="d-flex">
+                                  <input
+                                    name="value"
+                                    id="value"
+                                    type="number"
+                                    step="any"
+                                    min="1"
+                                    max="100"
+                                    class="form-control @error('value') is-invalid @enderror"
+                                    value="{{ $coupon->value }}"
+                                  >
+                                  <span id="input_percentage" class="input-group-text">%</span>
+                                </div>
+                                @error('value')
+                                  <div class="text-danger">
+                                    {{ $message }}
+                                  </div>
+                                @enderror
+                              </div>
+                            </div>
+                            <div class="form-group">
+                              <label for="max_uses">
+                                {{ __('Max uses') }}
+                                <i
+                                  data-toggle="popover"
+                                  data-trigger="hover"
+                                  data-content="{{__('The maximum number of times the coupon can be used.')}}"
+                                  class="fas fa-info-circle">
+                                </i>
+                              </label>
+                              <input
+                                name="max_uses"
+                                id="max_uses"
+                                type="number"
+                                step="any"
+                                min="1"
+                                max="100"
+                                class="form-control @error('max_uses') is-invalid @enderror"
+                                value="{{ $coupon->max_uses }}"
+                              >
+                              @error('max_uses')
+                                <div class="text-danger">
+                                  {{ $message }}
+                                </div>
+                              @enderror
+                            </div>
+                            <div class="d-flex flex-column input-group form-group date" id="expires_at" data-target-input="nearest">
+                              <label for="expires_at">
+                                {{ __('Expires at') }}
+                                <i
+                                  data-toggle="popover"
+                                  data-trigger="hover"
+                                  data-content="{{__('The date when the coupon will expire (If no date is provided, the coupon never expires).')}}"
+                                  class="fas fa-info-circle">
+                                </i>
+                              </label>
+                              <div class="d-flex">
+                                <input
+                                  value="{{ $expired_at ?? '' }}"
+                                  name="expires_at"
+                                  placeholder="yyyy-mm-dd hh:mm:ss"
+                                  type="text"
+                                  class="form-control @error('expires_at') is-invalid @enderror datetimepicker-input"
+                                  data-target="#expires_at"
+                                />
+                                <div
+                                  class="input-group-append"
+                                  data-target="#expires_at"
+                                  data-toggle="datetimepicker"
+                                >
+                                  <div class="input-group-text">
+                                    <i class="fa fa-calendar"></i>
+                                  </div>
+                                </div>
+                              </div>
+                              @error('expires_at')
+                                <div class="text-danger">
+                                  {{ $message }}
+                                </div>
+                              @enderror
+                            </div>
+                            <div class="form-group text-right mb-0">
+                              <button type="submit" class="btn btn-primary">
+                                {{__('Submit')}}
+                              </button>
+                            </div>
+                          </form>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+        </div>
+    </section>
+    <!-- END CONTENT -->
+
+    <script>
+      $(document).ready(function() {
+        $('#expires_at').datetimepicker({
+          format: 'Y-MM-DD HH:mm:ss',
+          icons: {
+            time: 'far fa-clock',
+            date: 'far fa-calendar',
+            up: 'fas fa-arrow-up',
+            down: 'fas fa-arrow-down',
+            previous: 'fas fa-chevron-left',
+            next: 'fas fa-chevron-right',
+            today: 'fas fa-calendar-check',
+            clear: 'far fa-trash-alt',
+            close: 'far fa-times-circle'
+          }
+        });
+        $('#random_codes').change(function() {
+          if ($(this).is(':checked')) {
+            $('#coupon_code_element').prop('disabled', true).hide()
+            $('#range_codes_element').prop('disabled', false).show()
+
+            if ($('#code').val()) {
+              $('#code').prop('value', null)
+            }
+
+          } else {
+            $('#coupon_code_element').prop('disabled', false).show()
+            $('#range_codes_element').prop('disabled', true).hide()
+
+            if ($('#range_codes').val()) {
+              $('#range_codes').prop('value', null)
+            }
+          }
+        })
+
+        $('#type').change(function() {
+          if ($(this).val() == 'percentage') {
+            $('#input_percentage').prop('disabled', false).show()
+          } else {
+            $('#input_percentage').prop('disabled', true).hide()
+          }
+        })
+      })
+    </script>
+@endsection
diff --git a/themes/default/views/admin/coupons/index.blade.php b/themes/default/views/admin/coupons/index.blade.php
index 814b41ab6..d89135cff 100644
--- a/themes/default/views/admin/coupons/index.blade.php
+++ b/themes/default/views/admin/coupons/index.blade.php
@@ -42,10 +42,12 @@
                 <table id="datatable" class="table table-striped">
                     <thead>
                     <tr>
-                        <th>{{__('Partner discount')}}</th>
-                        <th>{{__('Registered user discount')}}</th>
-                        <th>{{__('Referral system commission')}}</th>
-                        <th>{{__('Created')}}</th>
+                        <th>{{__('Status')}}</th>
+                        <th>{{__('Code')}}</th>
+                        <th>{{__('Value')}}</th>
+                        <th>{{__('Used / Max Uses')}}</th>
+                        <th>{{__('Expires')}}</th>
+                        <th>{{__('Created At')}}</th>
                         <th>{{__('Actions')}}</th>
                     </tr>
                     </thead>
@@ -62,4 +64,33 @@
 
 </section>
 <!-- END CONTENT -->
+<script>
+  function submitResult() {
+    return confirm("{{__('Are you sure you wish to delete?')}}") !== false;
+  }
+
+  $(document).ready(function() {
+    $('#datatable').DataTable({
+      language: {
+        url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
+      },
+      processing: true,
+      serverSide: true,
+      stateSave: true,
+      ajax: "{{route('admin.coupons.datatable')}}",
+      columns: [
+        {data: 'status'},
+        {data: 'code'},
+        {data: 'value'},
+        {data: 'uses'},
+        {data: 'expires_at'},
+        {data: 'created_at'},
+        {data: 'actions', sortable: false},
+      ],
+      fnDrawCallback: function( oSettings ) {
+        $('[data-toggle="popover"]').popover();
+      }
+    });
+  })
+</script>
 @endsection

From bad9d0ec1238858e4bda0c6934661ee93e593b70 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Thu, 18 May 2023 19:52:26 +0000
Subject: [PATCH 193/514] It is good to set the application's timezone.

---
 app/Models/Coupon.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index 20657db5b..01133f4a2 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -54,7 +54,7 @@ public function getStatus()
         }
 
         if (!is_null($this->expires_at)) {
-            if ($this->expires_at <= Carbon::now()->timestamp) {
+            if ($this->expires_at <= Carbon::now(config('app.timezone'))->timestamp) {
                 return __('EXPIRED');
             }
         }

From 24ce267962ef57d71354dbeaea8ac732789095c6 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Fri, 19 May 2023 14:01:10 +0000
Subject: [PATCH 194/514] Implement coupons for the other gateways.

---
 .../Mollie/MollieExtension.php                | 35 ++++++++--
 .../PaymentGateways/Mollie/web_routes.php     |  4 +-
 .../Stripe/StripeExtension.php                | 36 ++++++++--
 .../PaymentGateways/Stripe/web_routes.php     |  4 +-
 app/Models/Coupon.php                         | 67 ++++---------------
 app/Settings/CouponSettings.php               |  2 +-
 6 files changed, 78 insertions(+), 70 deletions(-)

diff --git a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
index 11cf3c6e1..9145b067d 100644
--- a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
+++ b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
@@ -9,10 +9,12 @@
 use App\Models\Payment;
 use App\Models\ShopProduct;
 use App\Models\User;
+use App\Models\Coupon;
+use App\Traits\Coupon as CouponTrait;
+use App\Events\CouponUsedEvent;
 use Exception;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
-use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Redirect;
 use Illuminate\Support\Facades\Log;
@@ -23,6 +25,8 @@
  */
 class MollieExtension extends AbstractExtension
 {
+    use CouponTrait;
+
     public static function getConfig(): array
     {
         return [
@@ -33,7 +37,7 @@ public static function getConfig(): array
         ];
     }
 
-    static function pay(Request $request): void
+    public function pay(Request $request): void
     {
         $url = 'https://api.mollie.com/v2/payments';
         $settings = new MollieSettings();
@@ -41,6 +45,18 @@ static function pay(Request $request): void
         $user = Auth::user();
         $shopProduct = ShopProduct::findOrFail($request->shopProduct);
         $discount = PartnerDiscount::getDiscount();
+        $couponCode = $request->input('couponCode');
+        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
+        $price = $shopProduct->price;
+
+        // Coupon Discount.
+        if ($isValidCoupon->getStatusCode() == 200) {
+            $price = $this->calcDiscount($price, $isValidCoupon->getData());
+        }
+
+        // Partner Discount.
+        $price = $price - ($price * $discount / 100);
+        $price = number_format($price, 2, thousands_separator: '');
 
         // create a new payment
         $payment = Payment::create([
@@ -50,7 +66,7 @@ static function pay(Request $request): void
             'type' => $shopProduct->type,
             'status' => 'open',
             'amount' => $shopProduct->quantity,
-            'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
+            'price' => $price,
             'tax_value' => $shopProduct->getTaxValue(),
             'tax_percent' => $shopProduct->getTaxPercent(),
             'total_price' => $shopProduct->getTotalPrice(),
@@ -65,10 +81,10 @@ static function pay(Request $request): void
             ])->post($url, [
                 'amount' => [
                     'currency' => $shopProduct->currency_code,
-                    'value' => number_format($shopProduct->getTotalPrice(), 2, '.', ''),
+                    'value' => $price,
                 ],
                 'description' => "Order #{$payment->id} - " . $shopProduct->name,
-                'redirectUrl' => route('payment.MollieSuccess'),
+                'redirectUrl' => route('payment.MollieSuccess', ['couponCode' => $couponCode]),
                 'cancelUrl' => route('payment.Cancel'),
                 'webhookUrl' => url('/extensions/payment/MollieWebhook'),
                 'metadata' => [
@@ -103,6 +119,15 @@ static function success(Request $request): void
     {
         $payment = Payment::findOrFail($request->input('payment'));
         $payment->status = 'pending';
+        $coupon_code = $request->input('couponCode');
+
+        // increase the use of the coupon when the payment is confirmed.
+        if ($coupon_code) {
+            $coupon = new Coupon;
+            $coupon->incrementUses($coupon_code);
+
+            event(new CouponUsedEvent($coupon));
+        }
 
         Redirect::route('home')->with('success', 'Your payment is being processed')->send();
         return;
diff --git a/app/Extensions/PaymentGateways/Mollie/web_routes.php b/app/Extensions/PaymentGateways/Mollie/web_routes.php
index f5640b9a3..2314774af 100644
--- a/app/Extensions/PaymentGateways/Mollie/web_routes.php
+++ b/app/Extensions/PaymentGateways/Mollie/web_routes.php
@@ -4,8 +4,8 @@
 use App\Extensions\PaymentGateways\Mollie\MollieExtension;
 
 Route::middleware(['web', 'auth'])->group(function () {
-    Route::get('payment/MolliePay/{shopProduct}', function () {
-        MollieExtension::pay(request());
+    Route::get('payment/MolliePay/{shopProduct}', function (MollieExtension $mollieExtension) {
+        $mollieExtension->pay(request());
     })->name('payment.MolliePay');
 
     Route::get(
diff --git a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
index 7102e223d..f54157d45 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
@@ -4,12 +4,15 @@
 
 use App\Helpers\AbstractExtension;
 use App\Events\PaymentEvent;
+use App\Events\CouponUsedEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Extensions\PaymentGateways\Stripe\StripeSettings;
 use App\Models\PartnerDiscount;
 use App\Models\Payment;
 use App\Models\ShopProduct;
 use App\Models\User;
+use App\Models\Coupon;
+use App\Traits\Coupon as CouponTrait;
 use App\Notifications\ConfirmPaymentNotification;
 use Exception;
 use Illuminate\Http\Request;
@@ -21,6 +24,8 @@
 
 class StripeExtension extends AbstractExtension
 {
+    use CouponTrait;
+
     public static function getConfig(): array
     {
         return [
@@ -35,10 +40,14 @@ public static function getConfig(): array
      * @param  Request  $request
      * @param  ShopProduct  $shopProduct
      */
-    public static function StripePay(Request $request)
+    public function StripePay(Request $request)
     {
         $user = Auth::user();
         $shopProduct = ShopProduct::findOrFail($request->shopProduct);
+        $discount = PartnerDiscount::getDiscount();
+        $couponCode = $request->input('couponCode');
+        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
+        $price = $shopProduct->price;
 
         // check if the price is valid for stripe
         if (!self::checkPriceAmount($shopProduct->getTotalPrice(), strtoupper($shopProduct->currency_code), 'stripe')) {
@@ -46,7 +55,14 @@ public static function StripePay(Request $request)
             return;
         }
 
-        $discount = PartnerDiscount::getDiscount();
+        // Coupon Discount.
+        if ($isValidCoupon->getStatusCode() == 200) {
+            $price = $this->calcDiscount($price, $isValidCoupon->getData());
+        }
+
+        // Partner Discount.
+        $price = $price - ($price * $discount / 100);
+        $price = number_format($price, 2);
 
 
         // create payment
@@ -57,7 +73,7 @@ public static function StripePay(Request $request)
             'type' => $shopProduct->type,
             'status' => 'open',
             'amount' => $shopProduct->quantity,
-            'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
+            'price' => $price,
             'tax_value' => $shopProduct->getTaxValue(),
             'total_price' => $shopProduct->getTotalPrice(),
             'tax_percent' => $shopProduct->getTaxPercent(),
@@ -75,7 +91,7 @@ public static function StripePay(Request $request)
                             'name' => $shopProduct->display . ($discount ? (' (' . __('Discount') . ' ' . $discount . '%)') : ''),
                             'description' => $shopProduct->description,
                         ],
-                        'unit_amount_decimal' => round($shopProduct->getPriceAfterDiscount() * 100, 2),
+                        'unit_amount_decimal' => $price,
                     ],
                     'quantity' => 1,
                 ],
@@ -93,7 +109,7 @@ public static function StripePay(Request $request)
             ],
 
             'mode' => 'payment',
-            'success_url' => route('payment.StripeSuccess', ['payment' => $payment->id]) . '&session_id={CHECKOUT_SESSION_ID}',
+            'success_url' => route('payment.StripeSuccess', ['payment' => $payment->id, 'couponCode' => $couponCode]) . '&session_id={CHECKOUT_SESSION_ID}',
             'cancel_url' => route('payment.Cancel'),
             'payment_intent_data' => [
                 'metadata' => [
@@ -114,7 +130,7 @@ public static function StripeSuccess(Request $request)
         $user = User::findOrFail($user->id);
         $payment = Payment::findOrFail($request->input('payment'));
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-
+        $couponCode = $request->input('couponCode');
 
         Redirect::route('home')->with('success', 'Please wait for success')->send();
 
@@ -136,6 +152,14 @@ public static function StripeSuccess(Request $request)
                     'status' => 'paid',
                 ]);
 
+                 // increase the use of the coupon when the payment is confirmed.
+                 if ($couponCode) {
+                    $coupon = new Coupon;
+                    $coupon->incrementUses($couponCode);
+
+                    event(new CouponUsedEvent($coupon));
+                }
+
                 //payment notification
                 $user->notify(new ConfirmPaymentNotification($payment));
 
diff --git a/app/Extensions/PaymentGateways/Stripe/web_routes.php b/app/Extensions/PaymentGateways/Stripe/web_routes.php
index 0f4fed969..c5640aba5 100644
--- a/app/Extensions/PaymentGateways/Stripe/web_routes.php
+++ b/app/Extensions/PaymentGateways/Stripe/web_routes.php
@@ -4,8 +4,8 @@
 use App\Extensions\PaymentGateways\Stripe\StripeExtension;
 
 Route::middleware(['web', 'auth'])->group(function () {
-    Route::get('payment/StripePay/{shopProduct}', function () {
-        StripeExtension::StripePay(request());
+    Route::get('payment/StripePay/{shopProduct}', function (StripeExtension $stripeExtension) {
+        $stripeExtension->StripePay(request());
     })->name('payment.StripePay');
 
     Route::get(
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index 01133f4a2..97a5b9733 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -4,11 +4,21 @@
 
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Spatie\Activitylog\LogOptions;
+use Spatie\Activitylog\Traits\LogsActivity;
 use Carbon\Carbon;
 
 class Coupon extends Model
 {
-    use HasFactory;
+    use HasFactory, LogsActivity;
+
+    public function getActivitylogOptions(): LogOptions
+    {
+        return LogOptions::defaults()
+            ->logOnlyDirty()
+            ->logOnly(['*'])
+            ->dontSubmitEmptyLogs();
+    }
 
     /**
      * @var string[]
@@ -97,67 +107,16 @@ public static function generateRandomCoupon(int $amount = 10): array
         return $coupons;
     }
 
-    /**
-     * Standardize queries into one single function.
-     *
-     * @param string $code Coupon Code.
-     * @param array $attributes Attributes to be returned.
-     *
-     * @return mixed
-     */
-    protected function getQueryData(string $code, array $attributes): mixed
-    {
-        $query = (Coupon::where('code', $code)
-            ->where('expires_at', '>', Carbon::now())
-            ->whereColumn('uses', '<=', 'max_uses')
-            ->get($attributes)->toArray()
-        );
-
-        // When there are results, it comes nested arrays, idk why. This is the solution for now.
-        $results = count($query) > 0 ? $query[0] : $query;
-
-        if (empty($results)) {
-            return [];
-        }
-
-        return $results;
-    }
-
-    /**
-     * Get the data from a coupon.
-     *
-     * @param string $code Coupon Code.
-     * @param array $attributes Attributes of a coupon.
-     *
-     * @return mixed
-     */
-    public function getCoupon(string $code, array $attributes = ['percentage']): mixed
-    {
-        $coupon = $this->getQueryData($code, $attributes);
-
-        if (is_null($coupon)) {
-            return null;
-        }
-
-        return $coupon;
-    }
-
     /**
      * Increments the use of a coupon.
      *
      * @param string $code Coupon Code.
      * @param int $amount Amount to increment.
      *
-     * @return null|bool
+     * @return bool
      */
-    public function incrementUses(string $code, int $amount = 1): null|bool
+    public function incrementUses(string $code, int $amount = 1): bool
     {
-        $coupon = $this->getQueryData($code, ['uses', 'max_uses']);
-
-        if (empty($coupon) || $coupon['uses'] == $coupon['max_uses']) {
-            return null;
-        }
-
         $this->where('code', $code)->increment('uses', $amount);
 
         return true;
diff --git a/app/Settings/CouponSettings.php b/app/Settings/CouponSettings.php
index 29ec33320..dde8f42ac 100644
--- a/app/Settings/CouponSettings.php
+++ b/app/Settings/CouponSettings.php
@@ -43,7 +43,7 @@ public static function getOptionInputData()
                 'description' => 'Maximum number of uses that a user can make of the same coupon.'
             ],
             'delete_coupon_on_expires' => [
-                'label' => 'Delete Coupon On Expires',
+                'label' => 'Auto Delete Expired Coupons',
                 'type' => 'boolean',
                 'description' => 'Automatically deletes the coupon if it expires.'
             ],

From 4320fa9ef636db4a8184ec92aea54a9d0c343d9d Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Fri, 19 May 2023 15:00:30 +0000
Subject: [PATCH 195/514] Make it possible to disable coupons

---
 .../Controllers/Admin/PaymentController.php   |  9 +--
 app/Settings/CouponSettings.php               | 29 ++++---
 ...23_05_12_170041_create_coupon_settings.php |  2 +
 themes/default/views/store/checkout.blade.php | 76 ++++++++++---------
 4 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 5ab740d9f..1b0d875aa 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -9,7 +9,6 @@
 use App\Models\Payment;
 use App\Models\User;
 use App\Models\ShopProduct;
-use App\Models\Coupon;
 use App\Traits\Coupon as CouponTrait;
 use Exception;
 use Illuminate\Contracts\Foundation\Application;
@@ -20,10 +19,9 @@
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use App\Helpers\ExtensionHelper;
+use App\Settings\CouponSettings;
 use App\Settings\GeneralSettings;
 use App\Settings\LocaleSettings;
-use Carbon\Carbon;
-use Illuminate\Support\Str;
 
 class PaymentController extends Controller
 {
@@ -51,7 +49,7 @@ public function index(LocaleSettings $locale_settings)
      * @param  ShopProduct  $shopProduct
      * @return Application|Factory|View
      */
-    public function checkOut(ShopProduct $shopProduct, GeneralSettings $general_settings)
+    public function checkOut(ShopProduct $shopProduct, GeneralSettings $general_settings, CouponSettings $coupon_settings)
     {
         $this->checkPermission(self::BUY_PERMISSION);
 
@@ -87,7 +85,8 @@ public function checkOut(ShopProduct $shopProduct, GeneralSettings $general_sett
             'total' => $shopProduct->getTotalPrice(),
             'paymentGateways'   => $paymentGateways,
             'productIsFree' => $price <= 0,
-            'credits_display_name' => $general_settings->credits_display_name
+            'credits_display_name' => $general_settings->credits_display_name,
+            'isCouponsEnabled' => $coupon_settings->enabled,
         ]);
     }
 
diff --git a/app/Settings/CouponSettings.php b/app/Settings/CouponSettings.php
index dde8f42ac..7669b06a3 100644
--- a/app/Settings/CouponSettings.php
+++ b/app/Settings/CouponSettings.php
@@ -6,9 +6,10 @@
 
 class CouponSettings extends Settings
 {
-	public ?int $max_uses_per_user;
-    public ?bool $delete_coupon_on_expires;
-    public ?bool $delete_coupon_on_uses_reached;
+    public bool $enabled;
+    public bool $delete_coupon_on_expires;
+    public bool $delete_coupon_on_uses_reached;
+    public ?int $max_uses_per_user;
 
     public static function group(): string
     {
@@ -22,9 +23,10 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'max_uses_per_user' => 'required|integer',
-            'delete_coupon_on_expires' => 'required|boolean',
-            'delete_coupon_on_uses_reached' => 'required|boolean',
+            'enabled' => "nullable|boolean",
+            'delete_coupon_on_expires' => 'nullable|boolean',
+            'delete_coupon_on_uses_reached' => 'nullable|boolean',
+            'max_uses_per_user' => 'nullable|integer',
         ];
     }
 
@@ -37,10 +39,10 @@ public static function getOptionInputData()
     {
         return [
             "category_icon" => "fas fa-ticket-alt",
-            'max_uses_per_user' => [
-                'label' => 'Max Uses Per User',
-                'type' => 'number',
-                'description' => 'Maximum number of uses that a user can make of the same coupon.'
+            'enabled' => [
+                'label' => 'Enable Coupons',
+                'type' => 'boolean',
+                'description' => 'Enables coupons to be used in the store.'
             ],
             'delete_coupon_on_expires' => [
                 'label' => 'Auto Delete Expired Coupons',
@@ -51,7 +53,12 @@ public static function getOptionInputData()
                 'label' => 'Delete Coupon When Max Uses Reached',
                 'type' => 'boolean',
                 'description' => 'Delete a coupon as soon as its maximum usage is reached.'
-            ]
+            ],
+            'max_uses_per_user' => [
+                'label' => 'Max Uses Per User',
+                'type' => 'number',
+                'description' => 'Maximum number of uses that a user can make of the same coupon.'
+            ],
         ];
     }
 }
diff --git a/database/settings/2023_05_12_170041_create_coupon_settings.php b/database/settings/2023_05_12_170041_create_coupon_settings.php
index 9ff792ce5..8e912bef3 100644
--- a/database/settings/2023_05_12_170041_create_coupon_settings.php
+++ b/database/settings/2023_05_12_170041_create_coupon_settings.php
@@ -6,6 +6,7 @@
 {
     public function up(): void
     {
+        $this->migrator->add('coupon.enabled', true);
         $this->migrator->add('coupon.max_uses_per_user', 1);
         $this->migrator->add('coupon.delete_coupon_on_expires', false);
         $this->migrator->add('coupon.delete_coupon_on_uses_reached', false);
@@ -13,6 +14,7 @@ public function up(): void
 
     public function down(): void
     {
+        $this->migrator->delete('coupon.enabled');
         $this->migrator->delete('coupon.max_uses_per_user');
         $this->migrator->delete('coupon.delete_coupon_on_expires');
         $this->migrator->delete('coupon.delete_coupon_on_uses_reached');
diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index 59ea53c18..5fc360040 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -79,45 +79,47 @@
                                 </div>
                             </div>
                         </div>
-												<div class="col-xl-4">
-													<div class="card">
-														<div class="card-header">
-															<h4 class="mb-0">
-																Coupon Code
-															</h4>
-														</div>
-														<div class="card-body">
-															<div class="d-flex">
-                                <input
-                                  type="text"
-                                  id="coupon_code"
-                                  name="coupon_code"
-                                  value="{{ old('coupon_code') }}"
-                                  :value="coupon_code"
-                                  class="form-control @error('coupon_code') is_invalid @enderror"
-                                  placeholder="SUMMER"
-                                  x-on:change.debounce="setCouponCode($event)"
-                                  x-model="coupon_code"
-                                />
-                              <button
-                                type="button"
-                                id="send_coupon_code"
-                                class="btn btn-success ml-3"
-                                :disabled="!coupon_code.length"
-                                :class="!coupon_code.length ? 'disabled' : ''"
-                                :value="coupon_code"
-                              >
-                                {{ __('Submit') }}
-                              </button>
+                        @if ($isCouponsEnabled)
+                          <div class="col-xl-4">
+                            <div class="card">
+                              <div class="card-header">
+                                <h4 class="mb-0">
+                                  Coupon Code
+                                </h4>
                               </div>
-                              @error('coupon_code')
-                                <div class="text-danger">
-                                  {{ $message }}
+                              <div class="card-body">
+                                <div class="d-flex">
+                                  <input
+                                    type="text"
+                                    id="coupon_code"
+                                    name="coupon_code"
+                                    value="{{ old('coupon_code') }}"
+                                    :value="coupon_code"
+                                    class="form-control @error('coupon_code') is_invalid @enderror"
+                                    placeholder="SUMMER"
+                                    x-on:change.debounce="setCouponCode($event)"
+                                    x-model="coupon_code"
+                                  />
+                                <button
+                                  type="button"
+                                  id="send_coupon_code"
+                                  class="btn btn-success ml-3"
+                                  :disabled="!coupon_code.length"
+                                  :class="!coupon_code.length ? 'disabled' : ''"
+                                  :value="coupon_code"
+                                >
+                                  {{ __('Submit') }}
+                                </button>
                                 </div>
-                              @enderror
-														</div>
-													</div>
-												</div>
+                                @error('coupon_code')
+                                  <div class="text-danger">
+                                    {{ $message }}
+                                  </div>
+                                @enderror
+                              </div>
+                            </div>
+                          </div>
+                        @endif
                     @endif
                     <div class="col-xl-3">
                         <div class="card">

From 6d50834f9c6706bf5feab33b7f0b6eb5a0e64aac Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sat, 20 May 2023 19:55:19 +0000
Subject: [PATCH 196/514] Just by improving the code.

---
 app/Events/CouponUsedEvent.php                |  4 ++-
 .../Mollie/MollieExtension.php                | 10 ++-----
 .../PayPal/PayPalExtension.php                | 10 ++-----
 .../Stripe/StripeExtension.php                | 15 ++++------
 app/Listeners/CouponUsed.php                  | 30 +++++++++++++++++++
 app/Models/Coupon.php                         | 15 ----------
 6 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/app/Events/CouponUsedEvent.php b/app/Events/CouponUsedEvent.php
index 49168b602..ceb0ac376 100644
--- a/app/Events/CouponUsedEvent.php
+++ b/app/Events/CouponUsedEvent.php
@@ -12,14 +12,16 @@ class CouponUsedEvent
     use Dispatchable, InteractsWithSockets, SerializesModels;
 
     public Coupon $coupon;
+    public string $couponCode;
 
     /**
      * Create a new event instance.
      *
      * @return void
      */
-    public function __construct(Coupon $coupon)
+    public function __construct(Coupon $coupon, string $couponCode)
     {
         $this->coupon = $coupon;
+        $this->couponCode = $couponCode;
     }
 }
diff --git a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
index 9145b067d..6edd34112 100644
--- a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
+++ b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
@@ -119,14 +119,10 @@ static function success(Request $request): void
     {
         $payment = Payment::findOrFail($request->input('payment'));
         $payment->status = 'pending';
-        $coupon_code = $request->input('couponCode');
-
-        // increase the use of the coupon when the payment is confirmed.
-        if ($coupon_code) {
-            $coupon = new Coupon;
-            $coupon->incrementUses($coupon_code);
+        $couponCode = $request->input('couponCode');
 
-            event(new CouponUsedEvent($coupon));
+        if ($couponCode) {
+            event(new CouponUsedEvent(new Coupon, $couponCode));
         }
 
         Redirect::route('home')->with('success', 'Your payment is being processed')->send();
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index 07771e486..e62cbe54c 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -141,7 +141,7 @@ static function PaypalSuccess(Request $laravelRequest): void
 
         $payment = Payment::findOrFail($laravelRequest->payment);
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-		$coupon_code = $laravelRequest->input('couponCode');
+		$couponCode = $laravelRequest->input('couponCode');
 
         $request = new OrdersCaptureRequest($laravelRequest->input('token'));
         $request->prefer('return=representation');
@@ -156,12 +156,8 @@ static function PaypalSuccess(Request $laravelRequest): void
                     'payment_id' => $response->result->id,
                 ]);
 
-                // increase the use of the coupon when the payment is confirmed.
-                if ($coupon_code) {
-                    $coupon = new Coupon;
-                    $coupon->incrementUses($coupon_code);
-
-                    event(new CouponUsedEvent($coupon));
+                if ($couponCode) {
+                    event(new CouponUsedEvent(new Coupon, $couponCode));
                 }
 
                 event(new UserUpdateCreditsEvent($user));
diff --git a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
index f54157d45..b66655932 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
@@ -44,9 +44,6 @@ public function StripePay(Request $request)
     {
         $user = Auth::user();
         $shopProduct = ShopProduct::findOrFail($request->shopProduct);
-        $discount = PartnerDiscount::getDiscount();
-        $couponCode = $request->input('couponCode');
-        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
         $price = $shopProduct->price;
 
         // check if the price is valid for stripe
@@ -55,6 +52,10 @@ public function StripePay(Request $request)
             return;
         }
 
+        $discount = PartnerDiscount::getDiscount();
+        $couponCode = $request->input('couponCode');
+        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
+
         // Coupon Discount.
         if ($isValidCoupon->getStatusCode() == 200) {
             $price = $this->calcDiscount($price, $isValidCoupon->getData());
@@ -152,12 +153,8 @@ public static function StripeSuccess(Request $request)
                     'status' => 'paid',
                 ]);
 
-                 // increase the use of the coupon when the payment is confirmed.
-                 if ($couponCode) {
-                    $coupon = new Coupon;
-                    $coupon->incrementUses($couponCode);
-
-                    event(new CouponUsedEvent($coupon));
+                if ($couponCode) {
+                    event(new CouponUsedEvent(new Coupon, $couponCode));
                 }
 
                 //payment notification
diff --git a/app/Listeners/CouponUsed.php b/app/Listeners/CouponUsed.php
index 75ced4eb4..7ba8c34b4 100644
--- a/app/Listeners/CouponUsed.php
+++ b/app/Listeners/CouponUsed.php
@@ -30,6 +30,14 @@ public function __construct(CouponSettings $couponSettings)
      */
     public function handle(CouponUsedEvent $event)
     {
+        // Always check the authenticity of the coupon.
+        if (!$this->isValidCoupon($event)) {
+            return;
+        }
+
+        // Automatically increments the coupon usage.
+        $this->incrementUses($event);
+
         if ($this->delete_coupon_on_expires) {
             if (!is_null($event->coupon->expired_at)) {
                 if ($event->coupon->expires_at <= Carbon::now()->timestamp) {
@@ -44,4 +52,26 @@ public function handle(CouponUsedEvent $event)
             }
         }
     }
+
+    /**
+     * Increments the use of a coupon.
+     *
+     * @param \App\Events\CouponUsedEvent  $event
+     */
+    private function incrementUses(CouponUsedEvent $event)
+    {
+        $event->coupon->where('code', $event->coupon->code)->increment('uses');
+    }
+
+    /**
+     * It checks that the coupon received from the request really exists.
+     *
+     * @param \App\Events\CouponUsedEvent  $event
+     *
+     * @return bool
+     */
+    private function isValidCoupon(CouponUsedEvent $event): bool
+    {
+        return $event->coupon->code === $event->couponCode ? true : false;
+    }
 }
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index 97a5b9733..082e423fe 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -107,21 +107,6 @@ public static function generateRandomCoupon(int $amount = 10): array
         return $coupons;
     }
 
-    /**
-     * Increments the use of a coupon.
-     *
-     * @param string $code Coupon Code.
-     * @param int $amount Amount to increment.
-     *
-     * @return bool
-     */
-    public function incrementUses(string $code, int $amount = 1): bool
-    {
-        $this->where('code', $code)->increment('uses', $amount);
-
-        return true;
-    }
-
     /**
      * @return BelongsToMany
      */

From c05b4d88202a3110acbea57d95190425e6f21ae8 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 26 May 2023 16:30:23 +0200
Subject: [PATCH 197/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Move=20Payment=20co?=
 =?UTF-8?q?ncerns=20from=20extension=20to=20payment=20controller?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Classes/AbstractExtension.php             |  8 +++
 app/Classes/PaymentExtensions.php             | 14 ++++
 .../PayPal/PayPalExtension.php                | 69 +++++--------------
 app/Helpers/AbstractExtension.php             |  9 ---
 .../Controllers/Admin/PaymentController.php   | 68 ++++++++++++++----
 5 files changed, 93 insertions(+), 75 deletions(-)
 create mode 100644 app/Classes/AbstractExtension.php
 create mode 100644 app/Classes/PaymentExtensions.php
 delete mode 100644 app/Helpers/AbstractExtension.php

diff --git a/app/Classes/AbstractExtension.php b/app/Classes/AbstractExtension.php
new file mode 100644
index 000000000..7c0683980
--- /dev/null
+++ b/app/Classes/AbstractExtension.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace App\Classes;
+
+abstract class AbstractExtension
+{
+    abstract public static function getConfig(): array;
+}
diff --git a/app/Classes/PaymentExtensions.php b/app/Classes/PaymentExtensions.php
new file mode 100644
index 000000000..30bb1e19f
--- /dev/null
+++ b/app/Classes/PaymentExtensions.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Classes;
+
+use App\Models\Payment;
+use App\Models\ShopProduct;
+
+abstract class PaymentExtension extends AbstractExtension
+{
+    /**
+     * Returns the redirect url of the payment gateway to redirect the user to
+     */
+    abstract public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string;
+}
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index e62cbe54c..e8ede9af7 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -3,10 +3,10 @@
 namespace App\Extensions\PaymentGateways\PayPal;
 
 use App\Events\CouponUsedEvent;
-use App\Helpers\AbstractExtension;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
+use App\Classes\PaymentExtension;
 use App\Models\PartnerDiscount;
 use App\Models\Payment;
 use App\Models\ShopProduct;
@@ -28,7 +28,7 @@
 /**
  * Summary of PayPalExtension
  */
-class PayPalExtension extends AbstractExtension
+class PayPalExtension extends PaymentExtension
 {
     use CouponTrait;
 
@@ -40,41 +40,8 @@ public static function getConfig(): array
         ];
     }
 
-    public function PaypalPay(Request $request): void
+    public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
     {
-        /** @var User $user */
-        $user = Auth::user();
-        $shopProduct = ShopProduct::findOrFail($request->shopProduct);
-        $discount = PartnerDiscount::getDiscount();
-        $couponCode = $request->input('couponCode');
-        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
-        $price = $shopProduct->price;
-
-		// Coupon Discount.
-        if ($isValidCoupon->getStatusCode() == 200) {
-            $price = $this->calcDiscount($price, $isValidCoupon->getData());
-        }
-
-        // Partner Discount.
-        $price = $price - ($price * $discount / 100);
-        $price = number_format($price, 2);
-
-        // create a new payment
-        $payment = Payment::create([
-            'user_id' => $user->id,
-            'payment_id' => null,
-            'payment_method' => 'paypal',
-            'type' => $shopProduct->type,
-            'status' => 'open',
-            'amount' => $shopProduct->quantity,
-            'price' => $price,
-            'tax_value' => $shopProduct->getTaxValue(),
-            'tax_percent' => $shopProduct->getTaxPercent(),
-            'total_price' => $shopProduct->getTotalPrice(),
-            'currency_code' => $shopProduct->currency_code,
-            'shop_item_product_id' => $shopProduct->id,
-        ]);
-
         $request = new OrdersCreateRequest();
         $request->prefer('return=representation');
         $request->body = [
@@ -82,14 +49,14 @@ public function PaypalPay(Request $request): void
             "purchase_units" => [
                 [
                     "reference_id" => uniqid(),
-                    "description" => $shopProduct->display . ($discount ? (" (" . __('Discount') . " " . $discount . '%)') : ""),
+                    "description" => $shopProduct->display,
                     "amount" => [
-                        "value" => $price,
+                        "value" => $totalPriceString,
                         'currency_code' => strtoupper($shopProduct->currency_code),
                         'breakdown' => [
                             'item_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
-                                'value' => $price
+                                'value' => $totalPriceString
                             ],
                             'tax_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
@@ -101,12 +68,10 @@ public function PaypalPay(Request $request): void
             ],
             "application_context" => [
                 "cancel_url" => route('payment.Cancel'),
-                "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id, 'couponCode' => $couponCode]),
+                "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id]),
                 'brand_name' =>  config('app.name', 'CtrlPanel.GG'),
                 'shipping_preference'  => 'NO_SHIPPING'
             ]
-
-
         ];
 
         try {
@@ -123,17 +88,15 @@ public function PaypalPay(Request $request): void
                 throw new \Exception('No redirect link found');
             }
 
-            Redirect::away($response->result->links[1]->href)->send();
-            return;
+            return $response->result->links[1]->href;
         } catch (HttpException $ex) {
             Log::error('PayPal Payment: ' . $ex->getMessage());
-            $payment->delete();
 
-            Redirect::route('store.index')->with('error', __('Payment failed'))->send();
-            return;
+            throw new \Exception('PayPal Payment: ' . $ex->getMessage());
         }
     }
 
+
     static function PaypalSuccess(Request $laravelRequest): void
     {
         $user = Auth::user();
@@ -141,7 +104,7 @@ static function PaypalSuccess(Request $laravelRequest): void
 
         $payment = Payment::findOrFail($laravelRequest->payment);
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-		$couponCode = $laravelRequest->input('couponCode');
+        $couponCode = $laravelRequest->input('couponCode');
 
         $request = new OrdersCaptureRequest($laravelRequest->input('token'));
         $request->prefer('return=representation');
@@ -157,7 +120,7 @@ static function PaypalSuccess(Request $laravelRequest): void
                 ]);
 
                 if ($couponCode) {
-                    event(new CouponUsedEvent(new Coupon, $couponCode));
+                    event(new CouponUsedEvent($couponCode));
                 }
 
                 event(new UserUpdateCreditsEvent($user));
@@ -193,7 +156,9 @@ static function PaypalSuccess(Request $laravelRequest): void
 
     static function getPayPalClient(): PayPalHttpClient
     {
-        $environment = env('APP_ENV') == 'local'
+        error_log(config('app.env'));
+
+        $environment = config('app.env') == 'local'
             ? new SandboxEnvironment(self::getPaypalClientId(), self::getPaypalClientSecret())
             : new ProductionEnvironment(self::getPaypalClientId(), self::getPaypalClientSecret());
         return new PayPalHttpClient($environment);
@@ -204,7 +169,7 @@ static function getPayPalClient(): PayPalHttpClient
     static function getPaypalClientId(): string
     {
         $settings = new PayPalSettings();
-        return env('APP_ENV') == 'local' ?  $settings->sandbox_client_id : $settings->client_id;
+        return config('app.env') == 'local' ?  $settings->sandbox_client_id : $settings->client_id;
     }
     /**
      * @return string
@@ -212,6 +177,6 @@ static function getPaypalClientId(): string
     static function getPaypalClientSecret(): string
     {
         $settings = new PayPalSettings();
-        return env('APP_ENV') == 'local' ? $settings->sandbox_client_secret : $settings->client_secret;
+        return config('app.env') == 'local' ? $settings->sandbox_client_secret : $settings->client_secret;
     }
 }
diff --git a/app/Helpers/AbstractExtension.php b/app/Helpers/AbstractExtension.php
deleted file mode 100644
index 68af6f88e..000000000
--- a/app/Helpers/AbstractExtension.php
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-
-namespace App\Helpers;
-
-// create a abstract class for the extension that will contain all the methods that will be used in the extension
-abstract class AbstractExtension
-{
-    abstract public static function getConfig(): array;
-}
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 1b0d875aa..657150bd5 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers\Admin;
 
+use App\Events\CouponUsedEvent;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Http\Controllers\Controller;
@@ -22,6 +23,7 @@
 use App\Settings\CouponSettings;
 use App\Settings\GeneralSettings;
 use App\Settings\LocaleSettings;
+use Illuminate\Support\Facades\Log;
 
 class PaymentController extends Controller
 {
@@ -127,26 +129,64 @@ public function handleFreeProduct(ShopProduct $shopProduct)
 
     public function pay(Request $request)
     {
-        $product = ShopProduct::find($request->product_id);
-        $paymentGateway = $request->payment_method;
-        $coupon_code = $request->coupon_code;
-
-        // on free products, we don't need to use a payment gateway
-        $realPrice = $product->price - ($product->price * PartnerDiscount::getDiscount() / 100);
-        if ($realPrice <= 0) {
-            return $this->handleFreeProduct($product);
-        }
+        try {
+            $user = Auth::user();
+            $user = User::findOrFail($user->id);
+            $productId = $request->product_id;
+            $shopProduct = ShopProduct::findOrFail($productId);
+            $discount = PartnerDiscount::getDiscount();
+
+
+            $paymentGateway = $request->payment_method;
+            $couponCode = $request->coupon_code;
+
+            $subtotal = $shopProduct->price;
+
+            // Apply Coupon
+            $isCouponValid = $this->isCouponValid($couponCode, $user, $shopProduct->id);
+            if ($isCouponValid) {
+                $subtotal = $this->applyCoupon($couponCode, $subtotal);
+            }
 
-        if ($coupon_code) {
-            return redirect()->route('payment.' . $paymentGateway . 'Pay', [
-                'shopProduct' => $product->id,
-                'couponCode' => $coupon_code
+            // Apply Partner Discount
+            $subtotal = $subtotal - ($subtotal * $discount / 100);
+            if ($subtotal <= 0) {
+                return $this->handleFreeProduct($shopProduct);
+            }
+
+            // Format the total price to a readable string
+            $totalPriceString = number_format($subtotal, 2, '.', '');
+
+            // create a new payment
+            $payment = Payment::create([
+                'user_id' => $user->id,
+                'payment_id' => null,
+                'payment_method' => $paymentGateway,
+                'type' => $shopProduct->type,
+                'status' => 'open',
+                'amount' => $shopProduct->quantity,
+                'price' => $totalPriceString,
+                'tax_value' => $shopProduct->getTaxValue(),
+                'tax_percent' => $shopProduct->getTaxPercent(),
+                'total_price' => $shopProduct->getTotalPrice(),
+                'currency_code' => $shopProduct->currency_code,
+                'shop_item_product_id' => $shopProduct->id,
             ]);
+
+            $paymentGatewayExtension = ExtensionHelper::getExtensionClass($paymentGateway);
+            $redirectUrl = $paymentGatewayExtension::getRedirectUrl($payment, $shopProduct, $totalPriceString);
+            event(new CouponUsedEvent($couponCode));
+        } catch (Exception $e) {
+            Log::error($e->getMessage());
+            return redirect()->route('store.index')->with('error', __('Oops, something went wrong! Please try again later.'));
         }
 
-        return redirect()->route('payment.' . $paymentGateway . 'Pay', ['shopProduct' => $product->id]);
+        return redirect()->away($redirectUrl);
     }
 
+
+
+
     /**
      * @param  Request  $request
      */

From fc84e7d1db7668b42b616a578489f55923ec071a Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 26 May 2023 16:30:55 +0200
Subject: [PATCH 198/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Enhance=20coupon=20?=
 =?UTF-8?q?validation=20and=20application?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Listeners/CouponUsed.php | 20 ++-------------
 app/Models/Coupon.php        | 12 +++++----
 app/Traits/Coupon.php        | 48 ++++++++++++++++++++++++++++++++++--
 3 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/app/Listeners/CouponUsed.php b/app/Listeners/CouponUsed.php
index 7ba8c34b4..c9abb42bc 100644
--- a/app/Listeners/CouponUsed.php
+++ b/app/Listeners/CouponUsed.php
@@ -30,11 +30,6 @@ public function __construct(CouponSettings $couponSettings)
      */
     public function handle(CouponUsedEvent $event)
     {
-        // Always check the authenticity of the coupon.
-        if (!$this->isValidCoupon($event)) {
-            return;
-        }
-
         // Automatically increments the coupon usage.
         $this->incrementUses($event);
 
@@ -60,18 +55,7 @@ public function handle(CouponUsedEvent $event)
      */
     private function incrementUses(CouponUsedEvent $event)
     {
-        $event->coupon->where('code', $event->coupon->code)->increment('uses');
-    }
-
-    /**
-     * It checks that the coupon received from the request really exists.
-     *
-     * @param \App\Events\CouponUsedEvent  $event
-     *
-     * @return bool
-     */
-    private function isValidCoupon(CouponUsedEvent $event): bool
-    {
-        return $event->coupon->code === $event->couponCode ? true : false;
+        $event->coupon->increment('uses');
+        $event->coupon->save();
     }
 }
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index 082e423fe..8cd02621c 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -2,11 +2,13 @@
 
 namespace App\Models;
 
+use App\Settings\CouponSettings;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Spatie\Activitylog\LogOptions;
 use Spatie\Activitylog\Traits\LogsActivity;
 use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
 class Coupon extends Model
 {
@@ -75,16 +77,16 @@ public function getStatus()
     /**
      * Check if a user has already exceeded the uses of a coupon.
      *
-     * @param Request $request The request being made.
-     * @param CouponSettings $coupon_settings The instance of the coupon settings.
+     * @param User $user The request being made.
      *
      * @return bool
      */
-    public function isLimitsUsesReached($requestUser, $coupon_settings): bool
+    public function isMaxUsesReached($user): bool
     {
-        $coupon_uses = $requestUser->coupons()->where('id', $this->id)->count();
+        $coupon_settings = new CouponSettings;
+        $coupon_uses = $user->coupons()->where('id', $this->id)->count();
 
-        return $coupon_uses >= $coupon_settings->max_uses_per_user ? true : false;
+        return $coupon_uses >= $coupon_settings->max_uses_per_user;
     }
 
     /**
diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php
index 091fa855b..5dd0e7e97 100644
--- a/app/Traits/Coupon.php
+++ b/app/Traits/Coupon.php
@@ -5,7 +5,7 @@
 use App\Settings\CouponSettings;
 use App\Models\Coupon as CouponModel;
 use App\Models\ShopProduct;
-use Illuminate\Http\Request;
+use App\Models\User;
 use Illuminate\Http\JsonResponse;
 use stdClass;
 
@@ -40,7 +40,7 @@ public function validateCoupon($requestUser, $couponCode, $productId): JsonRespo
                 return $response;
             }
 
-            if ($coupon->isLimitsUsesReached($requestUser, $coupon_settings)) {
+            if ($coupon->isMaxUsesReached($requestUser, $coupon_settings)) {
                 $response = response()->json([
                     'isValid' => false,
                     'error' => __('You have reached the maximum uses of this coupon.')
@@ -69,6 +69,32 @@ public function validateCoupon($requestUser, $couponCode, $productId): JsonRespo
         return $response;
     }
 
+    public function isCouponValid(string $couponCode, User $user, string $productId): bool
+    {
+        if (is_null($couponCode)) return false;
+
+        $coupon = CouponModel::where('code', $couponCode)->first();
+        $shopProduct = ShopProduct::findOrFail($productId);
+
+        if ($coupon->getStatus() == 'USES_LIMIT_REACHED') {
+            return false;
+        }
+
+        if ($coupon->getStatus() == 'EXPIRED') {
+            return false;
+        }
+
+        if ($coupon->isMaxUsesReached($user)) {
+            return false;
+        }
+
+        if ($coupon->type === 'amount' && $coupon->value >= $shopProduct->price) {
+            return false;
+        }
+
+        return true;
+    }
+
     public function calcDiscount($productPrice, stdClass $data)
     {
 
@@ -89,4 +115,22 @@ public function calcDiscount($productPrice, stdClass $data)
 
         return $productPrice;
     }
+
+    public function applyCoupon(string $couponCode, float $price)
+    {
+        $coupon = CouponModel::where('code', $couponCode)->first();
+
+        if ($coupon->type === 'percentage') {
+            return $price - ($price * $coupon->value / 100);
+        }
+
+        if ($coupon->type === 'amount') {
+            // There is no discount if the value of the coupon is greater than or equal to the value of the product.
+            if ($coupon->value >= $price) {
+                return $price;
+            }
+        }
+
+        return $price - $coupon->value;
+    }
 }

From 4873992c4853acd5dc561194192758c1165dc5f2 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 26 May 2023 16:31:23 +0200
Subject: [PATCH 199/514] =?UTF-8?q?refactor:=20=E2=9A=A1=EF=B8=8F=20remove?=
 =?UTF-8?q?=20coupon=20instance=20from=20event?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Events/CouponUsedEvent.php | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/app/Events/CouponUsedEvent.php b/app/Events/CouponUsedEvent.php
index ceb0ac376..54b322bd9 100644
--- a/app/Events/CouponUsedEvent.php
+++ b/app/Events/CouponUsedEvent.php
@@ -19,9 +19,10 @@ class CouponUsedEvent
      *
      * @return void
      */
-    public function __construct(Coupon $coupon, string $couponCode)
+    public function __construct(string $couponCode)
     {
-        $this->coupon = $coupon;
+
         $this->couponCode = $couponCode;
+        $this->coupon = Coupon::where('code', $couponCode)->first();
     }
 }

From 48e5cae9a1d1d57dba9385ff6cf7b26795de2127 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 28 May 2023 02:27:39 +0200
Subject: [PATCH 200/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Migrate=20other=20p?=
 =?UTF-8?q?ayment=20gateways=20to=20new=20payment=20pattern?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Mollie/MollieExtension.php                | 60 +++----------------
 .../PayPal/PayPalExtension.php                |  1 -
 .../Stripe/StripeExtension.php                | 60 ++++---------------
 .../Controllers/Admin/PaymentController.php   |  3 -
 4 files changed, 19 insertions(+), 105 deletions(-)

diff --git a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
index 6edd34112..a2bc7054f 100644
--- a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
+++ b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
@@ -2,7 +2,7 @@
 
 namespace App\Extensions\PaymentGateways\Mollie;
 
-use App\Helpers\AbstractExtension;
+use App\Classes\AbstractExtension;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Models\PartnerDiscount;
@@ -37,43 +37,10 @@ public static function getConfig(): array
         ];
     }
 
-    public function pay(Request $request): void
+    public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
     {
         $url = 'https://api.mollie.com/v2/payments';
         $settings = new MollieSettings();
-
-        $user = Auth::user();
-        $shopProduct = ShopProduct::findOrFail($request->shopProduct);
-        $discount = PartnerDiscount::getDiscount();
-        $couponCode = $request->input('couponCode');
-        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
-        $price = $shopProduct->price;
-
-        // Coupon Discount.
-        if ($isValidCoupon->getStatusCode() == 200) {
-            $price = $this->calcDiscount($price, $isValidCoupon->getData());
-        }
-
-        // Partner Discount.
-        $price = $price - ($price * $discount / 100);
-        $price = number_format($price, 2, thousands_separator: '');
-
-        // create a new payment
-        $payment = Payment::create([
-            'user_id' => $user->id,
-            'payment_id' => null,
-            'payment_method' => 'mollie',
-            'type' => $shopProduct->type,
-            'status' => 'open',
-            'amount' => $shopProduct->quantity,
-            'price' => $price,
-            'tax_value' => $shopProduct->getTaxValue(),
-            'tax_percent' => $shopProduct->getTaxPercent(),
-            'total_price' => $shopProduct->getTotalPrice(),
-            'currency_code' => $shopProduct->currency_code,
-            'shop_item_product_id' => $shopProduct->id,
-        ]);
-
         try {
             $response = Http::withHeaders([
                 'Content-Type' => 'application/json',
@@ -81,10 +48,10 @@ public function pay(Request $request): void
             ])->post($url, [
                 'amount' => [
                     'currency' => $shopProduct->currency_code,
-                    'value' => $price,
+                    'value' => $totalPriceString,
                 ],
                 'description' => "Order #{$payment->id} - " . $shopProduct->name,
-                'redirectUrl' => route('payment.MollieSuccess', ['couponCode' => $couponCode]),
+                'redirectUrl' => route('payment.MollieSuccess'),
                 'cancelUrl' => route('payment.Cancel'),
                 'webhookUrl' => url('/extensions/payment/MollieWebhook'),
                 'metadata' => [
@@ -94,24 +61,13 @@ public function pay(Request $request): void
 
             if ($response->status() != 201) {
                 Log::error('Mollie Payment: ' . $response->body());
-                $payment->delete();
-
-                Redirect::route('store.index')->with('error', __('Payment failed'))->send();
-                return;
+                throw new Exception('Payment failed');
             }
 
-            $payment->update([
-                'payment_id' => $response->json()['id'],
-            ]);
-
-            Redirect::away($response->json()['_links']['checkout']['href'])->send();
-            return;
+            return $response->json()['_links']['checkout']['href'];
         } catch (Exception $ex) {
             Log::error('Mollie Payment: ' . $ex->getMessage());
-            $payment->delete();
-
-            Redirect::route('store.index')->with('error', __('Payment failed'))->send();
-            return;
+            throw new Exception('Payment failed');
         }
     }
 
@@ -122,7 +78,7 @@ static function success(Request $request): void
         $couponCode = $request->input('couponCode');
 
         if ($couponCode) {
-            event(new CouponUsedEvent(new Coupon, $couponCode));
+            event(new CouponUsedEvent($couponCode));
         }
 
         Redirect::route('home')->with('success', 'Your payment is being processed')->send();
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index e8ede9af7..bef9b5304 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -156,7 +156,6 @@ static function PaypalSuccess(Request $laravelRequest): void
 
     static function getPayPalClient(): PayPalHttpClient
     {
-        error_log(config('app.env'));
 
         $environment = config('app.env') == 'local'
             ? new SandboxEnvironment(self::getPaypalClientId(), self::getPaypalClientSecret())
diff --git a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
index b66655932..2c975232d 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
@@ -2,7 +2,7 @@
 
 namespace App\Extensions\PaymentGateways\Stripe;
 
-use App\Helpers\AbstractExtension;
+use App\Classes\AbstractExtension;
 use App\Events\PaymentEvent;
 use App\Events\CouponUsedEvent;
 use App\Events\UserUpdateCreditsEvent;
@@ -36,52 +36,14 @@ public static function getConfig(): array
         ];
     }
 
-    /**
-     * @param  Request  $request
-     * @param  ShopProduct  $shopProduct
-     */
-    public function StripePay(Request $request)
+    public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
     {
-        $user = Auth::user();
-        $shopProduct = ShopProduct::findOrFail($request->shopProduct);
-        $price = $shopProduct->price;
-
-        // check if the price is valid for stripe
-        if (!self::checkPriceAmount($shopProduct->getTotalPrice(), strtoupper($shopProduct->currency_code), 'stripe')) {
-            Redirect::route('home')->with('error', __('The product you chose can\'t be purchased with this payment method. The total amount is too small. Please buy a bigger amount or try a different payment method.'))->send();
-            return;
+        // check if the total price is valid for stripe
+        $totalPriceNumber = floatval($totalPriceString);
+        if (!self::checkPriceAmount($totalPriceNumber, strtoupper($shopProduct->currency_code), 'stripe')) {
+            throw new Exception('Invalid price amount');
         }
 
-        $discount = PartnerDiscount::getDiscount();
-        $couponCode = $request->input('couponCode');
-        $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct);
-
-        // Coupon Discount.
-        if ($isValidCoupon->getStatusCode() == 200) {
-            $price = $this->calcDiscount($price, $isValidCoupon->getData());
-        }
-
-        // Partner Discount.
-        $price = $price - ($price * $discount / 100);
-        $price = number_format($price, 2);
-
-
-        // create payment
-        $payment = Payment::create([
-            'user_id' => $user->id,
-            'payment_id' => null,
-            'payment_method' => 'stripe',
-            'type' => $shopProduct->type,
-            'status' => 'open',
-            'amount' => $shopProduct->quantity,
-            'price' => $price,
-            'tax_value' => $shopProduct->getTaxValue(),
-            'total_price' => $shopProduct->getTotalPrice(),
-            'tax_percent' => $shopProduct->getTaxPercent(),
-            'currency_code' => $shopProduct->currency_code,
-            'shop_item_product_id' => $shopProduct->id,
-        ]);
-
         $stripeClient = self::getStripeClient();
         $request = $stripeClient->checkout->sessions->create([
             'line_items' => [
@@ -89,10 +51,10 @@ public function StripePay(Request $request)
                     'price_data' => [
                         'currency' => $shopProduct->currency_code,
                         'product_data' => [
-                            'name' => $shopProduct->display . ($discount ? (' (' . __('Discount') . ' ' . $discount . '%)') : ''),
+                            'name' => $shopProduct->display,
                             'description' => $shopProduct->description,
                         ],
-                        'unit_amount_decimal' => $price,
+                        'unit_amount_decimal' => $totalPriceString,
                     ],
                     'quantity' => 1,
                 ],
@@ -110,7 +72,7 @@ public function StripePay(Request $request)
             ],
 
             'mode' => 'payment',
-            'success_url' => route('payment.StripeSuccess', ['payment' => $payment->id, 'couponCode' => $couponCode]) . '&session_id={CHECKOUT_SESSION_ID}',
+            'success_url' => route('payment.StripeSuccess', ['payment' => $payment->id]) . '&session_id={CHECKOUT_SESSION_ID}',
             'cancel_url' => route('payment.Cancel'),
             'payment_intent_data' => [
                 'metadata' => [
@@ -119,7 +81,7 @@ public function StripePay(Request $request)
             ],
         ]);
 
-        Redirect::to($request->url)->send();
+        return $request->url;
     }
 
     /**
@@ -302,7 +264,7 @@ public static function getStripeEndpointSecret()
      * @return bool
      * @description check if the amount is higher than the minimum amount for the stripe gateway
      */
-    public static function checkPriceAmount($amount, $currencyCode, $payment_method)
+    public static function checkPriceAmount(float $amount,  string $currencyCode, string $payment_method)
     {
         $minimums = [
             "USD" => [
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 657150bd5..850f5a93d 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -184,9 +184,6 @@ public function pay(Request $request)
         return redirect()->away($redirectUrl);
     }
 
-
-
-
     /**
      * @param  Request  $request
      */

From 2161464ee38c7f9cee03ec8c2b82b10cf70631d9 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 28 May 2023 02:34:59 +0200
Subject: [PATCH 201/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Enum=20for?=
 =?UTF-8?q?=20payment=20states?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Enums/PaymentStatus.php                      | 12 ++++++++++++
 .../PaymentGateways/Mollie/MollieExtension.php   | 16 ++++++----------
 .../PaymentGateways/PayPal/PayPalExtension.php   | 11 ++++-------
 .../PaymentGateways/Stripe/StripeExtension.php   | 13 ++++---------
 app/Listeners/UserPayment.php                    |  3 ++-
 5 files changed, 28 insertions(+), 27 deletions(-)
 create mode 100644 app/Enums/PaymentStatus.php

diff --git a/app/Enums/PaymentStatus.php b/app/Enums/PaymentStatus.php
new file mode 100644
index 000000000..eb01dbddc
--- /dev/null
+++ b/app/Enums/PaymentStatus.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Enums;
+
+// Payment status are open, processing, paid and canceled
+enum PaymentStatus: String
+{
+    case OPEN = "open";
+    case PROCESSING = "processing";
+    case PAID = "paid";
+    case CANCELED = "canceled";
+}
diff --git a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
index a2bc7054f..08d4480d7 100644
--- a/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
+++ b/app/Extensions/PaymentGateways/Mollie/MollieExtension.php
@@ -3,6 +3,7 @@
 namespace App\Extensions\PaymentGateways\Mollie;
 
 use App\Classes\AbstractExtension;
+use App\Enums\PaymentStatus;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Models\PartnerDiscount;
@@ -74,12 +75,8 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
     static function success(Request $request): void
     {
         $payment = Payment::findOrFail($request->input('payment'));
-        $payment->status = 'pending';
-        $couponCode = $request->input('couponCode');
-
-        if ($couponCode) {
-            event(new CouponUsedEvent($couponCode));
-        }
+        $payment->status = PaymentStatus::PROCESSING;
+        $payment->save();
 
         Redirect::route('home')->with('success', 'Your payment is being processed')->send();
         return;
@@ -100,16 +97,15 @@ static function webhook(Request $request): JsonResponse
                 return response()->json(['success' => false]);
             }
 
-            $payment = Payment::findOrFail($response->json()['metadata']['payment_id']);
-            $payment->status->update([
-                'status' => $response->json()['status'],
-            ]);
 
+            $payment = Payment::findOrFail($response->json()['metadata']['payment_id']);
             $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
             event(new PaymentEvent($payment, $payment, $shopProduct));
 
             if ($response->json()['status'] == 'paid') {
                 $user = User::findOrFail($payment->user_id);
+                $payment->status = PaymentStatus::PAID;
+                $payment->save();
                 event(new UserUpdateCreditsEvent($user));
             }
         } catch (Exception $ex) {
diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index bef9b5304..981d86ef2 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -7,6 +7,7 @@
 use App\Events\UserUpdateCreditsEvent;
 use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
 use App\Classes\PaymentExtension;
+use App\Enums\PaymentStatus;
 use App\Models\PartnerDiscount;
 use App\Models\Payment;
 use App\Models\ShopProduct;
@@ -104,7 +105,6 @@ static function PaypalSuccess(Request $laravelRequest): void
 
         $payment = Payment::findOrFail($laravelRequest->payment);
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-        $couponCode = $laravelRequest->input('couponCode');
 
         $request = new OrdersCaptureRequest($laravelRequest->input('token'));
         $request->prefer('return=representation');
@@ -115,13 +115,10 @@ static function PaypalSuccess(Request $laravelRequest): void
             if ($response->statusCode == 201 || $response->statusCode == 200) {
                 //update payment
                 $payment->update([
-                    'status' => 'paid',
+                    'status' => PaymentStatus::PAID,
                     'payment_id' => $response->result->id,
                 ]);
 
-                if ($couponCode) {
-                    event(new CouponUsedEvent($couponCode));
-                }
 
                 event(new UserUpdateCreditsEvent($user));
                 event(new PaymentEvent($user, $payment, $shopProduct));
@@ -134,7 +131,7 @@ static function PaypalSuccess(Request $laravelRequest): void
                 dd($response);
             } else {
                 $payment->update([
-                    'status' => 'cancelled',
+                    'status' => PaymentStatus::CANCELED,
                     'payment_id' => $response->result->id,
                 ]);
                 abort(500);
@@ -146,7 +143,7 @@ static function PaypalSuccess(Request $laravelRequest): void
                 dd($ex->getMessage());
             } else {
                 $payment->update([
-                    'status' => 'cancelled',
+                    'status' => PaymentStatus::CANCELED,
                     'payment_id' => $response->result->id,
                 ]);
                 abort(422);
diff --git a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
index 2c975232d..b96134317 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
@@ -3,6 +3,7 @@
 namespace App\Extensions\PaymentGateways\Stripe;
 
 use App\Classes\AbstractExtension;
+use App\Enums\PaymentStatus;
 use App\Events\PaymentEvent;
 use App\Events\CouponUsedEvent;
 use App\Events\UserUpdateCreditsEvent;
@@ -93,7 +94,6 @@ public static function StripeSuccess(Request $request)
         $user = User::findOrFail($user->id);
         $payment = Payment::findOrFail($request->input('payment'));
         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-        $couponCode = $request->input('couponCode');
 
         Redirect::route('home')->with('success', 'Please wait for success')->send();
 
@@ -112,16 +112,11 @@ public static function StripeSuccess(Request $request)
                 //update payment
                 $payment->update([
                     'payment_id' => $paymentSession->payment_intent,
-                    'status' => 'paid',
+                    'status' => PaymentStatus::PAID,
                 ]);
 
-                if ($couponCode) {
-                    event(new CouponUsedEvent(new Coupon, $couponCode));
-                }
-
                 //payment notification
                 $user->notify(new ConfirmPaymentNotification($payment));
-
                 event(new UserUpdateCreditsEvent($user));
                 event(new PaymentEvent($user, $payment, $shopProduct));
 
@@ -133,7 +128,7 @@ public static function StripeSuccess(Request $request)
                     //update payment
                     $payment->update([
                         'payment_id' => $paymentSession->payment_intent,
-                        'status' => 'processing',
+                        'status' => PaymentStatus::PROCESSING,
                     ]);
 
                     event(new PaymentEvent($user, $payment, $shopProduct));
@@ -174,7 +169,7 @@ public static function handleStripePaymentSuccessHook($paymentIntent)
                 //update payment db entry status
                 $payment->update([
                     'payment_id' => $payment->payment_id ?? $paymentIntent->id,
-                    'status' => 'paid'
+                    'status' => PaymentStatus::PAID,
                 ]);
 
                 //payment notification
diff --git a/app/Listeners/UserPayment.php b/app/Listeners/UserPayment.php
index 3417a7ce2..9e1066ef1 100644
--- a/app/Listeners/UserPayment.php
+++ b/app/Listeners/UserPayment.php
@@ -2,6 +2,7 @@
 
 namespace App\Listeners;
 
+use App\Enums\PaymentStatus;
 use App\Events\PaymentEvent;
 use App\Models\User;
 use Illuminate\Support\Facades\DB;
@@ -48,7 +49,7 @@ public function handle(PaymentEvent $event)
         $shopProduct = $event->shopProduct;
 
         // only update user if payment is paid
-        if ($event->payment->status != "paid") {
+        if ($event->payment->status != PaymentStatus::PAID) {
             return;
         }
 

From d365b122db41cbd84ece2568e5e106f31b458fa7 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 2 Jun 2023 14:54:02 +0200
Subject: [PATCH 202/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Coupon=20frontend?=
 =?UTF-8?q?,=20calculation=20and=20submitting?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/store/checkout.blade.php | 363 +++++++++---------
 1 file changed, 181 insertions(+), 182 deletions(-)

diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index 5fc360040..5d5de5cfd 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -22,104 +22,87 @@
     <!-- END CONTENT HEADER -->
 
     <!-- MAIN CONTENT -->
-    <section class="content">
+    <section class="content" x-data="couponForm()">
         <div class="container-fluid">
-            <form
-							id="payment_form"
-              action="{{ route('payment.pay') }}"
-              method="POST"
-              x-data="{
-                payment_method: '',
-                coupon_code: '',
-                clicked: false,
-                setCouponCode(event) {
-                  this.coupon_code = event.target.value
-                }
-              }"
-            >
+            <form id="payment_form" action="{{ route('payment.pay') }}" method="POST">
                 @csrf
                 @method('post')
                 <div class="row d-flex justify-content-center flex-wrap">
                     @if (!$productIsFree)
                         <div class="col-xl-4">
                             <div class="card">
-                                <div class="card-header">
-                                    <h4 class="mb-0">
-                                        <i class="fas fa-money-check-alt"></i>
-                                        Payment Methods
-                                    </h4>
-                                </div>
+
                                 <div class="card-body">
-                                    <input type="hidden" name="product_id" value="{{ $product->id }}">
-                                    <input type="hidden" name="payment_method" :value="payment_method"
-                                        x-model="payment_method">
-                                    <div class="row">
-                                        <div class="col-lg-12">
-                                            @foreach ($paymentGateways as $gateway)
-                                                <div class="row checkout-gateways">
-                                                    <div class="col-12 d-flex justify-content-between">
-                                                        <label class="form-check-label h4 checkout-gateway-label"
-                                                            for="{{ $gateway->name }}">
-                                                            <span class="mr-3">{{ $gateway->name }}</span>
-                                                        </label>
-                                                        <button class="btn btn-primary rounded" type="button"
-                                                            name="payment-method" id="{{ $gateway->name }}"
-                                                            value="{{ $gateway->name }}"
-                                                            :class="payment_method === '{{ $gateway->name }}' ?
-                                                                'active' : ''"
-                                                            @click="payment_method = '{{ $gateway->name }}'; clicked = true;"
-                                                            x-text="payment_method == '{{ $gateway->name }}' ? 'Selected' : 'Select'">Select</button>
-                                                        </button>
+                                    <ul class="list-group ">
+                                        <li class="list-group-item">
+                                            <div class="row">
+                                                <input type="hidden" name="product_id" value="{{ $product->id }}">
+                                                <input type="hidden" name="payment_method" :value="payment_method"
+                                                    x-model="payment_method">
+                                                <div class="col-lg-12">
+                                                    <span class="h4">{{ __('Payment Methods') }}</span>
+                                                    <div class="mt-2">
+                                                        @foreach ($paymentGateways as $gateway)
+                                                            <div
+                                                                class="row checkout-gateways @if (!$loop->last) mb-2 @endif">
+                                                                <div class="col-12 d-flex justify-content-between">
+                                                                    <label
+                                                                        class="form-check-label h5 checkout-gateway-label"
+                                                                        for="{{ $gateway->name }}">
+                                                                        <span class="mr-3">{{ $gateway->name }}</span>
+                                                                    </label>
+                                                                    <button class="btn btn-primary rounded" type="button"
+                                                                        name="payment-method" id="{{ $gateway->name }}"
+                                                                        value="{{ $gateway->name }}"
+                                                                        :class="payment_method === '{{ $gateway->name }}' ?
+                                                                            'active' : ''"
+                                                                        @click="payment_method = '{{ $gateway->name }}'; submitted = true;"
+                                                                        x-text="payment_method == '{{ $gateway->name }}' ? 'Selected' : 'Select'">Select</button>
+                                                                    </button>
 
+                                                                </div>
+                                                            </div>
+                                                        @endforeach
                                                     </div>
                                                 </div>
-                                            @endforeach
-                                        </div>
-                                    </div>
+                                            </div>
+                                        </li>
+
+                                        <li class="list-group-item">
+                                            <div class="row">
+                                                <div class="col-lg-12">
+                                                    @if ($isCouponsEnabled)
+                                                        <span class="h4">{{ __('Coupon') }}</span>
+
+                                                        <div class="d-flex mt-2">
+                                                            <input type="text" id="coupon_code" name="coupon_code"
+                                                                value="{{ old('coupon_code') }}" :value="coupon_code"
+                                                                class="form-control @error('coupon_code') is_invalid @enderror"
+                                                                placeholder="{{ __('Enter your coupon here...') }}"
+                                                                x-on:change.debounce="setCouponCode($event)"
+                                                                x-model="coupon_code" />
+                                                            <button type="button" id="send_coupon_code"
+                                                                @click="checkCoupon()" class="btn btn-success ml-3"
+                                                                :disabled="!coupon_code.length"
+                                                                :class="!coupon_code.length ? 'disabled' : ''"
+                                                                :value="coupon_code">
+                                                                {{ __('Submit') }}
+                                                            </button>
+
+                                                        </div>
+                                                        @error('coupon_code')
+                                                            <div class="text-danger">
+                                                                {{ $message }}
+                                                            </div>
+                                                        @enderror
+                                                    @endif
+                                                </div>
+                                            </div>
+                                        </li>
+                                    </ul>
                                 </div>
                             </div>
                         </div>
-                        @if ($isCouponsEnabled)
-                          <div class="col-xl-4">
-                            <div class="card">
-                              <div class="card-header">
-                                <h4 class="mb-0">
-                                  Coupon Code
-                                </h4>
-                              </div>
-                              <div class="card-body">
-                                <div class="d-flex">
-                                  <input
-                                    type="text"
-                                    id="coupon_code"
-                                    name="coupon_code"
-                                    value="{{ old('coupon_code') }}"
-                                    :value="coupon_code"
-                                    class="form-control @error('coupon_code') is_invalid @enderror"
-                                    placeholder="SUMMER"
-                                    x-on:change.debounce="setCouponCode($event)"
-                                    x-model="coupon_code"
-                                  />
-                                <button
-                                  type="button"
-                                  id="send_coupon_code"
-                                  class="btn btn-success ml-3"
-                                  :disabled="!coupon_code.length"
-                                  :class="!coupon_code.length ? 'disabled' : ''"
-                                  :value="coupon_code"
-                                >
-                                  {{ __('Submit') }}
-                                </button>
-                                </div>
-                                @error('coupon_code')
-                                  <div class="text-danger">
-                                    {{ $message }}
-                                  </div>
-                                @enderror
-                              </div>
-                            </div>
-                          </div>
-                        @endif
                     @endif
                     <div class="col-xl-3">
                         <div class="card">
@@ -173,7 +156,7 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                             <li class="d-flex justify-content-between">
                                                 <span class="text-muted d-inline-block">{{ __('Subtotal') }}</span>
                                                 <span class="text-muted d-inline-block">
-                                                    {{ $product->formatToCurrency($discountedprice) }}</span>
+                                                    {{ $product->formatToCurrency($product->price) }}</span>
                                             </li>
                                             <div class="d-flex justify-content-between">
                                                 <span class="text-muted d-inline-block">{{ __('Tax') }}
@@ -184,18 +167,19 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                                 <span class="text-muted d-inline-block">
                                                     + {{ $product->formatToCurrency($taxvalue) }}</span>
                                             </div>
-                                            <div id="coupon_discount_details" class="d-flex justify-content-between" style="display: none !important;">
-                                              <span class="text-muted d-inline-block">
-                                                {{ __('Coupon Discount') }}
-                                              </span>
-                                              <span id="coupon_discount_value" class="text-muted d-inline-block">
+                                            <div id="coupon_discount_details" class="d-flex justify-content-between"
+                                                style="display: none !important;">
+                                                <span class="text-muted d-inline-block">
+                                                    {{ __('Coupon Discount') }}
+                                                </span>
+                                                <span id="coupon_discount_value" class="text-muted d-inline-block">
 
-                                              </span>
+                                                </span>
                                             </div>
                                             @if ($discountpercent && $discountvalue)
                                                 <div class="d-flex justify-content-between">
                                                     <span class="text-muted d-inline-block">{{ __('Discount') }}
-                                                        ({{ $discountpercent }}%):</span>
+                                                        ({{ $discountpercent }}%)</span>
                                                     <span
                                                         class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue) }}</span>
                                                 </div>
@@ -203,40 +187,36 @@ class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue)
                                             <hr class="text-white border-secondary">
                                             <div class="d-flex justify-content-between">
                                                 <span class="text-muted d-inline-block">{{ __('Total') }}</span>
-                                                <input id="total_price_input" type="hidden" value="{{ $product->getTotalPrice() }}">
-                                                <span
-                                                  id="total_price"
-                                                  class="text-muted d-inline-block"
-                                                >
-                                                  {{ $product->formatToCurrency($total) }}
+                                                <input id="total_price_input" type="hidden" x-model="totalPrice">
+                                                <span class="text-muted d-inline-block" x-text="totalPrice">
                                                 </span>
                                             </div>
                                             <template x-if="payment_method">
                                                 <div class="d-flex justify-content-between">
                                                     <span class="text-muted d-inline-block">{{ __('Pay with') }}</span>
-                                                    <span class="text-muted d-inline-block" x-text="payment_method"></span>
+                                                    <span class="text-muted d-inline-block"
+                                                        x-text="payment_method"></span>
                                                 </div>
                                             </template>
                                         </ul>
                                     </li>
                                 </ul>
 
-                                <button :disabled="(!payment_method || !clicked || coupon_code ? true : false) && {{ !$productIsFree }}"
+                                <button
+                                    :disabled="(!payment_method || !clicked || coupon_code) &&
+                                    {{ !$productIsFree }}"
                                     id="submit_form_button"
-                                    :class="(!payment_method || !clicked || coupon_code ? true : false) && {{ !$productIsFree }} ? 'disabled' : ''"
-                                    :x-text="coupon_code"
-                                    class="btn btn-success float-right w-100">
-
+                                    :class="(!payment_method || !clicked || coupon_code) &&
+                                    {{ !$productIsFree }} ? 'disabled' : ''"
+                                    :x-text="coupon_code" class="btn btn-success float-right w-100">
                                     <i class="far fa-credit-card mr-2" @click="clicked == true"></i>
                                     @if ($productIsFree)
                                         {{ __('Get for free') }}
                                     @else
                                         {{ __('Submit Payment') }}
                                     @endif
-
                                 </button>
-                                <script>
-                                </script>
+                                <script></script>
                             </div>
                         </div>
                     </div>
@@ -248,81 +228,100 @@ class="btn btn-success float-right w-100">
     <!-- END CONTENT -->
 
     <script>
-      $(document).ready(function() {
-        const productId = $("[name='product_id']").val()
-        let hasCouponCodeValue = $('#coupon_code').val().trim() !== ''
-
-        $('#coupon_code').on('change', function(e) {
-          hasCouponCodeValue = e.target.value !== ''
-        })
-
-        function calcPriceWithCouponDiscount(couponValue, couponType) {
-          let totalPrice = $('#total_price_input').val()
-
-          if (typeof totalPrice == 'string') {
-            totalPrice = parseFloat(totalPrice)
-          }
-
-          if (couponType === 'percentage') {
-            totalPrice = totalPrice - (totalPrice * couponValue / 100)
-            $('#coupon_discount_value').text("- " + couponValue + "%")
-          } else if (couponType === 'amount') {
-            totalPrice = totalPrice - couponValue
-            $('#coupon_discount_value').text(totalPrice)
-          }
-
-          $('#total_price').text(totalPrice)
-          $('#total_price_input').val(totalPrice)
-        }
+        function couponForm() {
+            console.log("{{ $discountedprice }}", " {{ $discountpercent }}", "{{ $discountvalue }}",
+                " {{ $taxpercent }}", "{{ $taxvalue }}", "{{ $productIsFree }}", "{{ $total }}")
+            return {
+                // Get the product id from the url
+                productId: window.location.pathname.split('/').pop(),
+                payment_method: '',
+                coupon_code: '',
+                submitted: false,
+                totalPrice: {{ $discountedprice }},
+
+
+                setCouponCode(event) {
+                    this.coupon_code = event.target.value
+                    console.log(event.target.value)
+                },
+
+                async checkCoupon() {
+                    console.log(this.coupon_code)
+                    const response = await (fetch(
+                            "{{ route('admin.coupon.redeem') }}", {
+                                method: 'POST',
+                                headers: {
+                                    'Content-Type': 'application/json',
+                                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr(
+                                        'content')
+                                },
+                                body: JSON.stringify({
+                                    couponCode: this.coupon_code,
+                                    productId: this.productId
+                                })
+                            }
+                        )
+                        .then(response => response.json()).catch((error) => {
+                            Swal.fire({
+                                icon: 'error',
+                                title: 'Oops...',
+                                text: "{{ __('The coupon code you entered is invalid.') }}"
+                            })
+                        }))
+
+                    if (response.isValid && response.couponCode) {
+                        Swal.fire({
+                            icon: 'success',
+                            text: "{{ __('The coupon was successfully added to your purchase.') }}"
+
+                        })
 
-				function checkCoupon() {
-					const couponCode = $('#coupon_code').val()
-
-					$.ajax({
-						url: "{{ route('admin.coupon.redeem') }}",
-						method: 'POST',
-						data: { couponCode: couponCode, productId: productId },
-						success: function(response) {
-							if (response.isValid && response.couponCode) {
-                Swal.fire({
-                  icon: 'success',
-                  text: 'The coupon was successfully added to your purchase.',
-                }).then(function(isConfirmed) {
-                  calcPriceWithCouponDiscount(response.couponValue, response.couponType)
-                  $('#submit_form_button').prop('disabled', false).removeClass('disabled')
-                  $('#send_coupon_code').prop('disabled', true)
-                  $('#coupon_discount_details').prop('disabled', false).show()
-                })
-
-							} else {
-								console.log('Invalid Coupon')
-							}
-						},
-						error: function(response) {
-              const responseJson = response.responseJSON
-
-              if (!responseJson.isValid) {
-                  Swal.fire({
-                  icon: 'error',
-                  title: 'Oops...',
-                  text: responseJson.error,
-                })
-              }
-						}
-					})
-				}
-
-				$('#payment_form').on('submit', function(e) {
-					if (hasCouponCodeValue) {
-						checkCoupon()
-					}
-				})
-
-        $('#send_coupon_code').click(function(e) {
-          if (hasCouponCodeValue) {
-						checkCoupon()
-					}
-        })
-      })
+                        this.calcPriceWithCouponDiscount(response.couponValue, response
+                            .couponType)
+
+                        $('#submit_form_button').prop('disabled', false).removeClass(
+                            'disabled')
+                        $('#send_coupon_code').prop('disabled', true)
+                        $('#coupon_discount_details').prop('disabled', false).show()
+
+                    } else {
+                        Swal.fire({
+                            icon: 'error',
+                            title: 'Oops...',
+                            text: "{{ __('The coupon code you entered is invalid.') }}"
+                        })
+                    }
+
+
+                },
+
+                calcPriceWithCouponDiscount(couponValue, couponType) {
+                    let newTotalPrice = this.totalPrice
+
+                    if (couponType === 'percentage') {
+                        newTotalPrice = newTotalPrice - (newTotalPrice * couponValue / 100)
+                        $('#coupon_discount_value').text("- " + couponValue + "%")
+                    } else if (couponType === 'amount') {
+                        newTotalPrice = totanewTotalPricelPrice - couponValue
+                        $('#coupon_discount_value').text(this.totalPrice)
+                    }
+
+                    // get language for formatting currency
+                    const lang = "{{ app()->getLocale() }}"
+                    console.log(lang)
+                    // format totalPrice to currency
+                    this.totalPrice = newTotalPrice.toLocaleString(lang, {
+                        style: 'currency',
+                        currency: "{{ $product->currency_code }}",
+                    })
+
+                    console.log(newTotalPrice)
+                    console.log(this.totalPrice)
+
+                    $('#total_price_input').val(this.totalPrice)
+                },
+
+            }
+        }
     </script>
 @endsection

From 2c2279af56a2b141d4b7cc3d340da57cfca6f1c0 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 2 Jun 2023 14:59:31 +0200
Subject: [PATCH 203/514] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20remove?=
 =?UTF-8?q?=20jquery=20code?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/store/checkout.blade.php | 30 +++++++++----------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index 5d5de5cfd..c9308548a 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -172,7 +172,7 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                                 <span class="text-muted d-inline-block">
                                                     {{ __('Coupon Discount') }}
                                                 </span>
-                                                <span id="coupon_discount_value" class="text-muted d-inline-block">
+                                                <span x-text="couponDiscountedValue" class="text-muted d-inline-block">
 
                                                 </span>
                                             </div>
@@ -188,7 +188,8 @@ class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue)
                                             <div class="d-flex justify-content-between">
                                                 <span class="text-muted d-inline-block">{{ __('Total') }}</span>
                                                 <input id="total_price_input" type="hidden" x-model="totalPrice">
-                                                <span class="text-muted d-inline-block" x-text="totalPrice">
+                                                <span class="text-muted d-inline-block"
+                                                    x-text="formatToCurrency(totalPrice)">
                                                 </span>
                                             </div>
                                             <template x-if="payment_method">
@@ -229,8 +230,6 @@ class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue)
 
     <script>
         function couponForm() {
-            console.log("{{ $discountedprice }}", " {{ $discountpercent }}", "{{ $discountvalue }}",
-                " {{ $taxpercent }}", "{{ $taxvalue }}", "{{ $productIsFree }}", "{{ $total }}")
             return {
                 // Get the product id from the url
                 productId: window.location.pathname.split('/').pop(),
@@ -238,15 +237,14 @@ function couponForm() {
                 coupon_code: '',
                 submitted: false,
                 totalPrice: {{ $discountedprice }},
+                couponDiscountedValue: 0,
 
 
                 setCouponCode(event) {
                     this.coupon_code = event.target.value
-                    console.log(event.target.value)
                 },
 
                 async checkCoupon() {
-                    console.log(this.coupon_code)
                     const response = await (fetch(
                             "{{ route('admin.coupon.redeem') }}", {
                                 method: 'POST',
@@ -291,34 +289,36 @@ function couponForm() {
                             text: "{{ __('The coupon code you entered is invalid.') }}"
                         })
                     }
+                },
 
 
-                },
 
                 calcPriceWithCouponDiscount(couponValue, couponType) {
                     let newTotalPrice = this.totalPrice
 
                     if (couponType === 'percentage') {
                         newTotalPrice = newTotalPrice - (newTotalPrice * couponValue / 100)
-                        $('#coupon_discount_value').text("- " + couponValue + "%")
+                        this.couponDiscountedValue = "- " + couponValue + "%"
                     } else if (couponType === 'amount') {
                         newTotalPrice = totanewTotalPricelPrice - couponValue
-                        $('#coupon_discount_value').text(this.totalPrice)
+                        this.couponDiscountedValue = "- " + couponValue + " {{ $product->currency_code }}"
                     }
 
+                    // get language for formatting currency
+                    const lang = "{{ app()->getLocale() }}"
+                    // format totalPrice to currency
+                    this.totalPrice = this.formatToCurrency(newTotalPrice)
+                },
+
+                formatToCurrency(amount) {
                     // get language for formatting currency
                     const lang = "{{ app()->getLocale() }}"
                     console.log(lang)
                     // format totalPrice to currency
-                    this.totalPrice = newTotalPrice.toLocaleString(lang, {
+                    return amount.toLocaleString(lang, {
                         style: 'currency',
                         currency: "{{ $product->currency_code }}",
                     })
-
-                    console.log(newTotalPrice)
-                    console.log(this.totalPrice)
-
-                    $('#total_price_input').val(this.totalPrice)
                 },
 
             }

From 416e2f6d000c0fb178a3bcbd82155062138568d3 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Tue, 6 Jun 2023 15:48:26 +0200
Subject: [PATCH 204/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Show=20coupon=20r?=
 =?UTF-8?q?esult=20with=20amount?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/store/checkout.blade.php | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index c9308548a..20e8bf91c 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -178,7 +178,7 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                             </div>
                                             @if ($discountpercent && $discountvalue)
                                                 <div class="d-flex justify-content-between">
-                                                    <span class="text-muted d-inline-block">{{ __('Discount') }}
+                                                    <span class="text-muted d-inline-block">{{ __('Partner Discount') }}
                                                         ({{ $discountpercent }}%)</span>
                                                     <span
                                                         class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue) }}</span>
@@ -296,24 +296,26 @@ function couponForm() {
                 calcPriceWithCouponDiscount(couponValue, couponType) {
                     let newTotalPrice = this.totalPrice
 
+
+                    console.log(couponType)
                     if (couponType === 'percentage') {
                         newTotalPrice = newTotalPrice - (newTotalPrice * couponValue / 100)
                         this.couponDiscountedValue = "- " + couponValue + "%"
                     } else if (couponType === 'amount') {
-                        newTotalPrice = totanewTotalPricelPrice - couponValue
-                        this.couponDiscountedValue = "- " + couponValue + " {{ $product->currency_code }}"
+
+                        newTotalPrice = newTotalPrice - couponValue
+                        this.couponDiscountedValue = "- " + this.formatToCurrency(couponValue)
                     }
 
-                    // get language for formatting currency
-                    const lang = "{{ app()->getLocale() }}"
                     // format totalPrice to currency
                     this.totalPrice = this.formatToCurrency(newTotalPrice)
                 },
 
                 formatToCurrency(amount) {
-                    // get language for formatting currency
-                    const lang = "{{ app()->getLocale() }}"
-                    console.log(lang)
+                    // get language for formatting currency - use en_US as product->formatToCurrency() uses it
+                    //const lang = "{{ app()->getLocale() }}"
+                    const lang = 'en-US'
+
                     // format totalPrice to currency
                     return amount.toLocaleString(lang, {
                         style: 'currency',

From 466f903209e118d7949f9cf7b23e994a892a3efa Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Tue, 6 Jun 2023 15:50:46 +0200
Subject: [PATCH 205/514] =?UTF-8?q?fix:=20=F0=9F=A5=85=20Extend=20error=20?=
 =?UTF-8?q?message?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 themes/default/views/store/checkout.blade.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index 20e8bf91c..b6a002940 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -263,7 +263,7 @@ function couponForm() {
                             Swal.fire({
                                 icon: 'error',
                                 title: 'Oops...',
-                                text: "{{ __('The coupon code you entered is invalid.') }}"
+                                text: "{{ __('The coupon code you entered is invalid or cannot be applied to this product.') }}"
                             })
                         }))
 
@@ -286,7 +286,7 @@ function couponForm() {
                         Swal.fire({
                             icon: 'error',
                             title: 'Oops...',
-                            text: "{{ __('The coupon code you entered is invalid.') }}"
+                            text: "{{ __('The coupon code you entered is invalid or cannot be applied to this product.') }}"
                         })
                     }
                 },

From 5027986b001d59076bb95ef2650bfc1776d26f21 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Tue, 6 Jun 2023 15:52:04 +0200
Subject: [PATCH 206/514] chore: remove old file

---
 Addon-notes.md | 4 ----
 1 file changed, 4 deletions(-)
 delete mode 100644 Addon-notes.md

diff --git a/Addon-notes.md b/Addon-notes.md
deleted file mode 100644
index ac00939be..000000000
--- a/Addon-notes.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Export diff files:
-Commit Hash of lates Main commit
-
-git diff -r --no-commit-id --name-only --diff-filter=ACMR \<commit> | tar -czf \.\./controllpanelgg-monthly-addon/file.tgz -T -

From af8eb7b1a3ac96de2ddda8cea634880b4dd1cb27 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Tue, 6 Jun 2023 17:04:36 +0200
Subject: [PATCH 207/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20fix=20text=20typo?=
 =?UTF-8?q?=20and=20add=20localisation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lang/en.json                                  | 67 ++++++++++++++++---
 themes/default/views/store/checkout.blade.php |  5 +-
 2 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/lang/en.json b/lang/en.json
index 90f23aae0..69316d6ef 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -236,7 +236,6 @@
     "You usually do not need to change anything here": "You usually do not need to change anything here",
     "Edit Server": "Edit Server",
     "Server identifier": "Server identifier",
-    "User": "User",
     "Server id": "Server id",
     "Config": "Config",
     "Suspended at": "Suspended at",
@@ -355,7 +354,6 @@
     "Useful Links": "Useful Links",
     "Icon class name": "Icon class name",
     "You can find available free icons": "You can find available free icons",
-    "Title": "Title",
     "Link": "Link",
     "description": "description",
     "Icon": "Icon",
@@ -385,11 +383,9 @@
     "Content": "Content",
     "Server limit": "Server limit",
     "Discord": "Discord",
-    "Usage": "Usage",
     "IP": "IP",
     "Referals": "Referals",
     "referral-code": "referral-code",
-    "Vouchers": "Vouchers",
     "Voucher details": "Voucher details",
     "Summer break voucher": "Summer break voucher",
     "Code": "Code",
@@ -452,7 +448,6 @@
     "Blacklist List": "Blacklist List",
     "Reason": "Reason",
     "Created At": "Created At",
-    "Actions": "Actions",
     "Add To Blacklist": "Add To Blacklist",
     "please make the best of it": "please make the best of it",
     "Please note, the blacklist will make the user unable to make a ticket/reply again": "Please note, the blacklist will make the user unable to make a ticket/reply again",
@@ -489,7 +484,6 @@
     "Please select software ...": "Please select software ...",
     "---": "---",
     "Specification ": "Specification ",
-    "Node": "Node",
     "Resource Data:": "Resource Data:",
     "vCores": "vCores",
     "MB": "MB",
@@ -554,9 +548,7 @@
     "Total discount": "Total discount",
     "Taxable amount": "Taxable amount",
     "Tax rate": "Tax rate",
-    "Total taxes": "Total taxes",
     "Shipping": "Shipping",
-    "Total amount": "Total amount",
     "Notes": "Notes",
     "Amount in words": "Amount in words",
     "Please pay until": "Please pay until",
@@ -593,11 +585,66 @@
     "Billing Period": "Billing Period",
     "Next Billing Cycle": "Next Billing Cycle",
     "Manage Server": "Manage Server",
-    "Delete Server": "Delete Server",
     "Cancel Server": "Cancel Server",
     "Yes, cancel it!": "Yes, cancel it!",
     "No, abort!": "No, abort!",
     "Billing period": "Billing period",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
-    "Caution": "Caution"
+    "Caution": "Caution",
+    "Only one of the two code inputs must be provided.": "Only one of the two code inputs must be provided.",
+    "At least one of the two code inputs must be provided.": "At least one of the two code inputs must be provided.",
+    "The coupon's was registered successfully.": "The coupon's was registered successfully.",
+    "coupon has been updated!": "coupon has been updated!",
+    "coupon has been removed!": "coupon has been removed!",
+    "Never": "Never",
+    "Legal pages updated": "Legal pages updated",
+    "Partner already exists": "Partner already exists",
+    "partner has been created!": "partner has been created!",
+    "partner has been updated!": "partner has been updated!",
+    "partner has been removed!": "partner has been removed!",
+    "Unknown user": "Unknown user",
+    "Default": "Default",
+    "Oops, something went wrong! Please try again later.": "Oops, something went wrong! Please try again later.",
+    "enabled": "enabled",
+    "disabled": "disabled",
+    "Role saved": "Role saved",
+    "Role updated. Name and Permissions of this Role cannot be changed": "Role updated. Name and Permissions of this Role cannot be changed",
+    "Role updated. Name of this Role cannot be changed": "Role updated. Name of this Role cannot be changed",
+    "Role removed": "Role removed",
+    "Server cancelled": "Server cancelled",
+    "An exception has occurred while trying to cancel the server\"": "An exception has occurred while trying to cancel the server\"",
+    "renamed": "renamed",
+    "servers": "servers",
+    "deleted": "deleted",
+    "old servers": "old servers",
+    "Category created": "Category created",
+    "Category name updated": "Category name updated",
+    "Category removed": "Category removed",
+    "Ticket not found on the server. It potentially got deleted earlier": "Ticket not found on the server. It potentially got deleted earlier",
+    "A ticket has been reopened, ID: #": "A ticket has been reopened, ID: #",
+    "User not found on the server. Check on the admin database or try again later.": "User not found on the server. Check on the admin database or try again later.",
+    "Reopen": "Reopen",
+    "User not found on the server. Check the admin database or try again later.": "User not found on the server. Check the admin database or try again later.",
+    "You can not delete the last admin!": "You can not delete the last admin!",
+    "User does not have the right permissions.": "User does not have the right permissions.",
+    "Account permanently deleted!": "Account permanently deleted!",
+    "The system administrator has blocked the creation of new servers.": "The system administrator has blocked the creation of new servers.",
+    "An exception has occurred while trying to remove a resource\"": "An exception has occurred while trying to remove a resource\"",
+    "This is not your Server!": "This is not your Server!",
+    "The system was unable to update your server product. Please try again later or contact support.": "The system was unable to update your server product. Please try again later or contact support.",
+    "This coupon does not exist.": "This coupon does not exist.",
+    "This coupon has reached the maximum amount of uses.": "This coupon has reached the maximum amount of uses.",
+    "This coupon has expired.": "This coupon has expired.",
+    "You have reached the maximum uses of this coupon.": "You have reached the maximum uses of this coupon.",
+    "The coupon you are trying to use would give you 100% off, so it cannot be used for this product, sorry.": "The coupon you are trying to use would give you 100% off, so it cannot be used for this product, sorry.",
+    "Select": "Select",
+    "Selected": "Selected",
+    "Pricing": "Pricing",
+    "Product details": "Product details",
+    "Total Amount": "Total Amount",
+    "Partner Discount": "Partner Discount",
+    "Coupon Discount": "Coupon Discount",
+    "Enter your coupon here...": "Enter your coupon here...",
+    "Coupon": "Coupon",
+    "Checkout details": "Checkout details"
 }
diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index b6a002940..8c7697806 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -180,8 +180,9 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                                                 <div class="d-flex justify-content-between">
                                                     <span class="text-muted d-inline-block">{{ __('Partner Discount') }}
                                                         ({{ $discountpercent }}%)</span>
-                                                    <span
-                                                        class="text-muted d-inline-block">-{{ $product->formatToCurrency($discountvalue) }}</span>
+                                                    <span class="text-muted d-inline-block">
+                                                        - {{ $product->formatToCurrency($discountvalue) }}
+                                                    </span>
                                                 </div>
                                             @endif
                                             <hr class="text-white border-secondary">

From 21e900040a1ab0be8c36385a16fb9a0d5d6006c8 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Tue, 6 Jun 2023 17:08:32 +0200
Subject: [PATCH 208/514] fix: remove unused "action area"

---
 themes/default/views/servers/index.blade.php | 22 +-------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index f7c2cec5b..a1b827f65 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -52,27 +52,7 @@ class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span>
                         style="max-width: 350px">
                         <div class="card-header">
                             <div class="d-flex justify-content-between align-items-center">
-                                <h5 class="card-title mt-1">{{ $server->name }}
-                                </h5>
-                                <div class="card-tools mt-1">
-                                    <div class="dropdown no-arrow">
-                                        <a href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown"
-                                            aria-haspopup="true" aria-expanded="false">
-                                            <i class="fas fa-ellipsis-v fa-sm fa-fw text-white-50"></i>
-                                        </a>
-                                        <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
-                                            aria-labelledby="dropdownMenuLink">
-                                            @if (!empty($phpmyadmin_url)))
-                                                <a href="{{ $phpmyadmin_url }}"
-                                                    class="dropdown-item text-info" target="__blank"><i title="manage"
-                                                        class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
-                                            @endif
-                                            <div class="dropdown-divider"></div>
-                                            <span class="dropdown-item"><i title="Created at"
-                                                    class="fas fa-sync-alt mr-2"></i><span>{{ $server->created_at->isoFormat('LL') }}</span></span>
-                                        </div>
-                                    </div>
-                                </div>
+                                <h5 class="card-title mt-1">{{ $server->name }}</h5>
                             </div>
                         </div>
                         <div class="card-body">

From eae524b653018f91515d442afd80e4fb8f2c686f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Tue, 6 Jun 2023 17:08:54 +0200
Subject: [PATCH 209/514] =?UTF-8?q?chore:=20=F0=9F=8C=90=20Change=20all=20?=
 =?UTF-8?q?language=20labels=20to=20english=20lables?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lang/bg.json | 25 +++++++++++++------------
 lang/bs.json |  3 +++
 lang/cs.json | 29 +++++++++++++++--------------
 lang/de.json | 29 +++++++++++++++--------------
 lang/en.json |  7 ++++++-
 lang/es.json | 27 ++++++++++++++-------------
 lang/fr.json |  3 ++-
 lang/he.json | 29 +++++++++++++++--------------
 lang/hi.json | 27 ++++++++++++++-------------
 lang/hu.json | 27 ++++++++++++++-------------
 lang/it.json | 25 +++++++++++++------------
 lang/nl.json | 27 ++++++++++++++-------------
 lang/pl.json | 23 ++++++++++++-----------
 lang/pt.json | 27 ++++++++++++++-------------
 lang/ro.json |  3 ++-
 lang/ru.json |  5 +++--
 lang/sh.json |  5 ++++-
 lang/sk.json |  3 ++-
 lang/sr.json |  3 ++-
 lang/sv.json |  3 ++-
 lang/tr.json | 29 +++++++++++++++--------------
 lang/zh.json | 29 +++++++++++++++--------------
 22 files changed, 209 insertions(+), 179 deletions(-)

diff --git a/lang/bg.json b/lang/bg.json
index bc1ab41ac..1e869cbfe 100644
--- a/lang/bg.json
+++ b/lang/bg.json
@@ -447,20 +447,21 @@
     "Notes": "Бележки",
     "Amount in words": "Сума с думи",
     "Please pay until": "Моля, платете до",
-    "cs": "Чешки",
-    "de": "Немски",
-    "en": "Английски",
-    "es": "Испански",
-    "fr": "Френски",
-    "hi": "Хинди",
-    "it": "Италиански",
-    "nl": "Холандски",
-    "pl": "Полски",
-    "zh": "Китайски",
-    "tr": "Турски",
-    "ru": "Руски",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
+    "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
     "Caution": "Внимание"
 }
diff --git a/lang/bs.json b/lang/bs.json
index cb014f873..5e168a9db 100644
--- a/lang/bs.json
+++ b/lang/bs.json
@@ -442,6 +442,9 @@
     "zh": "Chinese",
     "tr": "Turkish",
     "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
     "Caution": "Caution"
 }
diff --git a/lang/cs.json b/lang/cs.json
index 28574c415..1e98d37e0 100644
--- a/lang/cs.json
+++ b/lang/cs.json
@@ -447,20 +447,21 @@
     "Notes": "Poznámky",
     "Amount in words": "Celkem slovy",
     "Please pay until": "Splatné do",
-    "cs": "Čeština",
-    "de": "Němčina",
-    "en": "Angličtina",
-    "es": "Španělština",
-    "fr": "Francouzština",
-    "hi": "Hindština",
-    "it": "Italština",
-    "nl": "Holandština",
-    "pl": "Polština",
-    "zh": "Čínština",
-    "tr": "Turečtina",
-    "ru": "Ruština",
-    "sv": "Švédština",
-    "sk": "Slovensky",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian",
     "The system was unable to update your server product. Please try again later or contact support.": "Systém nebyl schopen změnit Váš balíček serveru. Prosím zkuste to znovu nebo kontaktujte podporu.",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
     "Caution": "Upozornění"
diff --git a/lang/de.json b/lang/de.json
index d1adf4b27..ca6109f4d 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -447,20 +447,21 @@
     "Notes": "Notizen",
     "Amount in words": "Betrag in Worten",
     "Please pay until": "Zahlbar bis",
-    "cs": "Tschechisch",
-    "de": "Deutsch",
-    "en": "Englisch",
-    "es": "Spanisch",
-    "fr": "Französisch",
-    "hi": "Indisch",
-    "it": "Italienisch",
-    "nl": "Niederländisch",
-    "pl": "Polnisch",
-    "zh": "Chinesisch",
-    "tr": "Türkisch",
-    "ru": "Russisch",
-    "sv": "Schwedisch",
-    "sk": "Slowakisch",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian",
     "hourly": "Stündlich",
     "monthly": "Monatlich",
     "yearly": "Jährlich",
diff --git a/lang/en.json b/lang/en.json
index 69316d6ef..80a33afeb 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -646,5 +646,10 @@
     "Coupon Discount": "Coupon Discount",
     "Enter your coupon here...": "Enter your coupon here...",
     "Coupon": "Coupon",
-    "Checkout details": "Checkout details"
+    "Checkout details": "Checkout details",
+    "per 6 Months": "per 6 Months",
+    "per 3 Months": "per 3 Months",
+    "per Year": "per Year",
+    "per Week": "per Week",
+    "per Day": "per Day"
 }
diff --git a/lang/es.json b/lang/es.json
index 818d8e132..f6fad67fb 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -447,20 +447,21 @@
     "Notes": "Notas",
     "Amount in words": "Cantidad en palabras",
     "Please pay until": "Por favor pague hasta",
-    "cs": "Checo",
-    "de": "Alemán",
-    "en": "Inglés",
-    "es": "Español",
-    "fr": "Francés",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
     "hi": "Hindi",
-    "it": "Italiano",
-    "nl": "Holandés",
-    "pl": "Polaco",
-    "zh": "Chino",
-    "tr": "Turco",
-    "ru": "Ruso",
-    "sv": "Sueco",
-    "sk": "Eslovaco",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Actualizar/Reducir el servidor restablecerá su ciclo de facturación a ahora. Se reembolsarán los créditos sobrepagados. El precio del nuevo ciclo de facturación se retirará",
     "Caution": "Cuidado"
 }
diff --git a/lang/fr.json b/lang/fr.json
index 65a6bc44c..73fadfe1a 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -462,5 +462,6 @@
     "tr": "Turkish",
     "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/he.json b/lang/he.json
index a64fde04a..a84e34195 100644
--- a/lang/he.json
+++ b/lang/he.json
@@ -447,20 +447,21 @@
     "Notes": "הערות",
     "Amount in words": "כמות במילים",
     "Please pay until": "בבקשה שלם עד",
-    "cs": "צכית",
-    "de": "גרמנית",
-    "en": "אנגלית",
-    "es": "ספרדית",
-    "fr": "צרפתית",
-    "hi": "הודית",
-    "it": "אטלקית",
-    "nl": "הולנדית",
-    "pl": "פולנית",
-    "zh": "סִינִית",
-    "tr": "טורקית",
-    "ru": "רוסית",
-    "sv": "שוודית",
-    "sk": "סלובקית",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "שדרוג / הורדת שרת יאפס את מחזור החיוב שלך לעכשיו. הקרדיטים ששילמת יוחזרו. המחיר למחזור החיוב החדש יוחסם",
     "Caution": "אזהרה"
 }
diff --git a/lang/hi.json b/lang/hi.json
index 1449e92af..eaa3a469a 100644
--- a/lang/hi.json
+++ b/lang/hi.json
@@ -449,18 +449,19 @@
     "Please pay until": "कृपया भुगतान करें",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "अपने सर्वर को अपग्रेड / डाउनग्रेड करने से आपका बिलिंग साइकिल अब तक रीसेट हो जाएगा। आपके ओवरपेड क्रेडिट वापस किया जाएगा। नए बिलिंग साइकिल के लिए की गई मूल्य निकाला जाएगा",
     "Caution": "सावधान",
-    "cs": "चेक",
-    "de": "जर्मन",
-    "en": "अंग्रेज़ी",
-    "es": "स्पेनिश",
-    "fr": "फ्रांसीसी",
-    "hi": "हिंदी",
-    "it": "इटॅलियन",
-    "nl": "डच",
-    "pl": "पोलिश",
-    "zh": "चीनी",
-    "tr": "तुर्क",
-    "ru": "रूसी",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/hu.json b/lang/hu.json
index 30350eacf..64ad22f2e 100644
--- a/lang/hu.json
+++ b/lang/hu.json
@@ -449,18 +449,19 @@
     "Please pay until": "Fizetési határidő",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "A szerver frissítése / lefrissítése visszaállítja a számlázási ciklust az aktuálisra. A túlfizetett Kreditet visszatérítjük. A számlázási ciklus új ára lesz kivonva",
     "Caution": "Figyelem",
-    "cs": "Cseh",
-    "de": "Német",
-    "en": "Angol",
-    "es": "Spanyol",
-    "fr": "Francia",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
     "hi": "Hindi",
-    "it": "Olasz",
-    "nl": "Holland",
-    "pl": "Lengyel",
-    "zh": "Kínai",
-    "tr": "Török",
-    "ru": "Orosz",
-    "sv": "Svéd",
-    "sk": "Szlovák"
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/it.json b/lang/it.json
index ac2f1020f..a7adb0c87 100644
--- a/lang/it.json
+++ b/lang/it.json
@@ -449,18 +449,19 @@
     "Please pay until": "Per favore paga fino",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "L’aggiornamento / riduzione del tuo server reimposterà il tuo ciclo di fatturazione a ora. I tuoi crediti in eccesso saranno rimborsati. Il prezzo per il nuovo ciclo di fatturazione sarà prelevato",
     "Caution": "Attenzione",
-    "cs": "Ceco",
-    "de": "Tedesco",
-    "en": "Inglese",
-    "es": "Spagnolo",
-    "fr": "Francese",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
     "hi": "Hindi",
-    "it": "Italiano",
-    "nl": "Olandese",
-    "pl": "Polacco",
-    "zh": "Cinese",
-    "tr": "Turco",
-    "ru": "Russo",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/nl.json b/lang/nl.json
index 6ff9ecf53..2ac3a457e 100644
--- a/lang/nl.json
+++ b/lang/nl.json
@@ -449,18 +449,19 @@
     "Please pay until": "Gelieve te betalen tot",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgraden/downgraden van uw server zal uw facturatiecyclus resetten naar nu. Uw overbetalen krediet zal worden terugbetaald. De prijs voor de nieuwe facturatiecyclus zal worden afgeschreven",
     "Caution": "Let op",
-    "cs": "Tsjechisch",
-    "de": "Duits",
-    "en": "Engels",
-    "es": "Spaans",
-    "fr": "Frans",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
     "hi": "Hindi",
-    "it": "Italiaans",
-    "nl": "Nederlands",
-    "pl": "Pools",
-    "zh": "Chinees",
-    "tr": "Turks",
-    "ru": "Russisch",
-    "sv": "Zweeds",
-    "sk": "Slovakish"
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/pl.json b/lang/pl.json
index b1f4164dd..f519a975d 100644
--- a/lang/pl.json
+++ b/lang/pl.json
@@ -449,18 +449,19 @@
     "Please pay until": "Zapłać w ciągu:",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizacja / degradacja twojego serwera spowoduje zresetowanie cyklu rozliczeniowego do teraz. Twoje nadpłacone kredyty zostaną zwrócone. Cena za nowy cykl rozliczeniowy zostanie pobrana",
     "Caution": "Uwaga",
-    "cs": "Czeski",
-    "de": "Niemiecki",
-    "en": "Angielski",
-    "es": "Hiszpański",
-    "fr": "Francuski",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
     "hi": "Hindi",
-    "it": "Włoski",
+    "it": "Italian",
     "nl": "Dutch",
-    "pl": "Polski",
-    "zh": "Chiński",
-    "tr": "Turecki",
-    "ru": "Rosyjski",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/pt.json b/lang/pt.json
index d31d5b9b0..59f4dc9da 100644
--- a/lang/pt.json
+++ b/lang/pt.json
@@ -449,18 +449,19 @@
     "Please pay until": "Favor pagar até",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Atualizar / Reduzir o seu servidor irá redefinir o seu ciclo de faturação para agora. Os seus créditos pagos a mais serão reembolsados. O preço para o novo ciclo de faturação será debitado",
     "Caution": "Cuidado",
-    "cs": "Tcheco",
-    "de": "Alemão",
-    "en": "Inglês",
-    "es": "Espanhol",
-    "fr": "Francês",
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
     "hi": "Hindi",
-    "it": "Italiano",
-    "nl": "Holandês",
-    "pl": "Polonês",
-    "zh": "Chinês",
-    "tr": "Turco",
-    "ru": "Russo",
-    "sv": "Sueco",
-    "sk": "Eslovaco"
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/ro.json b/lang/ro.json
index ea3bdea16..79186b380 100644
--- a/lang/ro.json
+++ b/lang/ro.json
@@ -462,5 +462,6 @@
     "tr": "Turkish",
     "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/ru.json b/lang/ru.json
index 50e458e55..a18c39516 100644
--- a/lang/ru.json
+++ b/lang/ru.json
@@ -460,7 +460,8 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Русский",
+    "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/sh.json b/lang/sh.json
index bdf0019ba..399f29d3e 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -443,5 +443,8 @@
     "pl": "Polish",
     "zh": "Chinese",
     "tr": "Turkish",
-    "ru": "Russian"
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/sk.json b/lang/sk.json
index dc88baf2c..3a84cd4c1 100644
--- a/lang/sk.json
+++ b/lang/sk.json
@@ -462,5 +462,6 @@
     "tr": "Turkish",
     "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/sr.json b/lang/sr.json
index 599516313..2fbb35470 100644
--- a/lang/sr.json
+++ b/lang/sr.json
@@ -462,5 +462,6 @@
     "tr": "Turkish",
     "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/sv.json b/lang/sv.json
index 41d5d1c72..e53c9d875 100644
--- a/lang/sv.json
+++ b/lang/sv.json
@@ -462,5 +462,6 @@
     "tr": "Turkish",
     "ru": "Russian",
     "sv": "Swedish",
-    "sk": "Slovakish"
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/tr.json b/lang/tr.json
index 7d34213fc..fe1186cd1 100644
--- a/lang/tr.json
+++ b/lang/tr.json
@@ -449,18 +449,19 @@
     "Please pay until": "Lütfen şu tarihe kadar ödeyin",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Sunucunuzu yükseltmek / düşürmek faturalandırma döngünüzü şimdiye sıfırlayacaktır. Aşırı ödenen kredileriniz iade edilecektir. Yeni faturalandırma döngüsü için ödenen tutar çekilecektir",
     "Caution": "Dikkat",
-    "cs": "Çekçe",
-    "de": "Almanca",
-    "en": "İngilizce",
-    "es": "İspanyolca",
-    "fr": "Fransızca",
-    "hi": "Hintçe",
-    "it": "İtalyanca",
-    "nl": "Flemenkçe",
-    "pl": "Polonya",
-    "zh": "Çince",
-    "tr": "Türkçe",
-    "ru": "Rusça",
-    "sv": "İsveççe",
-    "sk": "Slovakça"
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }
diff --git a/lang/zh.json b/lang/zh.json
index 907ed1695..02e6ac43f 100644
--- a/lang/zh.json
+++ b/lang/zh.json
@@ -449,18 +449,19 @@
     "Please pay until": "请支付至",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "升级/降级你的服务器将重置你的账单周期。你的多余的点数将被退还。新的账单周期的价格将被扣除",
     "Caution": "警告",
-    "cs": "捷克语",
-    "de": "德语",
-    "en": "英语",
-    "es": "西班牙语",
-    "fr": "法语",
-    "hi": "印度语",
-    "it": "意大利语",
-    "nl": "荷兰语",
-    "pl": "波兰语",
-    "zh": "中文(简体)",
-    "tr": "土耳其语",
-    "ru": "俄语",
-    "sv": "乌克兰语",
-    "sk": "斯洛伐克语"
+    "cs": "Czech",
+    "de": "German",
+    "en": "English",
+    "es": "Spanish",
+    "fr": "French",
+    "hi": "Hindi",
+    "it": "Italian",
+    "nl": "Dutch",
+    "pl": "Polish",
+    "zh": "Chinese",
+    "tr": "Turkish",
+    "ru": "Russian",
+    "sv": "Swedish",
+    "sk": "Slovakish",
+    "hu": "Hungarian"
 }

From 61d62407175943153b01c28f2d2877b0286996b7 Mon Sep 17 00:00:00 2001
From: MrWeez <64205495+MrWeez@users.noreply.github.com>
Date: Thu, 8 Jun 2023 22:41:37 +0300
Subject: [PATCH 210/514] Correction of incorrect text output

---
 themes/default/views/servers/index.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/themes/default/views/servers/index.blade.php b/themes/default/views/servers/index.blade.php
index a1b827f65..93f0baeba 100644
--- a/themes/default/views/servers/index.blade.php
+++ b/themes/default/views/servers/index.blade.php
@@ -257,7 +257,7 @@ class="btn btn-danger  text-center float-right mr-2"
         const handleServerDelete = (serverId) => {
             Swal.fire({
                 title: "{{ __('Delete Server?') }}",
-                html: "{{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}}",
+                html: "{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}",
                 icon: 'warning',
                 confirmButtonColor: '#d9534f',
                 showCancelButton: true,

From 15a8807642abbef65b4eedb0a5acc27367ea9a75 Mon Sep 17 00:00:00 2001
From: Dennis <ownerdennis8@gmail.com>
Date: Thu, 8 Jun 2023 23:36:16 +0200
Subject: [PATCH 211/514] "No Server" Option

---
 themes/default/views/ticket/create.blade.php | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/themes/default/views/ticket/create.blade.php b/themes/default/views/ticket/create.blade.php
index f9d35ad4d..c25b20e6b 100644
--- a/themes/default/views/ticket/create.blade.php
+++ b/themes/default/views/ticket/create.blade.php
@@ -44,14 +44,16 @@
                                     </span>
                                     @endif
                                 </div>
-                                @if ($servers->count() >= 1)
+
                                 <div class="form-group col-sm-12 {{ $errors->has('server') ? ' has-error' : '' }}">
                                     <label for="server" class="control-label">{{__("Server")}}</label>
                                     <select id="server" type="server" class="form-control" name="server">
-                                        <option value="">{{__("Select Servers")}}</option>
+                                      <option value="">{{ __("No Server") }}</option>
+                                      @if ($servers->count() >= 1)
                                         @foreach ($servers as $server)
                                         <option value="{{ $server->id }}">{{ $server->name }}</option>
                                         @endforeach
+                                        @endif
                                     </select>
 
                                     @if ($errors->has('category'))
@@ -60,7 +62,7 @@
                                     </span>
                                     @endif
                                 </div>
-                                @endif
+
                                 <div class="form-group col-sm-12 {{ $errors->has('ticketcategory') ? ' has-error' : '' }}">
                                     <label for="ticketcategory" class="control-label">{{__("Category")}}</label>
                                     <select id="ticketcategory" type="ticketcategory" class="form-control" required name="ticketcategory">
@@ -143,4 +145,3 @@
 
     </script>
 @endsection
-

From 7795ea3d9865dc6a4f894895cd54c3c1be445c7b Mon Sep 17 00:00:00 2001
From: MrWeez <64205495+MrWeez@users.noreply.github.com>
Date: Fri, 9 Jun 2023 12:17:11 +0300
Subject: [PATCH 212/514] Fixing the path of the installation log file

---
 public/install/forms.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 726e22ec3..223b26bfe 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -88,7 +88,7 @@
         header('LOCATION: index.php?step=3');
     } else {
         wh_log('Feeding the Database failed', 'debug');
-        header('LOCATION: index.php?step=2.5&message=There was an error. Please check the .txt file in /var/www/controlpanel/public/install/logs !');
+        header('LOCATION: index.php?step=2.5&message=There was an error. Please check the installer.log file in /var/www/controlpanel/storage/logs !');
     }
 }
 

From 3b18b79b475954057dbe690a5d0533a9f803ac09 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Fri, 9 Jun 2023 13:38:56 +0300
Subject: [PATCH 213/514] Language variables

---
 lang/bg.json |  8 +++++++-
 lang/bs.json |  8 +++++++-
 lang/cs.json |  9 ++++++++-
 lang/de.json |  6 +++++-
 lang/en.json |  6 +++++-
 lang/es.json |  6 +++++-
 lang/fr.json |  6 +++++-
 lang/he.json |  6 +++++-
 lang/hi.json |  6 +++++-
 lang/hu.json |  6 +++++-
 lang/it.json |  6 +++++-
 lang/nl.json |  6 +++++-
 lang/pl.json |  6 +++++-
 lang/pt.json |  6 +++++-
 lang/ro.json |  6 +++++-
 lang/ru.json | 10 +++++++---
 lang/sh.json |  6 +++++-
 lang/sk.json |  6 +++++-
 lang/sr.json |  6 +++++-
 lang/sv.json |  6 +++++-
 lang/tr.json |  6 +++++-
 lang/zh.json |  6 +++++-
 22 files changed, 119 insertions(+), 24 deletions(-)

diff --git a/lang/bg.json b/lang/bg.json
index 1e869cbfe..b1fc35680 100644
--- a/lang/bg.json
+++ b/lang/bg.json
@@ -463,5 +463,11 @@
     "sk": "Slovakish",
     "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
-    "Caution": "Внимание"
+    "Caution": "Внимание",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
+    "Caution": "Внимание",
+    "You can not see your Referral Code": "Не можете да видите вашия код за препращане",
+    "SERVER NAME": "ИМЕ НА СЪРВЪР",
+    "STORAGE": "Съхранение",
+    "Cancel": "Отказ"
 }
diff --git a/lang/bs.json b/lang/bs.json
index 5e168a9db..2b32fdcca 100644
--- a/lang/bs.json
+++ b/lang/bs.json
@@ -446,5 +446,11 @@
     "sk": "Slovakish",
     "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
-    "Caution": "Caution"
+    "Caution": "Caution",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
+    "Caution": "Caution",
+    "You can not see your Referral Code": "You can not see your Referral Code",
+    "SERVER NAME": "SERVER NAME",
+    "STORAGE": "STORAGE",
+    "Cancel": "Cancel"
 }
diff --git a/lang/cs.json b/lang/cs.json
index 1e98d37e0..d3101515a 100644
--- a/lang/cs.json
+++ b/lang/cs.json
@@ -464,5 +464,12 @@
     "hu": "Hungarian",
     "The system was unable to update your server product. Please try again later or contact support.": "Systém nebyl schopen změnit Váš balíček serveru. Prosím zkuste to znovu nebo kontaktujte podporu.",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
-    "Caution": "Upozornění"
+    "Caution": "Upozornění",
+    "The system was unable to update your server product. Please try again later or contact support.": "Systém nebyl schopen změnit Váš balíček serveru. Prosím zkuste to znovu nebo kontaktujte podporu.",
+    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
+    "Caution": "Upozornění",
+    "You can not see your Referral Code": "Nemůžete vidět váš doporučující kód",
+    "SERVER NAME": "NÁZEV SERVERU",
+    "STORAGE": "ZAVAZADLO",
+    "Cancel": "Zrušit"
 }
diff --git a/lang/de.json b/lang/de.json
index ca6109f4d..e9ab272d9 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -486,5 +486,9 @@
     "No, abort!": "Abbrechen",
     "Billing period": "Abrechnungsperiode",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Das Upgrade/Downgrade Ihres Servers wird Ihre Abrechnungsperiode auf \"jetzt\" zurücksetzen. Ihre überzahlten Credits werden erstattet. Der Preis für die neue Abrechnungsperiode wird abgebucht.",
-    "Caution": "Achtung"
+    "Caution": "Achtung",
+    "You can not see your Referral Code": "Sie können Ihren Empfehlungscode nicht sehen",
+    "SERVER NAME": "SERVERNAMEN",
+    "STORAGE": "STORAGE",
+    "Cancel": "Stornieren"
 }
diff --git a/lang/en.json b/lang/en.json
index 80a33afeb..633a4ec2c 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -651,5 +651,9 @@
     "per 3 Months": "per 3 Months",
     "per Year": "per Year",
     "per Week": "per Week",
-    "per Day": "per Day"
+    "per Day": "per Day",
+    "You can not see your Referral Code": "You can not see your Referral Code",
+    "SERVER NAME": "SERVER NAME",
+    "STORAGE": "STORAGE",
+    "Cancel": "Cancel"
 }
diff --git a/lang/es.json b/lang/es.json
index f6fad67fb..50ecfb4a4 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -463,5 +463,9 @@
     "sk": "Slovakish",
     "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Actualizar/Reducir el servidor restablecerá su ciclo de facturación a ahora. Se reembolsarán los créditos sobrepagados. El precio del nuevo ciclo de facturación se retirará",
-    "Caution": "Cuidado"
+    "Caution": "Cuidado",
+    "You can not see your Referral Code": "Не puedes ver tu Código de Referencia",
+    "SERVER NAME": "NOMBRE DEL SERVIDOR",
+    "STORAGE": "ALMACENAMIENTO",
+    "Cancel": "Cancelar"
 }
diff --git a/lang/fr.json b/lang/fr.json
index 73fadfe1a..16e7150f3 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Vous ne pouvez pas voir votre Code de parrainage",
+    "SERVER NAME": "NOM DU SERVEUR",
+    "STORAGE": "STOCKAGE",
+    "Cancel": "Annuler"
 }
diff --git a/lang/he.json b/lang/he.json
index a84e34195..4d09b0397 100644
--- a/lang/he.json
+++ b/lang/he.json
@@ -463,5 +463,9 @@
     "sk": "Slovakish",
     "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "שדרוג / הורדת שרת יאפס את מחזור החיוב שלך לעכשיו. הקרדיטים ששילמת יוחזרו. המחיר למחזור החיוב החדש יוחסם",
-    "Caution": "אזהרה"
+    "Caution": "אזהרה",
+    "You can not see your Referral Code": "You can not see your Referral Code",
+    "SERVER NAME": "SERVER NAME",
+    "STORAGE": "STORAGE",
+    "Cancel": "Cancel"
 }
diff --git a/lang/hi.json b/lang/hi.json
index eaa3a469a..c36b7d014 100644
--- a/lang/hi.json
+++ b/lang/hi.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "आप अपना रेफरल कोड नहीं देख सकते",
+    "SERVER NAME": "सर्वर का नाम",
+    "STORAGE": "स्टोरेज",
+    "Cancel": "रद्द करें"
 }
diff --git a/lang/hu.json b/lang/hu.json
index 64ad22f2e..af3ac9622 100644
--- a/lang/hu.json
+++ b/lang/hu.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Nem látod a hivatkozási kódodat",
+    "SERVER NAME": "SZERVERNEVE",
+    "STORAGE": "TÁROLÁS",
+    "Cancel": "Mégse"
 }
diff --git a/lang/it.json b/lang/it.json
index a7adb0c87..1fce8de29 100644
--- a/lang/it.json
+++ b/lang/it.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Non puoi vedere il tuo Codice di Riferimento",
+    "SERVER NAME": "NOME DEL SERVER",
+    "STORAGE": "ARCHIVIAZIONE",
+    "Cancel": "Annulla"
 }
diff --git a/lang/nl.json b/lang/nl.json
index 2ac3a457e..6db2f669d 100644
--- a/lang/nl.json
+++ b/lang/nl.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Je kunt je Verwijzingscode niet zien",
+    "SERVER NAME": "SERVERNAAM",
+    "STORAGE": "OPSLAG",
+    "Cancel": "Annuleren"
 }
diff --git a/lang/pl.json b/lang/pl.json
index f519a975d..d14b00803 100644
--- a/lang/pl.json
+++ b/lang/pl.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Nie możesz zobaczyć swojego kodu polecającego",
+    "SERVER NAME": "NAZWA SERWERA",
+    "STORAGE": "PAMIĘĆ",
+    "Cancel": "Anuluj"
 }
diff --git a/lang/pt.json b/lang/pt.json
index 59f4dc9da..9083b97d4 100644
--- a/lang/pt.json
+++ b/lang/pt.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Você não pode ver o seu Código de Referência",
+    "SERVER NAME": "NOME DO SERVIDOR",
+    "STORAGE": "ARMAZENAMENTO",
+    "Cancel": "Cancelar"
 }
diff --git a/lang/ro.json b/lang/ro.json
index 79186b380..d9a949671 100644
--- a/lang/ro.json
+++ b/lang/ro.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Nu poți vedea codul tău de recomandare",
+    "SERVER NAME": "NUMELE SERVERULUI",
+    "STORAGE": "STOCARE",
+    "Cancel": "Anulare"
 }
diff --git a/lang/ru.json b/lang/ru.json
index a18c39516..ec254e371 100644
--- a/lang/ru.json
+++ b/lang/ru.json
@@ -149,7 +149,6 @@
     "Will hide this option from being selected": "Скрывает эту опцию от выбора",
     "Price in": "Цена в",
     "Memory": "Оперативная память",
-    "Cpu": "Процессор",
     "Swap": "Файл подкачки",
     "This is what the users sees": "Вот что видят пользователи",
     "Disk": "Диск",
@@ -164,7 +163,6 @@
     "This product will only be available for these nodes": "Данный продукт будет доступен только для этих узлов",
     "This product will only be available for these eggs": "Этот продукт будет доступен только для этих яиц",
     "Product": "Продукт",
-    "CPU": "Процессор",
     "Updated at": "Обновлено",
     "User": "Пользователь",
     "Config": "Конфигурация",
@@ -463,5 +461,11 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Вы не можете видеть свой реферельный код",
+    "SERVER NAME": "НАЗВАНИЕ СЕРВЕРА",
+    "CPU": "ЦПУ",
+    "MEMORY": "ОЗУ",
+    "STORAGE": "ХРАНИЛИЩЕ",
+    "Cancel": "Отменить"
 }
diff --git a/lang/sh.json b/lang/sh.json
index 399f29d3e..2890e77e7 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -446,5 +446,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "You can not see your Referral Code",
+    "SERVER NAME": "SERVER NAME",
+    "STORAGE": "STORAGE",
+    "Cancel": "Cancel"
 }
diff --git a/lang/sk.json b/lang/sk.json
index 3a84cd4c1..2db59f349 100644
--- a/lang/sk.json
+++ b/lang/sk.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Nemôžete vidieť váš Referral Code",
+    "SERVER NAME": "MENO SERVERA",
+    "STORAGE": "ÚLOŽISKO",
+    "Cancel": "Zrušiť"
 }
diff --git a/lang/sr.json b/lang/sr.json
index 2fbb35470..50cab9924 100644
--- a/lang/sr.json
+++ b/lang/sr.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Не можете видети свој код за препоруку",
+    "SERVER NAME": "ИМЕ СЕРВЕРА",
+    "STORAGE": "СКЛАДИШТЕ",
+    "Cancel": "Откажи"
 }
diff --git a/lang/sv.json b/lang/sv.json
index e53c9d875..552f0def3 100644
--- a/lang/sv.json
+++ b/lang/sv.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Du kan inte se din hänvisningskod",
+    "SERVER NAME": "SERVERNAMN",
+    "STORAGE": "LAGRING",
+    "Cancel": "Avbryt"
 }
diff --git a/lang/tr.json b/lang/tr.json
index fe1186cd1..f05ebe60e 100644
--- a/lang/tr.json
+++ b/lang/tr.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "Yönlendirme Kodunuzu göremezsiniz",
+    "SERVER NAME": "SUNUCU ADI",
+    "STORAGE": "DEPOLAMA",
+    "Cancel": "Iptal"
 }
diff --git a/lang/zh.json b/lang/zh.json
index 02e6ac43f..58e00e356 100644
--- a/lang/zh.json
+++ b/lang/zh.json
@@ -463,5 +463,9 @@
     "ru": "Russian",
     "sv": "Swedish",
     "sk": "Slovakish",
-    "hu": "Hungarian"
+    "hu": "Hungarian",
+    "You can not see your Referral Code": "您无法查看您的推荐码",
+    "SERVER NAME": "服务器名称",
+    "STORAGE": "存储",
+    "Cancel": "取消"
 }

From fd5790c7750a05a7b0731f4263f0d03ae3129a27 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Fri, 9 Jun 2023 13:46:19 +0300
Subject: [PATCH 214/514] Translation of some fields

---
 themes/default/views/profile/index.blade.php   |  5 ++---
 .../default/views/servers/settings.blade.php   | 18 +++++++++---------
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/themes/default/views/profile/index.blade.php b/themes/default/views/profile/index.blade.php
index 459384379..ba95bca44 100644
--- a/themes/default/views/profile/index.blade.php
+++ b/themes/default/views/profile/index.blade.php
@@ -105,14 +105,14 @@ class="fa fa-coins mr-2"></i>{{ $user->Credits() }}</span>
                                             <div class="mt-1">
                                                     <span class="badge badge-success"><i
                                                             class="fa fa-user-check mr-2"></i>
-                                                        {{_("Referral URL")}} :
+                                                        {{__("Referral URL")}} :
                                                         <span onclick="onClickCopy()" id="RefLink" style="cursor: pointer;">
                                                             {{route("register")}}?ref={{$user->referral_code}}</span>
                                                     </span>
                                                 @else
                                                     <span class="badge badge-warning"><i
                                                             class="fa fa-user-check mr-2"></i>
-                                                        {{_("You can not see your Referral Code")}}</span>
+                                                        {{__("You can not see your Referral Code")}}</span>
                                         @endcan
                                             </div>
                                         @endif
@@ -367,4 +367,3 @@ function onClickCopy() {
         }
     </script>
     @endsection
-
diff --git a/themes/default/views/servers/settings.blade.php b/themes/default/views/servers/settings.blade.php
index bbcdf72d7..7aba57d01 100644
--- a/themes/default/views/servers/settings.blade.php
+++ b/themes/default/views/servers/settings.blade.php
@@ -33,7 +33,7 @@
                       <div class="row">
                         <div class="col-8">
                           <div class="numbers">
-                            <p class="text-sm mb-0 text-uppercase font-weight-bold">SERVER NAME</p>
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">{{ __('SERVER NAME') }}</p>
                             <h5 class="font-weight-bolder" id="domain_text">
                               <span class="text-success text-sm font-weight-bolder">{{ $server->name }}</span>
                             </h5>
@@ -54,9 +54,9 @@
                       <div class="row">
                         <div class="col-8">
                           <div class="numbers">
-                            <p class="text-sm mb-0 text-uppercase font-weight-bold">CPU</p>
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">{{ __('CPU') }}</p>
                             <h5 class="font-weight-bolder">
-                              <span class="text-success text-sm font-weight-bolder">@if($server->product->cpu == 0)Unlimited @else {{$server->product->cpu}} % @endif</span>
+                              <span class="text-success text-sm font-weight-bolder">@if($server->product->cpu == 0){{ __('Unlimited') }} @else {{$server->product->cpu}} % @endif</span>
                             </h5>
                           </div>
                         </div>
@@ -75,9 +75,9 @@
                       <div class="row">
                         <div class="col-8">
                           <div class="numbers">
-                            <p class="text-sm mb-0 text-uppercase font-weight-bold">Memory</p>
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">{{ __('MEMORY') }}</p>
                             <h5 class="font-weight-bolder">
-                              <span class="text-success text-sm font-weight-bolder">@if($server->product->memory == 0)Unlimited @else {{$server->product->memory}}MB @endif</span>
+                              <span class="text-success text-sm font-weight-bolder">@if($server->product->memory == 0){{ __('Unlimited') }} @else {{$server->product->memory}}MB @endif</span>
                             </h5>
                           </div>
                         </div>
@@ -96,9 +96,9 @@
                       <div class="row">
                         <div class="col-8">
                           <div class="numbers">
-                            <p class="text-sm mb-0 text-uppercase font-weight-bold">STORAGE</p>
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">{{ __('STORAGE') }}</p>
                             <h5 class="font-weight-bolder">
-                              <span class="text-success text-sm font-weight-bolder">@if($server->product->disk == 0)Unlimited @else {{$server->product->disk}}MB @endif</span>
+                              <span class="text-success text-sm font-weight-bolder">@if($server->product->disk == 0){{ __('Unlimited') }} @else {{$server->product->disk}}MB @endif</span>
                             </h5>
                           </div>
                         </div>
@@ -266,7 +266,7 @@ class="btn btn-info btn-md">
                                                   @endif
                                               @endforeach
                                           </select>
-                                          
+
                                           <br> <strong>{{__("Caution") }}:</strong> {{__("Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed")}}. <br>
                                           <br> {{__("Server will be automatically restarted once upgraded")}}
                                     </div>
@@ -298,7 +298,7 @@ class="btn btn-danger btn-md">
                                 {{__("This is an irreversible action, all files of this server will be removed!")}}
                               </div>
                               <div class="modal-footer">
-                                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+                                <button type="button" class="btn btn-secondary" data-dismiss="modal">{{ __('Cancel') }}</button>
                                 <form class="d-inline" method="post" action="{{ route('servers.destroy', ['server' => $server->id]) }}">
                                   @csrf
                                   @method('DELETE')

From 57ca71225495ce73c3bdb1361782b70fb5bc922c Mon Sep 17 00:00:00 2001
From: MrWeez <64205495+MrWeez@users.noreply.github.com>
Date: Fri, 9 Jun 2023 17:29:25 +0300
Subject: [PATCH 215/514] Removing duplicate rows

---
 lang/bg.json | 2 --
 lang/bs.json | 3 ---
 lang/cs.json | 3 ---
 lang/sh.json | 1 -
 4 files changed, 9 deletions(-)

diff --git a/lang/bg.json b/lang/bg.json
index b1fc35680..a5c070c57 100644
--- a/lang/bg.json
+++ b/lang/bg.json
@@ -464,8 +464,6 @@
     "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
     "Caution": "Внимание",
-    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Актуализирането / надграждането на сървъра ви ще нулира вашата билнгова цикъл до сега. Вашите превишени кредити ще бъдат възстановени. Цената за новия билнгов цикъл ще бъде извлечена",
-    "Caution": "Внимание",
     "You can not see your Referral Code": "Не можете да видите вашия код за препращане",
     "SERVER NAME": "ИМЕ НА СЪРВЪР",
     "STORAGE": "Съхранение",
diff --git a/lang/bs.json b/lang/bs.json
index 2b32fdcca..fe4f110bb 100644
--- a/lang/bs.json
+++ b/lang/bs.json
@@ -417,7 +417,6 @@
     "Value": "Value",
     "Edit Configuration": "Edit Configuration",
     "Text Field": "Text Field",
-    "Cancel": "Cancel",
     "Save": "Save",
     "Images and Icons may be cached, reload without cache to see your changes appear": "Images and Icons may be cached, reload without cache to see your changes appear",
     "Enter your companys name": "Enter your companys name",
@@ -447,8 +446,6 @@
     "hu": "Hungarian",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
     "Caution": "Caution",
-    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed",
-    "Caution": "Caution",
     "You can not see your Referral Code": "You can not see your Referral Code",
     "SERVER NAME": "SERVER NAME",
     "STORAGE": "STORAGE",
diff --git a/lang/cs.json b/lang/cs.json
index d3101515a..a0074d402 100644
--- a/lang/cs.json
+++ b/lang/cs.json
@@ -465,9 +465,6 @@
     "The system was unable to update your server product. Please try again later or contact support.": "Systém nebyl schopen změnit Váš balíček serveru. Prosím zkuste to znovu nebo kontaktujte podporu.",
     "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
     "Caution": "Upozornění",
-    "The system was unable to update your server product. Please try again later or contact support.": "Systém nebyl schopen změnit Váš balíček serveru. Prosím zkuste to znovu nebo kontaktujte podporu.",
-    "Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed": "Aktualizace/snížení vašeho serveru resetuje váš fakturační cyklus na aktuální. Vaše přeplacené kredity budou vráceny. Cena za nový fakturační cyklus bude odečtena",
-    "Caution": "Upozornění",
     "You can not see your Referral Code": "Nemůžete vidět váš doporučující kód",
     "SERVER NAME": "NÁZEV SERVERU",
     "STORAGE": "ZAVAZADLO",
diff --git a/lang/sh.json b/lang/sh.json
index 2890e77e7..c65182bb1 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -417,7 +417,6 @@
     "Value": "Value",
     "Edit Configuration": "Edit Configuration",
     "Text Field": "Text Field",
-    "Cancel": "Cancel",
     "Save": "Save",
     "Images and Icons may be cached, reload without cache to see your changes appear": "Images and Icons may be cached, reload without cache to see your changes appear",
     "Enter your companys name": "Enter your companys name",

From 458d6a3f26d947a4801a6ae6fc528795500c3c28 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:13:02 +0200
Subject: [PATCH 216/514] Change design of Roles on list

---
 app/Http/Controllers/Admin/RoleController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 9a521938a..b10c1b012 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -203,7 +203,7 @@ class="fa fas fa-trash"></i></button>
             })
 
             ->editColumn('name', function (Role $role) {
-                return "<span style=\"color: $role->color\">$role->name</span>";
+                return "<span style='background-color: $role->color' class='badge'>$role->name</span>";
             })
             ->editColumn('usercount', function ($query) {
                 return $query->users_count;

From 8785325a94e3d355632d22d5655b04f312069474 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:19:12 +0200
Subject: [PATCH 217/514] fix referral not being shown on home

---
 themes/default/views/home.blade.php | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/themes/default/views/home.blade.php b/themes/default/views/home.blade.php
index b3827bee1..426550823 100644
--- a/themes/default/views/home.blade.php
+++ b/themes/default/views/home.blade.php
@@ -251,14 +251,14 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                                     <table class="table">
                                         <thead>
                                             <tr>
-                                                @if(in_array($referral_settings->mode, ["Commission","Both"]))<th>{{ __('Reward per registered user') }}</th> @endif
-                                                @if(in_array($referral_settings->mode, ["Sign-Up","Both"]))<th>{{ __('New user payment commision') }}</th> @endif
+                                                @if(in_array($referral_settings->mode, ["comission","both"]))<th>{{ __('Reward per registered user') }}</th> @endif
+                                                @if(in_array($referral_settings->mode, ["sign-up","both"]))<th>{{ __('New user payment commision') }}</th> @endif
                                             </tr>
                                         </thead>
                                         <tbody>
                                             <tr>
-                                                @if(in_array($referral_settings->mode, ["Commission","Both"]))<td>{{ $referral_settings->reward }} {{ $general_settings->credits_display_name }}</td> @endif
-                                                @if(in_array($referral_settings->mode, ["Sign-Up","Both"]))<td>{{ $referral_settings->percentage }}%</td> @endif
+                                                @if(in_array($referral_settings->mode, ["comission","both"]))<td>{{ $referral_settings->reward }} {{ $general_settings->credits_display_name }}</td> @endif
+                                                @if(in_array($referral_settings->mode, ["sign-up","both"]))<td>{{ $referral_settings->percentage }}%</td> @endif
                                             </tr>
                                         </tbody>
                                     </table>

From 3a348ee894048164bc8c03e104fb446aada6c702 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:21:40 +0200
Subject: [PATCH 218/514] fix installer showing php8.2 as red

---
 public/install/functions.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/install/functions.php b/public/install/functions.php
index ebba003b1..8eb1318cb 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -19,7 +19,7 @@
 
 $requirements = [
     'minPhp' => '8.1',
-    'maxPhp' => '8.2', // This version is not supported
+    'maxPhp' => '8.3', // This version is not supported
     'mysql' => '5.7.22',
 ];
 

From 9a04f373f0f5a6dc85294bfaa6a0328a7fc0da17 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:23:23 +0200
Subject: [PATCH 219/514] fix voucher showing expiry "never"

---
 app/Http/Controllers/Admin/VoucherController.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php
index f39f9c335..ec6c5232f 100644
--- a/app/Http/Controllers/Admin/VoucherController.php
+++ b/app/Http/Controllers/Admin/VoucherController.php
@@ -245,10 +245,10 @@ public function dataTable()
             })
             ->editColumn('expires_at', function (Voucher $voucher) {
                 if (! $voucher->expires_at) {
-                    return '';
+                    return __("Never");
                 }
 
-                return $voucher->expires_at ? $voucher->expires_at->diffForHumans() : '';
+                return $voucher->expires_at ? $voucher->expires_at->diffForHumans() : __("Never");
             })
             ->editColumn('code', function (Voucher $voucher) {
                 return "<code>{$voucher->code}</code>";

From dfd5c184af6433ff4b78c64c7422f167b224bf69 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:25:58 +0200
Subject: [PATCH 220/514] increase max width to show lonjg emails on user show

---
 themes/default/views/admin/users/show.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/themes/default/views/admin/users/show.blade.php b/themes/default/views/admin/users/show.blade.php
index 5656c307b..6bdc21921 100644
--- a/themes/default/views/admin/users/show.blade.php
+++ b/themes/default/views/admin/users/show.blade.php
@@ -100,7 +100,7 @@
                                     <label>{{ __('Email') }}</label>
                                 </div>
                                 <div class="col-lg-8">
-                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                    <span style="max-width: 400px;" class="d-inline-block text-truncate">
                                         {{ $user->email }}
                                     </span>
                                 </div>

From 77e5b1302ed728425f5d47be849fdbc08b526e20 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:29:29 +0200
Subject: [PATCH 221/514] move oom killer

---
 themes/default/views/admin/products/index.blade.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/themes/default/views/admin/products/index.blade.php b/themes/default/views/admin/products/index.blade.php
index 17cbf9494..a951a46f6 100644
--- a/themes/default/views/admin/products/index.blade.php
+++ b/themes/default/views/admin/products/index.blade.php
@@ -51,10 +51,10 @@ class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
                             <th>{{__('Disk')}}</th>
                             <th>{{__('Databases')}}</th>
                             <th>{{__('Backups')}}</th>
+                            <th>{{__('OOM Killer')}}</th>
                             <th>{{__('Nodes')}}</th>
                             <th>{{__('Eggs')}}</th>
                             <th>{{__('Min Credits')}}</th>
-                            <th>{{__('OOM Killer')}}</th>
                             <th>{{__('Servers')}}</th>
                             <th>{{__('Created at')}}</th>
                             <th>{{ __('Actions') }}</th>
@@ -101,10 +101,10 @@ function submitResult() {
                     {data: "disk"},
                     {data: "databases"},
                     {data: "backups"},
+                    {data: "oom_killer"},
                     {data: "nodes", sortable: false},
                     {data: "eggs", sortable: false},
                     {data: "minimum_credits"},
-                    {data: "oom_killer"},
                     {data: "servers", sortable: false},
                     {data: "created_at"},
                     {data: "actions", sortable: false}

From 31bbc4f9063f6c59745ee0a17c247b9d27860c39 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:43:06 +0200
Subject: [PATCH 222/514] fix wrong credentials message on username

---
 themes/default/views/auth/login.blade.php | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/themes/default/views/auth/login.blade.php b/themes/default/views/auth/login.blade.php
index 8c3cbb786..c570550d9 100644
--- a/themes/default/views/auth/login.blade.php
+++ b/themes/default/views/auth/login.blade.php
@@ -32,7 +32,7 @@ class="mr-1">{{ config('app.name', 'Laravel') }}</b></a>
                         <div class="form-group">
                             <div class="input-group mb-3">
                                 <input type="text" name="email"
-                                    class="form-control @error('email') is-invalid @enderror"
+                                    class="form-control @error('email') is-invalid @enderror @error('name') is-invalid @enderror"
                                     placeholder="{{ __('Email or Username') }}">
                                 <div class="input-group-append">
                                     <div class="input-group-text">
@@ -41,11 +41,11 @@ class="form-control @error('email') is-invalid @enderror"
                                 </div>
 
                             </div>
-                            @error('email')
+                          @if ($errors->get("email") || $errors->get("name"))
                                 <span class="text-danger" role="alert">
-                                    <small><strong>{{ $message }}</strong></small>
+                                    <small><strong>{{ $errors->first('email') ? $errors->first('email') : $errors->first('name') }}</strong></small>
                                 </span>
-                            @enderror
+                            @endif
                         </div>
 
                         <div class="form-group">

From 74c7fc9da10674b840865081737c97bea9ffecdb Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 9 Jun 2023 23:55:17 +0200
Subject: [PATCH 223/514] more details on admin overview

---
 .../Controllers/Admin/OverViewController.php     |  4 +++-
 .../default/views/admin/overview/index.blade.php | 16 +++++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Admin/OverViewController.php b/app/Http/Controllers/Admin/OverViewController.php
index 866d8ece3..2b0a4f69d 100644
--- a/app/Http/Controllers/Admin/OverViewController.php
+++ b/app/Http/Controllers/Admin/OverViewController.php
@@ -37,7 +37,9 @@ public function index(GeneralSettings $general_settings)
         //Get counters
         $counters = collect();
         //Set basic variables in the collection
-        $counters->put('users', User::query()->count());
+        $counters->put('users', collect());
+        $counters['users']->active = User::where("suspended", 0)->count();
+        $counters['users']->total = User::query()->count();
         $counters->put('credits', number_format(User::query()->whereHas("roles", function($q){ $q->where("id", "!=", "1"); })->sum('credits'), 2, '.', ''));
         $counters->put('payments', Payment::query()->count());
         $counters->put('eggs', Egg::query()->count());
diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index 6b5bd4112..5a6fc1d53 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -58,7 +58,12 @@ class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
                         <span class="info-box-icon bg-info elevation-1"><i class="fas fa-server"></i></span>
 
                         <div class="info-box-content">
-                            <span class="info-box-text">{{__('Servers')}}</span>
+                            <span class="info-box-text">{{__('Servers')}}
+                          <i class="fas fa-info-circle mr-4" data-toggle="popover"
+                             data-trigger="hover" data-placement="top"
+                             data-html="true"
+                             data-content="{{ __("This shows the total active servers and the total servers. Total active servers are all servers which are not suspended") }}"></i>
+                            </span>
                             <span class="info-box-number">{{$counters['servers']->active}}/{{$counters['servers']->total}}</span>
                         </div>
                         <!-- /.info-box-content -->
@@ -71,8 +76,13 @@ class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
                         <span class="info-box-icon bg-primary elevation-1"><i class="fas fa-users"></i></span>
 
                         <div class="info-box-content">
-                            <span class="info-box-text">{{__('Users')}}</span>
-                            <span class="info-box-number">{{$counters['users']}}</span>
+                            <span class="info-box-text">{{__('Users')}}
+                              <i class="fas fa-info-circle mr-4" data-toggle="popover"
+                                  data-trigger="hover" data-placement="top"
+                                  data-html="true"
+                                  data-content="{{ __("This shows the total active Users and the total Users. Total active Users are all Users which are not suspended") }}"></i>
+                              </span>
+                          <span class="info-box-number">{{$counters['users']->active}}/{{$counters['users']->total}}</span>
                         </div>
                         <!-- /.info-box-content -->
                     </div>

From 0b1670ad50c6976222cd2b33ade842d76a8f4159 Mon Sep 17 00:00:00 2001
From: Dennis <ownerdennis8@gmail.com>
Date: Sat, 10 Jun 2023 01:24:16 +0200
Subject: [PATCH 224/514] Fix payment_method

---
 themes/default/views/store/checkout.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index 8c7697806..b0f91f0de 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -52,7 +52,7 @@ class="form-check-label h5 checkout-gateway-label"
                                                                         <span class="mr-3">{{ $gateway->name }}</span>
                                                                     </label>
                                                                     <button class="btn btn-primary rounded" type="button"
-                                                                        name="payment-method" id="{{ $gateway->name }}"
+                                                                        name="payment_method" id="{{ $gateway->name }}"
                                                                         value="{{ $gateway->name }}"
                                                                         :class="payment_method === '{{ $gateway->name }}' ?
                                                                             'active' : ''"

From d5e9f3cdaf22c9ff2c97c68e9456912b4d1b02b7 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sat, 10 Jun 2023 02:03:37 +0200
Subject: [PATCH 225/514] =?UTF-8?q?chore:=20=F0=9F=94=A5=20Remove=20unused?=
 =?UTF-8?q?=20extension=20routes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Extensions/PaymentGateways/Mollie/web_routes.php | 4 ----
 app/Extensions/PaymentGateways/PayPal/web_routes.php | 4 ----
 app/Extensions/PaymentGateways/Stripe/web_routes.php | 4 ----
 3 files changed, 12 deletions(-)

diff --git a/app/Extensions/PaymentGateways/Mollie/web_routes.php b/app/Extensions/PaymentGateways/Mollie/web_routes.php
index 2314774af..6d07f533d 100644
--- a/app/Extensions/PaymentGateways/Mollie/web_routes.php
+++ b/app/Extensions/PaymentGateways/Mollie/web_routes.php
@@ -4,10 +4,6 @@
 use App\Extensions\PaymentGateways\Mollie\MollieExtension;
 
 Route::middleware(['web', 'auth'])->group(function () {
-    Route::get('payment/MolliePay/{shopProduct}', function (MollieExtension $mollieExtension) {
-        $mollieExtension->pay(request());
-    })->name('payment.MolliePay');
-
     Route::get(
         'payment/MollieSuccess',
         function () {
diff --git a/app/Extensions/PaymentGateways/PayPal/web_routes.php b/app/Extensions/PaymentGateways/PayPal/web_routes.php
index 17d1ed028..75b1da191 100644
--- a/app/Extensions/PaymentGateways/PayPal/web_routes.php
+++ b/app/Extensions/PaymentGateways/PayPal/web_routes.php
@@ -4,10 +4,6 @@
 use App\Extensions\PaymentGateways\PayPal\PayPalExtension;
 
 Route::middleware(['web', 'auth'])->group(function () {
-    Route::get('payment/PayPalPay/{shopProduct}', function (PayPalExtension $payPalExtension) {
-        $payPalExtension->PaypalPay(request());
-    })->name('payment.PayPalPay');
-
     Route::get(
         'payment/PayPalSuccess',
         function () {
diff --git a/app/Extensions/PaymentGateways/Stripe/web_routes.php b/app/Extensions/PaymentGateways/Stripe/web_routes.php
index c5640aba5..742940d8c 100644
--- a/app/Extensions/PaymentGateways/Stripe/web_routes.php
+++ b/app/Extensions/PaymentGateways/Stripe/web_routes.php
@@ -4,10 +4,6 @@
 use App\Extensions\PaymentGateways\Stripe\StripeExtension;
 
 Route::middleware(['web', 'auth'])->group(function () {
-    Route::get('payment/StripePay/{shopProduct}', function (StripeExtension $stripeExtension) {
-        $stripeExtension->StripePay(request());
-    })->name('payment.StripePay');
-
     Route::get(
         'payment/StripeSuccess',
         function () {

From 2ca38e5906d6d559e59d2dc5afc0cb8bf76d546e Mon Sep 17 00:00:00 2001
From: MrWeez <64205495+MrWeez@users.noreply.github.com>
Date: Sat, 10 Jun 2023 18:07:52 +0300
Subject: [PATCH 226/514] Incorrect data output

---
 themes/default/views/home.blade.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/themes/default/views/home.blade.php b/themes/default/views/home.blade.php
index 426550823..f6bd50047 100644
--- a/themes/default/views/home.blade.php
+++ b/themes/default/views/home.blade.php
@@ -249,16 +249,16 @@ class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings
                                     <hr
                                         style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
                                     <table class="table">
-                                        <thead>
+                                    <thead>
                                             <tr>
-                                                @if(in_array($referral_settings->mode, ["comission","both"]))<th>{{ __('Reward per registered user') }}</th> @endif
-                                                @if(in_array($referral_settings->mode, ["sign-up","both"]))<th>{{ __('New user payment commision') }}</th> @endif
+                                                @if(in_array($referral_settings->mode, ["sign-up","both"]))<th>{{ __('Reward per registered user') }}</th> @endif
+                                                @if(in_array($referral_settings->mode, ["commission","both"]))<th>{{ __('New user payment commision') }}</th> @endif
                                             </tr>
                                         </thead>
                                         <tbody>
                                             <tr>
-                                                @if(in_array($referral_settings->mode, ["comission","both"]))<td>{{ $referral_settings->reward }} {{ $general_settings->credits_display_name }}</td> @endif
-                                                @if(in_array($referral_settings->mode, ["sign-up","both"]))<td>{{ $referral_settings->percentage }}%</td> @endif
+                                                @if(in_array($referral_settings->mode, ["sign-up","both"]))<td>{{ $referral_settings->reward }} {{ $general_settings->credits_display_name }}</td> @endif
+                                                @if(in_array($referral_settings->mode, ["commission","both"]))<td>{{ $referral_settings->percentage }}%</td> @endif
                                             </tr>
                                         </tbody>
                                     </table>

From 8fe6ad0d5278a2f9bd948c59347c31413f57158f Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 25 Jun 2023 14:30:03 +0200
Subject: [PATCH 227/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Description=20of?=
 =?UTF-8?q?=20settings?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Settings/ServerSettings.php | 6 +++---
 app/Settings/UserSettings.php   | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/app/Settings/ServerSettings.php b/app/Settings/ServerSettings.php
index 3043066ad..3a82ac3bc 100644
--- a/app/Settings/ServerSettings.php
+++ b/app/Settings/ServerSettings.php
@@ -45,12 +45,12 @@ public static function getOptionInputData()
             'creation_enabled' => [
                 'label' => 'Creation Enabled',
                 'type' => 'boolean',
-                'description' => 'Whether or not users can create servers.',
+                'description' => 'Enable the user server creation.',
             ],
             'enable_upgrade' => [
-                'label' => 'Enable Upgrade',
+                'label' => 'Server Upgrade Enabled',
                 'type' => 'boolean',
-                'description' => 'Whether or not users can upgrade their servers.',
+                'description' => 'Enable the server upgrade feature.',
             ],
         ];
     }
diff --git a/app/Settings/UserSettings.php b/app/Settings/UserSettings.php
index df85053eb..1260a94e1 100644
--- a/app/Settings/UserSettings.php
+++ b/app/Settings/UserSettings.php
@@ -106,14 +106,14 @@ public static function getOptionInputData()
                 'description' => 'The amount of servers a user can create after they verify their email.',
             ],
             'register_ip_check' => [
-                'label' => 'Register IP Check',
+                'label' => 'Register IP Check Enabled',
                 'type' => 'boolean',
                 'description' => 'Check if the IP a user is registering from is already in use.',
             ],
             'creation_enabled' => [
                 'label' => 'Creation Enabled',
                 'type' => 'boolean',
-                'description' => 'Whether or not users can create servers.',
+                'description' => 'Enable the user registration.',
             ],
         ];
     }

From c4b75bf760a524496cc470ffa783d55904562d9c Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Sun, 25 Jun 2023 15:10:47 +0200
Subject: [PATCH 228/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Settings=20descri?=
 =?UTF-8?q?ption?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Settings/UserSettings.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/Settings/UserSettings.php b/app/Settings/UserSettings.php
index 1260a94e1..adc849af3 100644
--- a/app/Settings/UserSettings.php
+++ b/app/Settings/UserSettings.php
@@ -91,9 +91,9 @@ public static function getOptionInputData()
                 'description' => 'The minimum amount of credits a user needs to create a server.',
             ],
             'server_limit_after_irl_purchase' => [
-                'label' => 'Server Limit After IRL Purchase',
+                'label' => 'Server Limit After first purchase',
                 'type' => 'number',
-                'description' => 'The amount of servers a user can create after they purchase a server.',
+                'description' => 'The amount of servers a user can create after they make their first purchase.',
             ],
             'server_limit_after_verify_discord' => [
                 'label' => 'Server Limit After Verify Discord',

From df0b9f57a44c86c0e21badcdbb0529eedc82e95c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 31 Jul 2023 14:57:04 +0200
Subject: [PATCH 229/514] add favicon on preview

---
 storage/app/public/logo.png                     | Bin 0 -> 95961 bytes
 .../views/admin/settings/index.blade.php        |   3 +++
 themes/default/views/layouts/app.blade.php      |   4 ++--
 3 files changed, 5 insertions(+), 2 deletions(-)
 create mode 100644 storage/app/public/logo.png

diff --git a/storage/app/public/logo.png b/storage/app/public/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..1dda9e7c6c5aa69f3b2d512e6a0521aee51f7b3c
GIT binary patch
literal 95961
zcmV)0K+eC3P)<h;3K|Lk000e1NJLTq00EEy004Lh1^@s6+~1^^00004XF*Lt006O$
zeEU(80000WV@Og>004&%004{+008|`004nN004b?008NW002DY000@xb3BE2000U(
zX+uL$P-t&-Z*ypGa3D!TLm+T+Z)Rz1WdHz3$DNjUR8-d%htIutdZEoQ0#b(FyTAa_
zdy`&8VVD_UC<6{NG_fI~0ue<-nj%P0#DLLIBvwSR5EN9f2P6n6F&ITuEN@2Ei>|D^
z_ww@l<E(G(v-i3C?7h!g7XXr{FPE1FO97C|6YzsPoaqsfQFQD8fB_z0fGGe>Rz|vC
zuzLs)$;-`!o*{AqUjza0dRV*yaMRE;fKCVhpQKsoe1Yhg01=zBIT<Vw7l=3|OOP(M
z&x)8Dmn>!&C1$=TK@rP|Ibo3vKKm@PqnO#LJhq6%Ij6Hz*<$V$@wQAMN5qJ)hzm2h
zoGcOF60t^#FqJFfH{#e-4l@G)6iI9sa9D{VHW4w29}?su;^hF~NC{tY+*d5%WDCTX
za!E_i;d2ub1#}&jF5T4HnnCyEWTkKf0>c0%E1Ah>(_PY1)0w;+02c53Su*0<(nUqK
zG_|(0G&D0Z{i;y^b@OjZ+}lNZ8Th$p5Uu}<?XUdO8USF-iE6X+i!H7SfX*!d$ld#5
z(>MTtq^NHl*T1?CO*}7&0ztZsv2j*bmJyf3G7=Z`5B*PvzoD<bXCyxEkMhu6Iq^(k
zihwSz8!Ig(O~|Kbq%&C@y5XOP_#X%Ubsh#moOlkO!xKe>iKdLpOAxi2$L0#SX*@cY
z_n(^h55xYX#km%V()bZjV~l{*bt*u9?FT3d5g^g~#a;iSZ@&02Abxq_DwB(I|L-^b
zXThc7C4-yrInE_0gw7K3GZ**7&k~>k0Z0NWkO#^@9q0f<U<Ry!EpP;Gz#I635D*Dg
z0~SaGseli%Kpxlx3PCa03HE?$PzM@8GiU|JK_@r`&Vx(f8n^*&gZp3<On_%#7Q6-v
z5CmZ%GDLyoAr(jy(ud3-24oMpLB3EB6bZ#b2@nqwLV3_;s2D1Ps-b$Q8TuYN37v<o
zK!ea-XbhT$euv({2uy;huoA2V8^a9P3HE_Q;8kz}yavvN3*a4aCENfXg*)K$@HO~0
zJPJR9=MaDp5gMY37$OYB1@T9ska&cTtVfEF3ZwyPMY@qb<R&tT%ph-37!(CXM;W4Q
zQJ$z!6brQmwH{T1szx0~b)b4tH&J7#S=2`~8Lf!cN86yi&=KeabQZc0U4d>wx1%qj
zZ=)yBuQ3=54Wo^*!gyjLF-e%Um=erBOdIALW)L%unZshS@>qSW9o8Sq#0s#5*edK%
z>{;v(b^`kbN5rY%%y90wC>#%$kE_5P!JWYk;U;klcqzOl-UjcFXXA75rT9jCH~u<)
z0>40zCTJ7v2qA<d!X`o`p_Oov@PP1=NF=Het%-p|E^#BVl6Z`GnK(v#OOhe!kz7d8
zBq3=B=@980=`QIdnM~FqJCdWw0`d-WGx-Af5&4Y-MZ!qJOM)%2L83;YLt;qcxg=gv
zQ_@LtwPdbjh2#mz>yk54cquI@7b&LHdZ`+zlTss6bJ7%PQ)z$cROu4wBhpu-r)01)
zS~6}jY?%U?gEALn#wiFzo#H}aQ8rT=DHkadR18&{>P1bW7E`~Y4p3)hWn`DhhRJ5j
z*2tcg9i<^OEt(fCg;q*CP8+7ZTcWhYX$fb^_9d-LhL+6BEtPYW<H!}swaML<dnZqq
zcau++-zDEE|4;#?pr;V1kfpF+;iAIKQtDFMrL3hzOOG$TrwA+RDF!L7RXnKJuQ;cq
ztmL7Tu2iLTL1{*rrtGMkq+G6iMtNF=qGGSYRVi0FtMZgCOLwBD&@1V^^jTF!RZmr+
zYQ5@!>VlfKTBusSTASKKb%HuWJzl+By+?gkLq)?+BTu76<DMp7lcAZYxmUAKb6!hZ
zD_m=<R;SjKww$(?cCL1d_5&TVj)Tq`od%s-x)@!CZnEw^-5Ywao`qhbUX9*$eOTX8
zpR2!5f6xGJU~RxNXfPNtBpEsxW*W8_jv3L6e2wyrI*pziYZylv?=tQ){%B%hl48<m
za^F<O)Y~-QwA=J|Gd(kwS&i8(bF#U+`3CbY^B2qXmvNTuUv|fWV&P}8)uPAZgQb-v
z-?G(m+DgMJ)~eQOgh6ElFiIGgt<l!b)*Gx(S--Whv=P`GxB1Q1&^Foji0#yJ?d6>1
zjmyXF)a;mc^>(B7bo*HQ1NNg1st!zt28YLv>W*y3CdWx9U8f|cqfXDAO`Q48?auQq
zHZJR2&bcD49<D{M18y>Ip>EY~kKEPV6Wm+eXFV)D)_R=tM0@&p?(!V*Qu1PXHG9o^
zTY0bZ?)4%01p8F`JoeS|<@<K~!G7L;yZs)l&|JY=(diHTz5I9kKMc?gSQGGLASN&%
zuqN<HkZDj}P+u@5I41Z=@aqugkkXL*p*o?$(4H{Ku;{Snu=#M;@UrmH2;+!#5!WIW
zBDs-WQP`-ksHUj7m2NBdtel9ph%SsCUZuS%d)1ZI3ae9ApN^4?VaA+@MaPE69*KR=
z^k+6O=i<ELYU5^EF08$*XKY7yIeVI8$0_4X#@of0#ZM*JCG1X^PIO4DNSxuiaI3j5
zl01{@lID~BlMf|-N(oPCOU0$erk>=<@RE7GY07EYX@lwd>4oW|Yi!o+Su@M`;WuSK
z8LKk71XR(_RKHM1xJ5XYX`fk>`6eqY>qNG6HZQwBM=xi4&Sb88?zd}EYguc1@>KIS
z<&CX#T35dwS|7K*XM_5Nf(;WJJvJWRMA($P>8E^?{IdL4o5MGE7bq2MEEwP7v8AO@
zqL5!WvekBL-8R%V?zVyL=G&{be=K4bT`e{#t|)$A!YaA?jp;X)-+bB;zhj`(vULAW
z%ue3U;av{94wp%n<(7@__S@Z2PA@Mif3+uO&y|X06?J<Fdxd*PD}5`wsx+#0R=uxI
ztiE02T+>#oSi8M;ejj_^(0<4Lt#wLu#dYrva1Y$6_o(k^&}yhSh&h;f@JVA>W8b%o
zZ=0JGnu?n~9O4}sJsfnnx7n(>`H13?(iXTy*fM=I`sj`CT)*pTHEgYKqqP+u1IL8N
zo_-(u{qS+0<2@%BCt82d{Gqm;(q7a7b>wu+b|!X?c13m#p7cK1({0<`{-e>4hfb-U
zsyQuty7Ua;Ou?B?XLHZaol8GAb3Wnxcu!2v{R<HnZuJKC4qWuPc=?k1r3-ydeP=J*
zT|RZi=E}*djH{j3EU$I+TlBa8Wbsq`faO5Pb*t-LH>_`T4=x`(GvqLI{-*2AOSimk
zUAw*F_TX^n@STz9k<mNsJ5zU4?!LH}d2iwV#s}yJMGvJORy<OC)bO+J&uycYqo>DQ
z$NC=!KfXWC8h`dn#xL(D3Z9UkR7|Q&Hcy#Notk!^zVUSB(}`#4&lYA1f0h2V_PNgU
zAAWQEt$#LRcH#y9#i!p(Udq2b^lI6wp1FXzN3T;~FU%Lck$-deE#qz9yYP3D3t8{6
z?<+s(e(3(_^YOu_)K8!O1p}D#{JO;G(*OVf32;bRa{vGf6951U69E94oEQKA^+8EQ
zK~#8Nl>KRsWLcWui5+({H#0YL^F8*+$gIq)%C4=K8g{dXL$p8)nixRBe3E&uw*ibk
zfb?o!34|6v8VI0>=1|}OLyFU4cURSP71>KwE>)G8m3zkGySur&`J&(Nf9!Zz2D5s|
z<8k9&JNK;5dG@p1h2Q%2_pVP*&db@^S?P4I%lY|vuB)r7Tnh^exfT}}i{aH*UoC5E
zYh`!$Ie8{rm*wK(q8uF^mC0mMzWwcQm+kHC((CoggGZ0b!QNhZ`t)g`kTMwb%Y=02
zq+c1Wl*`M@((m_(U*_H~8yjn-)9I6TvGkXE<?#5Zy!-Y$<(KchS58h&l4dfYot^7)
zU26Lbt&N4)^XWz6d}sNKiwouA@}l^*x3pNM)O~%qP_B4)WtXm#JpD8M>UdPToki+7
zz3KD9HHlJwE%$m3E`@hXOG_!=%e)qOeZ~J=3$=-5skc-XNk1Bm$|-#@SYPsVyR>a7
z?{;^0%XB(TJ;tX6)UiNu*R*|!@{J!2hh@w-3|Cgl?#@oe?2>e6q!GU9A6YG@Lq7(<
z&ie)FmS{(ZGL{E}(&N6wSY1%(DL8P#7+SymHUBkbra%1dF;<;Ur<|Qrez~MAow7*&
zvvbm4P3bf3zO?_H(pl<or+?(@_XjD*u}I*y$X}<kP`be7YI<3^bab%1T$Z|>G8itG
zv(wXZJcE<<UkOY4zDS<)^Q&@jbX?Zg*Giv0h#QB8;MLh_>GHcn8Ql)}1Fkt9-KDM|
zO#jXp*XwIwbG-okfdjZkrRDr`3VgsS6H?<6@s6`??^51Ee%prv+?K%aK{-A?F8yA=
zbo-satKY3-Ofl&njix-{51g(qff%^Cd$gA{L&i@WUS6Vn(q2r@(^rGz+XWx4%tL<1
z-f^^T7w6Kc?|Z?W!^u%upnXgHK8B93uP!pq;_j4uhX)5VtxG$5<&tq)B<&ULpjgt0
z!}JSW5&y)Ilutg(u-%v7LJyb^$K$fHx|(s>-`^{jv+<aSceG7B5ONnhi`TZ-u@?`!
z+?S#8!Z_RJ^^J|Pd26d2?jMxrPoDsfPC2C<VR%6wLt{KIQ2z-0c6`H=92+j*g<dJl
zI&7!-aZXz=W_25U4xCKiy(IA!<xmFoiDyf6bg{Eku0g&FU?Oj@?Pq7;LZ_QD<cW*G
z@2s*F(p8+cPRFtK6MUEM0jlltox!_2%eXG|uz1~phKA6~Y1!J`D*xO6-G9yVarw7@
z{%^x4?%sbG+@&aZ-y!%qEmOwhY%*nR;F0jp&p-cyl7;;hbb3Mgz2N1OCr`q|0~h)r
zy@^M*Z*y}qH0^cw-o5Z@X<nRIUtfoI4wKfl%C`-tjI%hp%9uZU_N?rKN3c<7>ae``
z?%SaW^K{nNHy=Cl5@WB|3FA~CGz4gu4U)lGfrP^-B<}R|JPor#8L7g>O7GE7k?r~O
z=gBXyr!XEsUzTAMy&lZM^sDRT%{RXl;j%=7hQpPz^K7U5{AWKaKmOs5%DeBpO~YYU
zq`kP9a;IJhueC{pTmWbWky@fRp8qPc1(&#sObn>PKt$wi?yVf#XZq1H%#KGHDle1I
z@-5f&4QcFuEgz)e9)eqhQSj=T_R1_;8}g2PefnohBapbRs3T}<n}PWP_c4Te1+j>N
zUGf>X#NBj#25sO#^Lv%SeelXF<p|+%1_CG;Y|9iRlIX3c)zt@fJ^Fraef;i`e;{&G
z);jfdh*PLs%M7^ek5}sDvh5;^!shG@LWbEb0BfI>366n%l#niAdJ?n3<XViQtG>Tv
z?8OJ+VxMH(3YaU}D>3&FBvTm0+35sWIKH(1I&9cZq#ZtA0NYb=bO^pE&<;dw#^~ha
z7}%{LgdkY*D&)>-U%wAiCxY(4ATFcipjL$WW&A_zFlGb@vB2GaLmXT(aL3!eEx`cn
zhXn<niIYxb8VXVwWuLoDc#*vJPi7#lScc<pO5aR3fQA%MJ>cb72!9cWRsxHqD%8k#
zsW9LbKj_aS0ul~g$Cb3g_X1()SeX78g)0gRWuBg%!5B_p-Z1t{`Uf+zzdaaZ6-bx0
zUotGKkUoHuc+sV!J+2OMBgSQ!xZ5a&_U{m8a(O)A-4%U>`7)jnn0A3@g_CXR$xwm!
zBF_u7nOcK~3&2bz=-%CXfz_4DhnPUTFsOYK_ZP~FxC!j+xA(xFOPD(bSHhn*hITE5
zcaDkaEF>_Ze)&Zc{ulBf;C=;cFN7t15~svl`HW?l-C(gxv%4UcM)QjQ76IZFun!O7
zIZBC%2(3Nd+qD2w0WBDx#WEZX%iiwO^6dH3^4;%!A0D_C0pK_t?C+QT!#!{ir3TuN
z*RF4@mm}_nhr4ABhA$61K0YZc2-nf_O8BZUQ9%+ftzF@1P>2Z=`Lpj75-Mg<8o)!-
z%GWJRT=kNk4Dxk(weRH3`?PI&*bj}KfNKib&YipW9;+RgY5zd&w+fFSzKx;tHp06S
z$pZat`U-d(hm>THeSiP{{a7GY_UWge25AOpg{Mf;ljBpQ-hfUF%EtO8jkozQGwPS<
zkCD1R`r(huPyh0#<=4Odkn~s`YIv040Bd<%Lg*qxh?vXKRs#}I(s2=hQfnXbl)*JD
zp=lBsElDlLw3gE@HTdz$DESmtmT3?UKHFMD?jVF3oS0=^H4vX=9zkr9G{NCrEzCiX
zd0JKkg!OWl$U-0lnY!;x7v@cyWHMed^krZnA*)r$xDF5?Q;;KLL|U~l@3zVQS)TbM
zOa`}>M_Pr@0>3S5S*AyQGH^PcdKDHC3dGxPkxe0W#dxPK+vr7qD^c?Uq;G=vO6Eaa
z(kN6N3;rn-^1!%Ufbd!&GH0z2%N8FLGG4;hF_kzZR0X324hO?%bO#5AFynrRuE$+G
zJ3prn)HOk6w9cMmZsWKv5GWJMxTc*VKQ&@0X*Gyf7lBI`=4}hpckU9ORt|-w-Qu5(
zXtW{YqYGsL{9J$ms6@!n?Nh7{-;+aTa|sh)<lRsKLYz!>K>bZnDYz6M!c!tW$J!Q-
zr&#*pthk$c(gIoo<4`!#lyZcy2opyz935*((oS$RbU_;|KZ<~NGI$pz9p0zklqU|@
zE^%x{Ymna~o>yToBXHyzJX-(<y1=4qKH91fP%+7<5*NI+9{OT??7PZ|b*yL|Qm0DH
z8cHU>EXUxl?UH8FC+;dM%kT)9-34_Tmo{^W52nu;&F&2zGR-OgDi1IyG;;}el#6r5
zz;QDTQNiEY&{DQMPi3I;Kl>qlm{9nO3)jJ4K_^bui~kriV=EtN%1(``Oxy}O;$63D
z_-Y1Eo_tPwF3KBkd@Dlbvrj(b_oR%*qwwJ)tn4UV@S@#a=p4muL^>I}aPaDOtJSc)
ztQWyNhm}4ZUfON5OmDlqJ4V7)g?s}Za)LEt9eu`Im}u$M@+zPAinYu;6_oHco>kne
zq_e$w>+#jq0ulSscx;q_3InpA6kwcE=+UD`u`V=$G?yG`E3{zq`2P2P@AuFQ87LZS
zL$|lKV&1C#uZ~yKnA^8+BV@MHP&IB{IzRd8UzR`nvwvGY`0%52T!yTflyQM5DkxrP
z2okXMM^MndFnL~hH$i(=3o%U{K($`+!GX7bDIMY>o}Uu#XtbR2?2q}Qy^3k11x+ek
zxE5%W(IQIKGOVk@EKGy`N+>}no^=s~DcLsLOFC0aaOn%_L^IRso@y3}g2OloTS2hO
zIIIG*hgctHXeCFxyRl@VNpTM$T9);bp217m60!M3Ux~us3J@=u!&nW3F$K%g*2Zvj
zmpD$As{n~mBfl^b#<tD0Diacu3^amOc!5_{n9cgiGtdtb>k1fR?OmXFoSdA~HgOFh
zi6D?*nh?L@GFYbqb9s4`@{TpbJ4@y40;`F(jlr#nnyT%AP|tM5kg%(kOk1@+&S<~m
z>Nuo{;+bQAUA5*|4ylc{l19Zv;<8>DI}K0U?Qa`XyVMCjRVJm&%%UkEN|ms;*Ow6g
z*+h$Ap^Rb33gt!8>PEyCs<5Vh3)G$ESX!pSNbS)+RKeb>nk?znq8EG6An=oh6-fst
zXK7Q~Al=a3Fj_9-VqJ1~EMomquDBph_<KmZ2K@Fu1TO}p8!`SD2<ccP;HG#DAR~N6
z;9|p7%dV}cxawuv0rzFfP?>4MD%J=24iO-geyXr@Y=n*DXd6|IVo~!xE>r6vzkO2p
z2G_}Br^QJ_XrHw0S@>Jl3fi-Z;}okWcu78SNB6SyZ+^?0a#!eNjJwrRmDU|!??Shh
zDqpGXHY_O|NZWXkun4X2UL`g>0-mO2aW%aHmj~t7@4p{6+w0$W9qV~eo_zTP3;QH(
z@wa@pkAkh0Am6oIaZv`Z5I950I0x6oCEZc``v>HuJ@mu0wkP9Gn`}#5*yPjdnewb4
z&`l^DbQQ|G^&*M;C-4_79^)f?C@b_sIeUA1;qjeUUVZKH!9D^2WK?@;2@M%U8e-*I
z6$%93D>RJret5WFCUkgnbEEth|KK0SY>&o9u%Y_3zx?vcvVCj2yz%<$G-xB*hXZWm
z|NPJYto-T!?@!AopL~@12K^y`2IvmZf|3&f!JmZL!cDulJ9w3t>LB{8z-z#B(2euA
zmw--EU#E`xP9RI1YAKqHmM0=xOf65O6<xT~_tej`j0m(2^D&(XD>ER@a(Rw+m$W1X
zeiE(d?PZ!+1i&gnhTk$3e@mFAm%y7gGy<Nwv7G-nL3o@1Lt*TA=zdE3NGGvHC{dpG
zSTVdCQtp`Yd$yCZhorOqb;?uoT%c_dmu*vU$SA7i0RdPhmlmJ(h-AhEJ~P~jVBww6
zU0hOQXC%F7gK%~jtE&$oLb=1te}ONkaI!cR6BP=Xy4K0^@-Q%sc8qYb9u<~z()e39
z)domDMbPLP=`2E2Fo@~t3Ap5(%>sf&23vjGG-jqD(w3`?+zf6ICVdGm&{pxndhLsZ
z7JqN2&H?GNFx=n>WjL3hm9dB<Tm+9m;q+T^qCgZzS}4+lnz<V2Vi&D=2+pmoK#T|~
zpswX{8OyAWp>CB6grwsuek_kys1HKERBP;%lf%=pvv*c5#Xs7s;1TzNfAqmC0)#4s
zp~xR*Y#P#s+0T9}C=?t^v{gJ=gWiXxQ$r=K@5Mb87?q9%l}Pf(HATI_G18evoLZ!u
zWuCQWw$OH?43R$XXomtt9I$O+)|Btqh_7B+HqD(Y?s|`4nzc7fk>>~l?lQLs5#zWL
zX73z_p1f&>GY&x;XX|$y#i3Xqlwo^(cX<U5q8@p26%^vIm|F4GIN>RN$OFV5gZa}g
zp1rJJ-ZMQHTX+wiE-oyQu3O&!)vq$%ufOpI{ByDFAM8aT(n652D{!PUm2Jx!f&+RW
zWcH`0$M6E@lNsmUfVOKXphyKil@|&p+tp|@3L$(^fn>c89z4kVqr<}(2nvu`KE%n3
z!q;pweRRG=?}R*3cW`GkTzRZnHw8&Gku0bYQ2<ZnS^{xHf!u<_cnQ5uZh^d*|F6CF
zdbxY=eu&%7iO3?uF_nlsub?s85ad+(<kL^EHvTNvmq=VYB(dw3u!BwGUx=D0<6!{O
zj;fg$EK9(OKoWAB05h1|oW>hB%R(9aSBvKIznU(H#BbZXJk*_6%`|~*VxPUML9~3<
zYdJEYDwHZBHJ@xQ$`gr1rZ92tHbEb_zw^$1dGSt5g350Q-Za)1Lg&4cUSaUmrADIg
zkoh%awQl<(@>rMM4&&ur&-%GmK)MJD#zi;Q8s+%=0>qGrnkK1GvYfb$`0eF<f#WJt
z+qaMt=_Oq6)m4D7;F93f?q$?!Oc96_<9pMIoI+0qAH)VR?8Esf8Z>E^82c`kgdmWK
zs&PqdljD;zIXo&o=RjZvDl2MXC$T<Y<}mlk2?_wktHDjckq9tqi>rusi$e-D8G~)%
zP1@l*gLlWzcS)Nx^oMb_Jzj?34M8+Dj}}wr>wu#!91-LaOUsViZ{evDP~A@AlMK-b
z?&_*JJ2@>=n45#Yh)OK}A3;yzm&}3|rToUgCNPTqeSTwwh(lCT$BCMQLtM5(xJIEM
zO>mAlpB-nJvA7~`hz|;Y5$$*0W05xLzLI|L!enIli;T7RRfM*T<mB12+_fmQSe)bV
zSz%#X8NKmZx7Oo4o9!}B+QW0hUEA+FU8-XkS?GZ)?I&%NDcefkz?igwEqNU)^Ex<D
zaJY*{_FuRg27TMP9L2YdiRpx|cP&)mYdH#f$Io%1P|B}-#_~;TXnax}X^SjutNG0p
z81o!_G7W$2w{4Q0XyKEkeDT?*(f04bL;K?G$)r5nd6v8Flh^9K(IU}hD<ij!6L4m<
zf>jRExR69;%K5-k>4EZXN5fzFr+mZT&4XkaL*le1v<OuSRhSeG&B~F!+i&Z(G~w-n
zpU&!d?eX<O)p9P;(gJvaV5hkZ3XheQp|B&a8<W~WaOH=Zos#$d{Rg?<xqT~yxqo=T
z0QbuGzxUha-rf7r{+>R4UVi-JAD5r}<R`I8?7$EWGXNJCW(*rHmbwgWkh~lO2hk2i
z81bCD$VV`XNaKh!z{N-DJL^clKq>A)hFQG74Sfi)PyYsJkOIgB0#%3*_?>p}n9DMd
z_QFV@`#$jEF7e9L6KA_gFS1K`5eDYrx5(|iF?)$fw}9pQ+q-GaC&8Fb0iyu2+$n=<
zJtE_>t_9MF1gW3A60vRvnU)MfrmzkIYI&&9`K&udrg6oX>f;WRgMjTzgoSOQf0fZn
z!&-%vK)g4rBk#Fx;4D!pKBPIG`&f3CbrEK6&xogv1(?1ZQ{TRBrppVM1>>-^G$g$m
zb!EJkb4q`E1O2h|js6Ou!-K=P9AZ6CtbXv!muamK(X3@BOdWIE7At@_n{j!GhKquf
zk)5?YjLq`w2hS1i;JNLQSy)aR>+~U)`8(7%o#m<YGgV`v$KrM$+|%V`yjD!Lc*Mi2
za=5pLU__%6ZnQ^h=0vxbllzv1W*TPW%ndL(I=hBZI5yxE?G_(wkN5oMIZTSX%r^=M
z`Ng+(<u~uWbTO^Nv=ts&AAS1R1(!C7+t}DB8+YzR5Qv|aw|Vz&x&7!-Ir{9g;FpYT
z`_`>$EsHaz<GH!6{C$Iy#7h%RXaLw)UAA8<ONCMaq6MSCiN!H%uWl>xUm+t+L~$XV
zW0K2qDM$RQ7|WeHjZ?v}?32mq44=6ucR?kFzeSp}pevBZ33JmdFg^+g3aNF?3QZlp
zpTSt=gq*&}_&N>^PZCcMNBC)#wT?x38GWWrDy^S<{BillH@;DBZQr3BEa&jqDOSN6
z@EDV(@;Px@WnUPLS2w5<McqmEgZ;9(y%hoE9CTc$z{qw;m(sOmM40hg3rB(C0;Yjp
z0D{89$#{910>k$T4KG)GT2@?Fytj_daCzl%golI;bgaO_0|YJ!W{k;{ilY&R)zKJP
z5Q1WVr`!T@T)ykdt1iHJ`|Y>OcxAQx;eY<0b03#aKKZ2l=tn;)Km6ej%f}yoB#cAE
z23JlwQK-;p%-(^i?a0rxrxC7$*apulNMnHn2d%|bg5rWujkAmdZ`Mg4Dj^%;`|6j~
zjWEH|>cQ{?zVFQMJ(p$iBoRmk5_Lmli6Zs3J88Ygzf4^ct%RN5JbOj661L=TLPSBK
z(AM9qKnMZN%J7{7Yh5C4<|U}VwF!)j7HHWk488(HH<c5&S{hD_c0qs*%v6_CE-7%x
zD+6$urUK4(>prvJ3Txq;i@b3~kzRnQ=_zE4mq8hyb~LzJ4r3|_@fd<38O((7h8dgK
zNlaZlGEos*ff0fgEZ_yT@Ed%9ushv4S2LMlVbCwNqAa(jE|;e|7PdEo37)!yH5Lk5
zeVbqvkE+I4T^`~<ggqhSM~zv+ndXZZj4^3cBqZ7_mY}ER3!ZT|WCE6QEK9<*eGPB5
z7+j%bEsHRG7jrnbW14FOgv{gQ@FbJs9mYvUb57hjcqoI?^18n0WQ85wEvJ!5RjG=`
zOByZ5JkR391;;YDBaV{A`dwuew<&QWV54FYMh|W%KyJfSB0xy1FmdAh-kWchtyf-&
zo60hz-SO5|l$NP3RMU~yGQ@3vTc#W$jGuVx^GdsDuj3-#UZ7b6$QkUbfQjqYv9X=}
zwjZ{8YkRvq`sOzyJWh|W%xrs@F9L`%6coa%vRMM}y&5jMy38>;Rx#wao=62kmY<80
z;FxW_0B7Y(>I5#ZsGbMPqYf?Sj5uXV^BDsRvOJ#W8FqMrZQ?oO5?rvX%2VVd8C%9u
z3sZdk?9)%n-TU{-t=qQ)qy4=D$|!MPiQifd_Sc0^u0nL)MJ39GOj-n4#Yx$E4s>rt
zVJ6rP`G%GY4JvEUzWgEcE%a4d@Und8QeJuZFoH_B8fTu28|}0|KHH8?cX8>l#F9ba
zY902nKr`r%(~Y&dx;|@6oiugg{R9*1wbx!NZ@u+f@twW<&O32e{rx}q0~$9i|N3A5
ztMVs*@+alpci)|LLd~*j4D=H^IHxYzISh(;L#^L-=qH3I9eILzUgWKW(}>vLWVji$
zR=y@^2Fo9WmaaW}Wq<*K$hS18ZnqN##8ggBD%UD;%BU5p{3fk=)E*?zFay&NZ`!=)
zE}#_>L3YYhi;_US^dqbNXR@9AzLVgFAkHQPsu0mC5MlKND;Q+-K?z|6k|=l-7L0cF
zD~qI**C$Q}Fy`6>A+{uNvMrHr3*>nXfiF?&$JTVdi{>LjWhpQHj~|}AGC=zz;pw_+
zL}QR?(djT0)282Ev%cGB`)~f-X}LtXGQu<-)D=9Ce_RXZ$+~ySHLr^l#53!fp21AO
z59d7SaXC9VDu+j>5e#HR^pJ;l-R@F303Y4=AQN{y6uP=M9ZY}g2DDvaIOMZGh9+3t
z697HK*u@{T=%q@4DonnwmbZ#U6_m!=#)eC^zZ4J#B*FEnTMA7x^Mk?(A=z-fgO%Rr
zx;zJeW|qbk4C!=oNZYzFEb5#hED<iJ(<;cRC|48^>JOfAsa%LVP1E-h4|Gjs**5nG
z2cJpfJLf3064XC?z#{K~mzut~xd|hC@H@X#raL?3;DZms=q_DE^XyqUM+3FY%%v&#
zz?rzcU}7@+%-7B8vR#&`PhD$7yv{^A@Vv23NGpy9kNNGKOWd#g9wV&2@zz@vzxl0u
z%Q+HPM}^)=?|8b8L>?hNF))FR+O!IUg52>rb?LD0Wd-B}qe;I6PQU{bO)LW3w{`rr
zCXAQ9XAGILr2;Si56|K+I7FSkZ;G8`6&j*`-Lln6mS2biT9wMn%S>i}`Q*#;?CG;|
z7Yk2eFdB}sAf#Ft2jGGWEc6&jXI<iU%hB;6mPlP(vbnX6GICIc(3rf_$!__G^@+Qd
zDGdk*_u4(%Macq3v&e(@_Z~dR9JTY)QLJdYdvu&GkoVY6%c|W1@5bZx$Drk`Lo|v6
zVS=-SS{Dii*Vr4BwrYNDW?mul`@jG9%huLr`TVobV}gD6yWc4veDHqxpa0FDmOuT|
zKMgZis#&Ia3}Lw3W$+HRCc6=pS+&8f+M23@%O}qvA~l5w2S=1(o9jLQ-~7G_`OVeR
zaoG-o|68B$Tw-V5<>3<TQ8QRdJ!&H6s{T#$h#ZwUm^Tx`<kNBxX<B*wpFxtyCFBqY
z&k}{iAmK^4&KF5&5{iVQcBP5#pl4MS<;s+G3pk+B;7F&?iiSx!VHUIB(E_P!L|U~+
z_jx#m)+v*4Ma=!zUyu7i>qI~G8p2AAa>zJefT&Zo6oS^|GRV}U9Q)|Rnv|s0XJ4DJ
zwk=h_(tj`VdarN=PCn1#h@uEI%6=6fzHw6X1hx8tu^qx>oePt}U&%0a4Ok#t-92D~
z9+t&1!b1y&nq2%rB`78%i0mZD?)ceO=W)b0@z}a`k4V)1Zj87wa;tEt-MDAG?aH`<
zmshb8tgqsZtDnqn8ZX-_<7oX1fudQ;kld@`JfUo-!|S$0*^H*{Lgem|2|eg<=buYE
zPtUH(`2{pczZYR{!dzUkO%c-6=_S*ZsYVDmUcgjEMaHd#5h1}CxU$Mi+*syr8ZCqf
z6<{J>m}khl#8Zc9AAbM)Wf{CUK{K8_eOjij1QKT8O~XN#_FA4o!t$J7%bW`D#mBf$
z8H?Z?=`UeUDnDMfJ%UcWwJoGGkJh&?vupT_f=uN`Me77XCM>+#MDHTc-rYc}J5wRT
zK!w&_0V;oS%$FDw`H46pJzqz0W!$+!$K3tToUuF|Fv^M`;CH+<ymt(m;wnCv57Cz~
z_nmlP9_cmKfbdF2z{a!6m}#q}ApX^H^|uQ94t;dr$L%|J!iTy`%}Ty5w}=yu6(H^p
zaj}UOLX=I~H0afpY1X4h$o(a@Rs0ML$m<k@^K}X=l`X9oX-t=x<>;D{uN&N0Y~A+N
z33kh{eb%8s>a47+J-)cW<PM`0?k}XM&+hB6QZsrPZv!MurJ@!7;UE6}FsTO*?#EjB
ziy!{D{11QfKOjUt%zJ^-2-&Lv-JtL?EL>|f$hfOC4|9f@IJp{$O^2-8Q11?6ZBM-%
zT;lm>{<c!az|Xv^@h{5v&WqWzS=CTvG-yV^L)SuM9HukynzU7T@KnoSfPC+Bkd5DQ
zS#gEI1HTXnaCHNqMD05IF~sr+fvdIAp?}Up#6<-`NL(^=8V~}EwrQEvDwB{{)#4;H
z%a!<b9VjHUY_u}8JY*If2HN%fGKRRasF%?%mz1wY>G&v=Zhh-p5gw-?h!%yKo4!un
zRxTN~kN#FDq`#CG*Bb95<cJq4qPp-g-n6C>M%C?C;dkkr1X`D;16%-O6}?`cJecIJ
zfj>W;f`{ZqV3<o6)^J2S$-8?<TNr!i8G3_WCevM-eL6+pl2$*i^@_(Lx#JQ+#&v^#
z+$EBR1CDoGWsG?gl#G2NZkt~jftGj^iYbS*GJo?#7+IEO8%Oz;SNlvKAX*7toVPCf
zcYTR=H$8y?+Ain>?fB%>{FV7BjNDMCFIsn{aMVf_wq7z`8Li_gj;RnRFyek9Zp`}?
zFMh9*Zk=-cEuLtRy2?tc!{1}xdo|&)0Zrfg?ca{&akjf#VFp7Njy-Tl#Uk!6Esj@S
zDXS_&FeL?n3Xymxo@f6UX`Ogqg8>$V5E^Lkw&AWq!|N9OW{onmVianN;;3z<FA5M{
zWm^a$7mu8Ps|(~=q-^=isWc<pX_NHsn8Xs{(h3z{q#?)A)qGMk@;SK6pk^#h?|3OJ
z95cNmx|vL<OEsI7N$({b8edWAtr|OcK-o>nXbMWhKj*AcF~N6POrk=XMI4p`9Uuh0
z_~P?e1aH3iM)<96E?2NFDtKsz?^aeuz`J^M(tlvug%%X-E^}8oRVeK-c5$x~FHO|N
zPg8{Q3PNK&drWi-SGXV;Nh96ZJ}21eVBD1ochdy#({AXhzchTDCA>t~!2n|hnE1uH
zlyI6p3KEIVLcBC{-hA`TH1u_}T7|{``=9>P@-P0yzZB2EV)97f-ZiUc@FVChkf8Xx
zq+X<91*F16fxrcD)j}Q67ATUdB1r8>9nd;5m9Q((z8Gx7{D8Ns1sUebcqJ3HnyJ}?
z5M&{Zogq{Wvz1*Dtv=T@B8irOgWw<<C&QP4MkAESsb8X!$!`EtfE%-2;s;a00HVo}
zUbj|Oz3{AHi4dAySwhKsg^=?C64(+*<nK)_Mh0F+&?Q}#W(ouPX1lyDAwGqLZMy*3
z)GXK35E<jimtV$3ATc@KZuryxF7nx@rUAG1gqhh-o=K51ZLe|SgqPNpa1uu5cTA@-
z#jnchifJ^f(b!<9VXi#)`YI6OkIP*l42h@faW?vG>)5;OQ30ssAoIvr+aCK!A516S
z`rBvg_wHr?qD9kIal`So?WQqKVd1eU9koE7odc{GRxd;PL|O^e{4T6$^FrdT?$<sH
z!E(dQ78p}*wkZn@C`fBorr=Q|6Y6tefyb}d4u!a|R@=^g3+u6c_L2I-thp8;cyYyj
z8?iKb-vb`2<X4D{sox3l+b9;RjE924MHITL#^8<?t3t<#RhQj5wwnkA>0<AlcVZ0-
z+bIma^?A6xT~<gxq}=iC+hOqT3)y<>tuX%uEe-HWe0M_pa&NDUNV|>@SwPF}(&h*b
z>!(fyVQ`se<G0bE#c2hI?l0-&)j#-yGDfgH{ph1|L>Wimw3EJW5X~_vq|Nx!mf$Px
z5Xj=OyW3sL8{r_Ym;Zn_3hGd}?KC~3>w=EJIsAyRW1OZ_QW0m_!oc^zBYr#fRhg)~
zH2A^Yj7`~a{G+_(RaHocj>Vlt7_=zurj1%1A0oKNYvc0j!*9eYRS0UC>;gygT9(4O
z?GJIR<kJcd1&oT+D!d>^9f3d6K<!gC5NIyry$z1L^6?_=bOOF@*$9r(E?xTKy^653
ztTN;ACMqu-G|<Na!C=8wU}uf9aS8`b7YD!w`%V{@LdEMJ|Koq0&4ZtP_F4HS|Ky*P
z|K)%AQF;BfZ(?4pC7t;~OajwpKvawraT5D%z+e&rE<_43na0itBzISuKSGFmW$LZG
zSs<<8=f;2J=bi8U-K>QSAeZs;R}COOeG@qD1XcR>mPFesxY};(w3RaIq*_Ii#Lb?C
zpFpOO6&Z;Sp>yeLc9L>~OCh3`b>F3tq`P?jyetAs30|#DZPJx55e5vV1g|BrN_-fE
z<#{Ll9W=IAzx&;|s`?^~+8$*NAgBR%wa^WSTg_0W5UWVUpbXo531Vgbh4-fjjx7`d
zdK7ns^C0#wmIP^JWV$65Et~qCoR{gy#AFx>Duv_<ZP0y^$y6@u)oSumi<Qu1hFW`S
zV3SjE3xRrToAl19=;9in(K!Y(g6cjvo*>8&?AaB}Z^%ExEz@w!9M9?=fIz6nv2r5P
z;5*0Pu~N`P8>3z6pY3G4J<2C%Bz1KgV6oAc2%-oz%IcGbvX^E`j`<BTjo<|B5@*1&
z^i5?VP_|wCIY;9%@dyXXNtWwQIo!W0JBO!*TEYYjmTjF{G1*LK|7<t;tW{y5u+AI@
z<%=I$7U+wyHiooim9%S=v(9fP$DIdLpsbK~KzZxn*KMrdRqpQjSOZqNt92Ktw2XM3
zeEf07N^4j}LZPfTAbp~aJJ7z2U00`;$jG@n?$Uu}bX8Jlf1kFmfYS?Tzfnv{?|fY7
zf_R0Bmbm@7^6WgAWC#ACwV@Rv9x0@@f9tox3_pGQ?VQgvp<K`7@;;?Km*(e+u;y|c
z<s0IQXL>E6aA--yQjs4Kf;Y3VtoQ?F!Dkfy6vewvlpS4_!6C~xvCrhqBl#mlGS;;m
z)0nsMRnv=4=NFzgSl$0gCn8uTmvtCCYt452?c47l1l&0M5L~&+`EK%I^Ge6#@#uyx
zKYaMG(iZvU-SSkeh}D&GCfKb*K5Bau0$TbNU&Uc*$CD&3FbodkNm6mD!Cm~-`mioH
zf@?fPsU+fY1E80ZPzG(MbW7Pt1%Y?d=~MH!lQS0dkN(j=O5^_7Kl^79BLBrd{G$-w
z=bwKbvnoX3z%qc|k>hpP5E8KvE+sMtn)*96&a~ELXpF(D=J)x<d&|#YCipD*67t@(
z()DcM3Es_XU%mTV;_smaIAG>+aGhuqAwYo)ijN_B3kiHGu}jd|7r}4eNjT9Id6o&p
zav+@=Xb6fy@X|$a8v*hNg1BNZvM+-&bSG><Ofr2LvlCjboRVSd%F^W^vrvzb@E-l(
z2j!ZvxB%XkDPxEw0ukRr7;Jsx8)aF7Wh{qWU|v}Qx$Ka_BWvv`yHA`Gqd_hR*@@C<
zwB%K@^jUVEHqf8A89*kNZmub`XqN&-O)>5Z`Y3~8Fe7+kwOEdDCyt6jbd8D2NYBu|
zc>tLm8*q`aP~eFZ61<j(Ou~_MpU7aj3Ye_2qHHyP-(@VkEZ26}SKdji5>>?~iAJRa
ze4|X6O43q7+*!8E@lsfDw;tQMGV}mS;$aN#Ahztq>r3M7N5uh?>tA<n=X~NJcFu#i
z%0-K-o=bFm<UHajOz^avCXZ!Si^$MmCDFG2(6G9CiTC1_uohpu9D{A}K_x;VvW`Gl
zhYmLxr@Jr~wMrEc=Qv`akgg8{Q0sSZkgIaUu`X@XO3-zoU=Uw=;F5yu92~u(O*aCK
z^ub-;sVD`<Nh^No;!-JDMsTTgxEax9!ERD?9z+dSrnI5}LkZHwb&aq&|Mb(cNIj0M
z<>~5@Do4=7`WtVQF*Nh>U;lM^f?%6a-UOITZIgG>sa%Ky(d5Z54AsWv0m$zx*r)=8
zaSv~x4`v`eY^UNW<LG!-{$TC!Fxu^V%QYkgWtz`A?7w$^i_=xmR~%~XFt1jG{Kb35
zm3S4P;G{5QEUjCMT0Uy+AAI;>SzBKzckbRVrzlZ+7o6YIia(Frwq$jc$C!v~;z-=m
z)GH5GX>qzi*HtZFvaIe{=OW#`F1@*@#QZ8#E|~J%F87moI*0R>3V4OTGQj*oqSNmW
zVu8^1bXI0+XOv)0d}|)HXHV6&q4AHA=a2vRk0V6>`9J^X5h{Q5M}LH=eO5lC!!|ZR
zb3g$`?#g_g1-}F#Kn0?H!M3tR0*e&oT^h;V(8>|GhA;@O_MV4&C%Dwu_1kT*4Iw~6
zOP|4>-F?+o+4#Or+|w3->3fkQ2i$R0@$>>|s^7B;BA;adO-q#R$P}W%TN#7tT!-eo
z1fsV0+V{VoNyTd}SDS1B&vh;U9SuzLUSXhHLAO_5grIyi{Z|kk68yCji)sTPiSKm-
ztU+iJ+<-b{0$s*1Op$VW#2rAWS{Uc#aSTk8qfKa=eXxyM8oCQ4{H(O0ekbF#cGPxt
zeYnv~i%G_$0MnHcmxXoOZ?3qnxWcf3l>*nX6>cuQbZm|D<k9Jc%VjU?MH(kYU4<mU
zXP_7X50mQ;dN2*&i^#<DPwlR*o}p;UbfmNdvNtC0Dp4xr?Q<8VZ;`so98;}g@y~iQ
z8B1Rj0=CU`uFT42Tl+^I@k94Roiu0cDc8daty61bz_Wzh2cJ}sY`wzqa_X|l%W`rG
zOo+8DmMPqWN8%RciHl)U_JiNzl`V~h$2hvdPx`wD1NLYe1^SS2(#lY9+$R3cy?a?<
zmkCnxyRbs{kk)M`)kz;~mU4SO^G*h&TP(s%_^V9NM=g-dFQi3b9<j1BS4Uo5u+vXI
zDVJY-5dktpa1Fp8=Sr+wJQ~RS6i_N2-~477X@%1t1%>0XKwS!)Ap*_c*0J&JZ<m!<
zUkyI*V<o@;mwy?hRpD{$IN2uhs6;q!Z4VEFM6;^JB$g~QR$AhY=|y<IOk31}=TU|V
zfR+l(Lv)BB(Gm$CBdvnQJdQ~ChxvWx3e8Z4W9&QUTU3PIKcef*5IpDdo+Z6p-cuH#
z@-um{xMH2)EB#kNa{GgA|Hf;tr44c0g6oGz`|+HJ*IEwyyL%PqxPr@ETGUS3%lM@c
z)2hUnhN8mbomy}|i0}0{iFclqElkeO5&n#Y%A#8`JRmm)1!<tGrN?200^rJ31axNc
zIvR`Sip=W`22P9P3lO6={4y>U1;$T*`qP**zw<jkpv&Fz&fD*noxS}4B18ZTFR!&k
z1bYRf@hxOhlAjKwp$QOy>}AM6=kmAAI?)NHaS+uUy!+lEwom41f}@2xNH5~Odx@+v
zINzC9gb>gUo+XM*sRJexMB(z@h`&9XFH&AarhMbFQiUsP;wf8VQcKtUa~~@qt086r
zKx@Ny3I)`LxU@9$#|ZFseUp@_1tLROK@eP`iK%t=xO7>q!BEy-f4vOv-YqLIjvh=#
zB6P{46XBlRdki8SVzHcoI1*Qv_X>^`^6G{_8wgW$;w%CW;$Btzka5u#nT>7<EfMiU
z!RDl=uDQ74e9z@5s}?NrUYJ}^u45!I3LD4HITwTDF06tuz*@wOWnfB}wf9&8T+W*~
zVX9Bswr7PB1RF)9t5pC2f>-95PCW8NrU-FJr<5;2d-e4_iz`&o#?7&J+!cHozaS^A
zR)KI_c$6_@(<8VbEkuL0ee_P!cVU2TE;Z<_&2`{7Kx;=havjs|$*D^w(H`laLS5Xj
z9P0zIf{VdF`X;>vcW9IC)9(!6!r--Nwfs~l#0gIoaL2f`sdek`J}_6w(4DAdu?hp)
z_|~_|>Z3<x1)Lg#Q(7=R(k!bC5T}*U2X6+vQ@NS$@5h46?tR)LjB>mS&sqk~nYp0D
z_IbG=BQ7Y?4YZ2Dt3LRnRjPF|;P-&`4alp|xdty)Hbw}X2zdKVTbKF0^#^}YHe3k?
zKJS0_S^4?D{Fmi(l%G@5PrNAe1l+l#u5+HXM5@JDwd^P=1nGJ_WL&X84v*`;AYn~5
z;9mJbgam^rf3lA%6bp;)Gf{ZdF_Hs`MtM)1_b80yk2TFbJd8BXeYxybfsjqt;GPWK
zcjj~K4Jn5*ocjnKEDZ8KtN3`Q_V0cty*jsVZ-?fbJ`fKr!e<qHam7u31_gxaq|2Q>
zlu_tHupD4*Xb{*&1&;zF)(miSHI{jNe*)d;#+R3#p3aWbCyj#Je6~xgrZXIl9@}Xf
zETKwFo?v?K{=N9gY?#)C!XrdZI)C3`@b$TU%AkJhn{O}(3*gK_dG8nRMN1Qr>YyM9
zvce?fk&1nGkVKZGVbI!O2c*PVm)b+iW8-yY)b!Ot@oJ%!pMJa)A3-*&*Sv-dAiq;5
z11!Tb&N@xwvwhHAaZ?w4iSV;be)}93%d8#=oy;MApGA;p;9R<~)a*3()yQ=PsdcR}
zVE53lWY+qeo%Gi7P^-_<OVav0VjOfu-6pLoS=O`+5C*!kobS*&*wAJ5hksbcPGUlE
zQv}7)JMWYUV|UEJAMtx1;yZ@8os?C>Ry&k<9Sg_1t?5_LiAY@-h^`KqlmeqqKIdMX
znB9OWIM?9;kEVU_z3)ZHDCDwWfV=&6pUDQAuna463*>Rb+#=78RKqLb)r3nJD|HHE
zVJrOAeuF2xpMo=5C8n3EFU}xt%F*QZyB8jF?pSzCh^tjR8pPE!)y*W!AQKfyB)S@0
z#_hZ2Qj0>xod$%+v?(R<j5)s@zPP=#T7aYL<o%Wgk>&X8s+?SsqrY5s4vx#OKYmi4
zA56*w%R?pT94ku~MFbs!ui`cZa@lth#T6ry4h_%_-F~Kvl0!cMTHK7+TniAgmV~(S
z2>iH%0?~o#m#0t5_IJKhwiuUK6|_-pf8>G}@MnmHBCd>35M9FUiL9nma14Lzx5D((
zF6z9{N~V0rEA+s#-(Jy@(3-VPUgroCg~Af=mMK5XRhWV2OO~(Da12Rz0ZvX~iXGEp
zLG`G2g?fEfcnq;RCeNOg-Cz8oJbVBB^5KtvTt5BvugfXrP06F{FBS;*3&tdFEZQLM
zh-U`zrP6OH8|y<r*(t||<`mLI(!c7)6qkr`{CP!=<n?_N8LlQg8a_6m5g75l#YZzY
zp0s8VUo1~XZxFYf`xBN1^I5J|x9t;0!h_O|dWm-~sr>?YZEkL%+>eva(|KJ*rJ}3l
zV3656cis5w`r1Z${`5JD#X3y?AZdNqgou0jv_KRdS|ffgVRK_MLhta1aYy-gkCrZe
zk4mwgSS|Fiv()Q9Mpt5>Vfc$O=F76Wwi*jWU^JJN%(MZ(xbJ@VyYbHpSP!prfIj>5
zvz&7ktx2E~Gyx?tIBLoZu&h|b;%=M+72=pZw}G<+-y7=S_*BbiakGcYyz@94#My5{
z7y-dL3@x82%qL)s3S;57>FjUXLC{K4<4cM3NByP=2Q_t{C1?pHHO=Z#xcJ*LEiccc
z(?oY-S?%7HC|VNERjfiZV+c&GU16c-;R=^k=P?*u&3}E&626+9LMZF!NjHYrMrf9O
z1c$vl$J9K2`|UD;NEH?n#%y0DfVM1Bw*G9>=}yp}?lA>UaO%Ry${HArb17j=l&^cO
zM|(%qtKWK^Hm$>moLfm5^eLLBW$@c}tI_tkM&OchaaGV}1xHrQ&=#)<3i3y2aM_<M
z7bZUGxMU0>yh22`RwHQpaKV_!L`EZ57C~4%M;K6M&Y6<YLu{J-8ACH!&XjV9&+0F5
zREFJfB=a=ZaYe~alJo4i_`M5{WOvTP6<~|xcRs}aS3Ij0i<oeYBDJ@Nm4~LNyR1K`
z{fly;@Srs}0Chl$zf76C_+|-VSoRm#2M0-iBUrgd;0q_NEY}5AaVvt0SxCY7i7!LO
zX$(%8$M!ENz!?YIpx}|wcNiZ9L6>(+jFa!X+{I_x<pK{a50{vO#DR;;W*swO*adG+
zwNOZ(zA5lXt1EM0nFtMqN1+`1aSadA;;_G&R{=lI-IR#1J4L}+REeS8j)UiH9Uy4-
zz}sgis!zG^Q@;Y_fO7W1;Unr(&6HAgUkNAaO$9}~6_&zLX1})Pk>v~7M<jO+{Ox1%
z_^a^>$H#HtaTaWEc#A(s)0FP!weX$4t<Sqc!#=o|DtHVIHLEB2xg1Y<#!b0IWWSjk
zmTezRp;<TO%WIq(P$Bo@d(GvfrJ}{rc$Vp<U-|TxUwn=cutu7ToDnx1t(0fLS~$66
z{FpdbHJ+ZG)V()Y%lk(j=D1QuE6Xt!vLX_rB1fN)Cf3NTj?SRJ{Mb`Q?UxgVc2?^`
zBDOI~DxYn*6DUd^(|ixD=K0P}4y)5ldiLyjdHd~m09u_x(BEwD>$>TRi~=Fr+ze<<
z+YbO~kk0~{M+m9LwJ<-hExp0#N{|jm4GwM##zzB~mG5uMnlD?;RPB<NVN$iOTBigf
z^Ri!x1BcqbW?5)$_$-12sVG<NBQ6mxiNv}bT<@7c<XOqDP;xn~%NunUDj>|eg0{X4
z@oC175ejid!MGJ%R}gEK@Y+s(JIA5Bp|39)&CQ+USCn}Mv7JJ+6UNPBnZ0}T`!(a)
zgFw%z)4nOZWQ+<jC-GMqdzsG4qel^RYOT68Y}@Fy*UB0e&gwV6S%$PpO?HX+Ys%F<
zAv00qlsU<;bd#*<v*mdgfwluP5P5Znx-?MS$)+#*tY8rSGA0>OgbVq^!5s9)?>0f|
zJI7LZ3InpFFX!Og))*r2a5*CD_%U|QrwA8_s7|1IuLSM9M(|F?M+gJrcPe7E(JkTv
zTgpkii<#`zD)pU;h3;|*Oq_T5t+-92!3o+vJuBxYPTnsdOm#tZ5$57N_=?~Ov!J5j
zuDC;~_Q~J2N#<m*P5w?GF77LENK0`IyzzA9Y!>950>!TfW(-j(rZQ$=f5rIg#ymxX
zpTdkUWg?7&u1o1hym3!O2ZcabUdr&H`?C)}tZfp1XY|?wFSQz6(yR5=+NZ$wjIz)e
z@b$<XC(@U|T?Naf?EqI`BxM01<pGjf$L>2i#lmr}#Yy@rV7UA4yXC3YGx-i_`vKP>
z&j+;afI9cUpF{4tucp+m^%49KmbQmWx>txeiSDuZ8=I?fyX32cFleHJ18{}3U%Z>C
z4-N--_F_D|r))y{$K@|^Gy<C6j(u=vmL>v~%l$vL!3@_b4#v;D&p7k@CR~HJ{sxDd
zfC+pppVvFjcY@nn(6M*jw(@EDseQIj`;4vLqbML0r4pk7pnFq(uz#>0m#_UYkL4>E
z@>vI-Rj9;!Eo;lp(I>nUe#!v%CRtx+d3gl^qC~9BQ>o(Wt5&cRz0C^oy^|;&|NGm&
z{oC2GSc&bry!-BZWtWaQFm_yqe02p;A}wXOcEa+!EIS<&Ry=#zXnot!CDj(STJm0r
z?f}jhh5)xtLI#rGExrYxGeEOJX?aZNfH?>T5y*jCT0)yl8fu5ZDCtd~0ZZFJGTNK-
zamW%uLHf8kc(2boaNrV|%&%Y3xCkWDt2NqpCzD%#edKDAYGqdpimOl<oziFER}cmR
zn1KFcH9CdNC4{C%xL`W+I6txk5_PdUBxpu7?R8&=+S~zV|2~YuFOZ$mezgfTO;^>p
z2SjGCZ(K{pcId*|c<Zf9VD=SEq*d@Kpq3F9%epnF%L&yG4f(xfKF+hKY3kp$ZTiGl
z-gqOv^Fsv33Ap0AeT9ef7pK6*Ie-i5jg>+B990>+?aXI+XYliVv`gBVadZsGXArks
znyKk8bJjd}VtWbgOjyWpbxXK(*7LGFnnKguF%UP!(|jhF_i^(;;KIcN_S~B?^i!hw
z2%3}c3K89CXxrdpuREX|)e3|s#W|<qF%upiufRH;NC(aV)r0A@R8Ed3C?pUl`Nc)C
zQQQMFQm;6ng(hCn0Xtgz;YHuY=q$|OclKQ{e$JV7ftgFf@2YUXoSg%k!mRgx{NpGK
z9vLFT*QGfXml%KXDV7K@)*WVDp)Kwgq;bB(&89N-9^<+QZ*W`}#CsW*N&sW3k`!T2
z9l~3N(*u`WOkrDHw9$p9Oy7Gi^C{Pqqj2&ll*3Oy&1bGJN$;31p>P}%|M_42RoMlH
zcffar#Tj)T)6dU|+vWF(_{?=qobw+lBH~Xj$`L<8?~HTk6xv;JHPYTexn#@~-quGF
zU@EVubZy99H1S%JCP6DJ<KTPJd9}DK7IECThvyLIT{oIMz<ny>=^{#qdrl0N8{W|J
z&FaV@j-&;Uv8sG$*-^}RFMi02rD<JG@@M0NyVNI7_E>gTXu1j9Hn_6Nx`eYG9j&aE
zz32N94?Ia;S^1@HvV7;;{Jl!L2uRwd;$)rjIxP|3>rU$|kDLPmz!m`WzI_`Fl!h5(
zcvh@=BvCv2?r+^!S|u*qbrp!aCf`GVL`$c#9BV0n(D>B)Y=9LuqHoOHyO+$vizxc!
zWMYjcOD@ySUjo$7ep|M8%lFw}+gtEm>YSxZ9@4sCz$U3s=I9C9K(d%?O`6Nl(r)rP
zw8}>{PUC_&lrO<}7dC1<?zpA!8<&V}60t2St{53Tb=eQ+18jt4C62N@TKyPJu`5wY
zKtKFp*@vLc5Z(%jxEmP64#?wV<u#_hlkN*@50rKCi(h2-u)^b%_FQmze1k-`#MtVN
zu)b9oP26d;&53+n9!|K1K@qQZy8Qj`moA9dq0T^-`Xk6FdrI5RWkSZ&7e6{AW6-BQ
zz=|^LxL*IGkK$sw6!|IJ6*Fp?-W4R#9;r($&3jt`CGsjfn#)R|g(R=cipzESMxC8q
zU<I$1)wN;S+4o~-le(I$r)7!tz<ALqz#L>kNYr_ZF7Fi*u2P{{FdlFZO)Vc*L;3Oh
z=~IM~pHy|s{GNyY;6?D;V?$i}y-XQ?4bIhamuFae=UPh@&m+i)mx=hLLnmX;DOY?G
zC&U?7Y-z!YQ!)wL<!^~u#uqoJ@451h-&(O+cnW^!rd&N0YlQK0Y3v3TqATp4{^&=U
z`_f{QhP6P2rDK7nSPGVe!o~eR;${vb)S`4;7*_?3YyGqTgKOyA3H0u!!gFv`W++^|
zvc#9WIP5+UHyJK-DM)mADL~F({u4I<g4_Gx#Uc1}21B|a{TY3^q&>T|<td8K4(-~f
z&Cg+4&%moM`Td0S{yw7br(9F=oO6lup-+)PxMeUa?id_{RfLDD;hsFh3MY*)kspXt
zDhp&xocR<e3UT*FgtzcEG|c-tvX!wLRJ@uHkk+kR-XLvj1q*lcJI8j8;$Xbxm^S<c
zc-czZ<U8A3Ycx$&;(ceo8t;<FXhpa|Fw3)no8xD>D*FcSwppQ~_aPPoX?Av=GxS*K
z;G6RzOTDT%o7TQtpTfwyZZ!L)5Q>L}@?GFy+buIVIvQeuP?$}&<9@4HLUS3Sf<#8D
z@KAHK@tQ%NccrCb9w$vd{`lh@&t5@FaI%}f#*nLp^FoT-053yLQ-6~r!E$MR%HY9Y
zwS#k^rmq6SGJR{D&+WZs=h-;YwGzx@ar!;wDVl0(l1l2<1}%<Ob}K*HX37DPcy7df
zW5SZgxeF25c?SoKhJ-L>BKEi;nq@oaO^7&;Ai}vfL*MTySH7V@e9j<}xsu+44lx^J
z33L%4R}f`fNHA;}{pl}%S&lyZFpOi$z@O5Vtd%G4HNUlhv}l~4a0QMN_RdW>8S0rw
zGN!DUF)eu&R$50FXo^mxp2Gl6ApR2s)Cu(*AgoTl_#)cqDeXK#$jRJwsd?;$8tN&?
zzDGNCTb)Z(v_;p08^E+iVr@`Y;6-TTB?EOpgui2Lye<GDAjpb4VHPC6fHAMFt;2-t
zY7%kK_Z}D*+!5wvQgLvc+%(mJc=Acpi@Ma)W3y$z6PGRa`el6$p)_781Io~iR`XT{
zr8Uwce^!1CmLvF%4$$fWZ|42x+H7BBR{36tN*2u#e=H}KspUbS`GyGTD}E|e8om+i
zyJhlA7nXf+^^|)!vR_Ey!I*A3U&gpT``f=Q`!H&i2Hg(ggU5plV+Hm#`38?3l>=zk
zd9n%go$u*W-!Wq-gAd-3H}e$Y0PmMyeKnKa=PD75Uz7pbq5yHMWH8Q?Iae1~CUq`>
z!wL{-N;tZ2<Aiwe;1c}06z2TirM^Az-qlrF8~c>M0}g3%?D2d+-XqGGf<rnS#TMZ!
zlhi5_PWDaJu_+lccU^jJj+`9qmxGD8K}z9@;2=9HE3hR`+w%ci;8x>&ZwPPU?zlK6
zji1SA{heg|jxh0^Kgn}OAEQ8PSupmgn_xMuJoDwwWj!^`tjyW_#xtzbXRjPd0!*AR
zSD`nZE+}11@@$V_*Fuqp>x%N(_Gtx+>ywis$~XegssNN;Y`Y4vE_U(8Hmr`<@-8l0
z(pk1J7xtaeXytJ`qTMrvJTy_W#>-4zS{`izU5V<aYu7dycmV{lzWdI*<>2Tb8kgmS
z#Zq`B{7MWhSf25Q3J9M~EAtl>1BZkR3_r}>@)%M!cjH5(lw+`-`MO$2{Os9a9)kiz
z0#;MCc!$h&;3B$aY+V4LMo`;Q%b-t5Yib^NFQLnL)Di`(XVRo^lw(Mn%+J;O<8w=+
z)@GbLY(vQ8mmzz+2ofd(6<@P`HLY<lb2kshmkomSAZ&fh6Mftw42UhW-h<GO(MI9|
z;<AmJp-!4hXs-Nn*{^P@1?txV((<vLix8e}3r}Lz<#CF|>CWUc5tp`Wnp?KZCuLM>
zq6&*>r{r_4#l!FXY^i3o0>o7_C!{;3KbE2YI=hEyOPDTg&OC@PqQ4TTurp-bbteY$
z{1Gqg<1U3z9oF7Z#D;Nz(|)tttU+|jtjYp}M!k-n8kTb+)05-kKAW|*F@mF0c3_yE
z1bt_76_EB(mX^`BWf*FZGIj7cdqAA$>X-ff!z_=asFa;CMnI{A+49uw*wJs@Xjd2D
zjeVtYT^{4gRG`@(uHY;04Y54PYn;LhnMIuGA#~!ilN%<SW!*6D+i$&9bPFjM)KX>C
zerv=PJZHk5F_Xz&$s`c+d*F+6Q8I98`vBpwi*n$%$`$Sk8kc*!c~HERQ9If0oZKnp
z=IfEPEpvU8>%5<HcjDGmrILIK5GThKK#sXq!vzd#YT5Mt5Jq<bJ_I+oobT8LUv{W>
zm;72BzB{Il32<@WhpsDeF7q~&qapwmhnD0q(v1)lpJa$}@9geH3Cl_=2a(IuNoFjF
zu|hDYnNU9e7|NMdVm(F>nov&~e{;7E<1<D)`_48ftQ)V1#UtGFE7j#{>2G)%&!%bh
zrEYHGa0~Jc^GVNI8d?Zh#yjvxc$6686&5mjd4a;k0}zd08Lp78u1?g=?swUB|JqKk
zhO1g36Y&RO(_QSBH7xv#Ym5oTM%ekWHsR1&8I2!TCSGC=X<fK>-R>wfY@lm@(=i%u
z+{1^j<jYweGi(L#y#4buPBYDPA)pxm+C9vY%Xi*Q@4bckuD-VuwTvnp!dPbIwBYYH
zIHo0Wo=t0={>pt8?*O)E)8^f^%Q6)p3?fC;cJYwnT$3#$;@La`*Zh>D&`AxX_nmD~
z>O0ZoN9sjVEe7AIMW_9<0ZRMKBjWJew#R(~p(sF{Gl28dc?Jg&;Vlz34U~{&kZ1hX
zoh4(}8gbQ1?_1w0s10!uoQXIf)j9QeE{=@eHd%jGSkYFsSgobIfAmMCOBtu+a|xzQ
z&ixwtr?nuQUpXWG5KH55X4$AUUUMC4aY)p(+cU&s*3$L~!p%uh-62{q&wll*EVDe~
zz55{4KouY|wD_-Sr*IJ)Y@=iI6?h51z`O?0wJ9b+;=Zd-fFm0IXzUK%I+k!1n3m%J
zPU&v)*lK>e6WBR653Td-ZGD(}jvuGJ;`GiA0{85)Y;GfD7ilAeqh{S*gpmPH@m%3y
zd(_e-G~Hb}nnk4pJ3+TeeChOC=B0%rF8S;{Nu9$eb)f>nLmz$ciy#ve$HZ>&L>Tlu
zQ;RxXj@+~F;HG7GY{@!f>d6J`SfNK)gAoA0|BAY_{5&rz!kRMA#979@hee=}-v__0
zVK!IvJp$e_;?g=)%XjWWnm>gP=$`D)gvT;Uq|AF4i`TglY3dA|aXe%`&XrtXP3Xev
zX&uu>E!CZO-pPIrwPWWn7HNl8$3EpNSoVRh0_1?UIB9+a+)n7HE-QDQL$JZ?%$pH!
zkT&8LX8b$xepE{&3Wo6Gu1ixvX}n`ndCPSKk?;)<0Z)<^_+|qtY3r9IMI~*&DnRV3
zIGOPhPt9pLmhF2&%H((4Xr?2C2L&6+mU<|YOJ0~~;>=%pU#;J}!MM=Ftd7KUsl<EC
zyB?wK?OPETu^dRR;B3}{Ld1N2>nNX)zFsVM@7*rDJI~AB-hSTOj;yQ#W?CS2_~iH`
z@zPJ`ODJQxznqPtp03at4p(!Oi3Pa&$|byKrx%z!Fv010+1=mGy5QC+8+YgK?XtOb
zt2}?YU!FestUP`8#jKMOeFZ}6xX%VVZbK}m36J*7jq8OlF>jsN0bu$B93sl`81?$D
zUWSxo3VyeH;w^L*_mz16^Id`)vLIlju`9(~hpp8ilGrxu)wPgA@Aze%_NHnn4sMNa
z6X~8?wF^OJ;4Oo9mZKJ}AkkGNbFgg=e2|A{3Bcc(ROZ?Fip&Fe$#Cr>c^5zkm0Xuz
zI{z`i>R5XCFe_&k89#Rf@BZaqmP43EChlYkAXg(aSHvhhY^zIaH@^GbwEy6*|GJz&
z)M}bx7L>EE8v`wN|J`@X9>T>X!21XfH9-Z4nxIQ7J?T?npm0#r4Wpu83NZyk|Ni|D
zrJGGJfx#j1=8e_D`)HCp3n#T#iMzqSxd<Dvsns$-73Tc*9&J(v%s4u^?KkxuceVc<
zU&8wcba2@WnHOOc^&|Vi9aP_P2l#pRR)6HDWnrL)SW?qT*}@`Gt3$`7Eiw$<K@-~M
z6vA?>7uib>0d{qP(xaan!K9$*4G=Q4D`zml_^&R`a~7Br@_s04Ku+hL+&xY~Wk6mD
z-aaba?R!(C>;qsetF%wc$PH@lwb2dcu@)Yf=e`Rqf+K`|#+>&uOd0Y8<t*rq_AU-E
zCYRvAj;=@A<f<Cexj9cQf1mN!O4I_;I&}U^_vaFDx~2>TiEwu_s*58WU-8#Qdi2dQ
z0w&)`C*Rs{|8`mb!4H(2Wgo%z{QdW%ba*IWE}1%IUD9_IibLWQ6epCW`_;4xJrxaC
z5XuK)@$fE+1(*4<Nm2ZPHl1s*oi1icTH4aNJjc4JJJqGncn8QU{}C^Qr35QhktH}6
ziy?6YetVaaf{)yzt^110^1|!P$8TxQdi*W!diS%qv8V}AAPK_Fe3jqS(B93*TbDsv
zNj-#$AJ7~9J2^Tn8*AI}pbhGxZtzaw5ne>yS}2b5_SQDau8I=xuC-LwvqN3w%Xwhi
zr)!KX@kX7UxoQpNs52<bgApBto+#6mU&9f?W;7f>wlSJKuD&`xLYqPhbAbH5d87{w
z^)4aWpu2bPm0L)==g)V_yYKugLPZnOjy1+^$6Mp8kf?yLvp&zK^SQk@#Jpr!j5F4x
z^J!XML-KPsuEiSH2Dx2HXWZ;+X_U^^=hDu!m%r4>rD>;y60KtvSK~!92ppmh0#S|(
zi9(}^TTT$1#3CRWOvFPH2iZhUk=y(tTkD6gihvQ;JexPGVfd{J!O1<Xjx3>+Ny98e
z&;>LH^BuwX-7u&-0+qTPX|0e>*MqC8)QsJmaSNhedF{2hr1W(kbGf?16*4+2)l3gT
zILG!_p+ej_OzNEcYO7bY$@jX*WH$PGWjNj?UJ2ed=<ZrvMJcgA#CwuxPEe(9ais_k
z%2sehGn~O8t^w}C)Mw)whFoWIv;Gd;cu+7n3Gew>3id{5!Z22#?cz`O*ir{=40=33
z^KvhfN|Sp!+^BkTg!Vn5zqEY=0WzdK$4Zp+phXIRz|KN!(N>8MZA`C92gdFMyxME#
zI8aQg^+Y=<!+2M-Ob(7Rk)NI92p{*)=!f=r68DpUK<TeSBsfVKwW6y`nrj`a1n9zQ
zi#Ajqv{XHsMt^rKT5*Q_S`u2bE)QQpc!*EBwCtlRo%Ap`mb$h2@PG&o>QQNNKFmpQ
z$5ZQ5*Op3+f@%kWAim24-QOfWI*;ZObZN%<yN&OCuP!IY%1{7gE)1M-dF~PQ>r%69
zl?&Uc6{K5JMMRuY$q=8i@su<&FZ(5Y`oL3bq^_KU24QGw#p0@rQ2Nr^^ynL@`Yisc
z>MjoMP*&(vm}Zc`5Xv$x{DCsuD->mrv<7)bgbVK@@OfuG>uZeNcQy4aklr$U&#MG)
z)?=LI8N!$HRLe+tEdxPZ2w$7kZ;&^O?=pQ?VBNcaH>ZlL2pe=A*Mk!k5cLp6^ZWcu
ztVdm1mUVFGmk&|=u+WFg1L}f4$unMEDM#XKx1W`S9s}bMCr-+*tSnanV&`2SYyul%
z;hNb8NBe0+Tf&<_yWD~9DUct0_<s5IuYV2kK?LM!oif;2e|t3n(&FrZp{4iMc9~b;
zB$|8>&m4ebrTA>R#MCkxKwG(n`Da6G*-gA<kf#X{zfXZcCi(?4mkBte$&xm{(0m-U
z6q9rnL7dRCuMULcm$FEae85jQ`o89`W^zT|iYPpheug-{r){=d2B@DGAjjS0ikM@x
zM_o);FbtPyI<e`p-+cBIM9Rt~+d&@v*UoD!X??&9B<%G!-waWnzz9T?#&E7cjD1}S
zGJ48&)0T573XU7UHRGt(m&s6t3;EP?U6LykcVZP}iW{%Zk)$2ulUeESZrW`&rOo;)
z41{HySa!nS6-Uhy@qNZmp!3d&NhqEHfSC+>SZ=3Oi&g~O+KQkEb1tnEzw>edgK>PP
z;FkL|wl-Y3ghdB|WW}ID<nR<z-~CNPF8YCX=9lCaB4p6ej$po%lUQ?}-*q(=AHhwS
z7?ewY9CH;67zV=5ah3tu^i|rRP<1ZFzO7*4Y_4yX`&g6GU-t3PcKhnwNN|U|={rIu
zFcF8u3$C2T>)0@UE~8aBP+4&PqoYzm845a=(kejIz(4=huVS5OH9lvoW#kd)mP!7s
zmJ@EYUtyt@;kP$j2C6dRJe@13a-soo;+*ZX?OGtNz;Xkj<1j(s?ELNDmIJI+al*Yo
zae0znmzDTpT?!Dma8*F4R|`r(;&bLX=%X~Gbs}7sf-;oB;Cry<FjnAIIfn40ABBg<
z%|L8r)g|4;dv03rM_5w6c&8f+c}yUW@O7+sALdS4EnDHA^!&E&c4_^X)+;niaNeWk
zHJ%sAXM3uP-YDuKt?$zwg7@I~ETp{l-b@7F8sF{_9(ki&yb7aV>@JkeO?df0SFT_C
z>_=!Qw8cRMz99nEwqQ}X0&{<VFRKl^C|B#yg#6Hh8wZr*w?bmgL2E9oT1If_sff2`
zxIBLB<oV|2HpSM4x=vny_6g?vDdx5eM#k5K#Dj+qvWn+ZwB4s5gzhg1rUArzfIfRR
zuVFskyH|iowO<t=KAWS0hhMq3G`6y7Wvxy_ZGFABxG?;=_pSVv)`?av4L>`In7bMH
zmWM9S5NW0j8qb}QEIitmh?u_FPk)ms>$!=mdC|y|C%L#PQ_=6O+3jFv{WUKaW=sA2
zElR3s=Da6}PwPQ9#W6%L!*HI&dSwnCT;~pRCpbfVFc2*p<D8JE;nAohL>X&@59wTD
ztCgY)VFAISuXzuKp=%*l2lcz$Q`dsbKg%b%6dInhwLrV_6+oC((|8?k>y}xGM_%#E
zQoobBGOV~p=$G1MtkM}=8-b+%l#yfLX`5C^CZTy3-!r%%oMbXCe_dV~gxLuXVHy_#
zmt`4@k8d8$D)2dlT`pdh&9#l-z_q6NbdpK*ljHL+*!5wrEcM07iaSn#JJ;gJ&paz=
zxLm&;d2)(CMAHq7Nyo4{!f{3PJew=Ha+Mwbt7v=*>n>%uv2Y!@z51<hm4|P<kt1I`
zEYPtP&%`(T5`0RZ!5o;N?zAop!*V5TnOSy<)5i^6hWz&2GljHgPxVm_Jw#I%qi#oi
z=8l>35DIhWMpQOvP~OSlwcup#3J;Y>$4Fshyh>*FZkUE=R}Shf)J3}f=uzf9v}#Ym
zm!r==&-{rBhYFUi%qS4RH**ry+YUn%PpngccShQ{o9x@H?@>C4bIMX2m;ys-&oOpC
z(<yM*A`uSBPrDVmqk*SrP%e2rwIE|@x#EbwYy;08k0UNYnxRj3kwZaIAR;ihnlcmS
z&E4@fUM0_VNaw;RWzVkg2iwK}F7b|n;V=6|u$+`dy2eX<<L~y~(0+SQS_;iEQ4vg(
z!KLe!9Ayow+J!ytG}r34&6XqMmtSi=Id6A<b_w3CLN6EDb2A#Q1!j)9pUibkoFne}
zc?Ia?)z@B2`<)B4Ii2Ov^5gaOF<Q`C@p$UZtxb^S6qEK4e3EI_`4N#>B(h?y6{Xoz
z%u)SpcG$~cBTegX?~Uoc{5+q>8_{zi;7eLBS^+W67(Z77hQZ%0otGts*k+-nyLoSZ
zfuC3q4~@{E_Ue1{I<P?);;o&Z^_}_bha<;enXcu@!1K<;B9QUAIk+)6BIHbS0r7Nw
z^%;~7$Rq;0k<IU6I7up#F`W$5<3L<t;RLRXU*b6d8N7>_)~65|z4A(!&hvlw@5&iS
z;PPHgeeaI)34~0=VE__*HuVvw4|@kCV2?bSx-R$CeWfqliOX~9U2+nYxG$ZY1!-JV
zp%77Hbn?^9gWE7bt*cDP+HaVaxT1^1XYaa9oM2beJ%Wii!K+Q%@Q430c1{edHOU}6
z%}C+l0tMsTeVx5E#JkE$==IUK&LQyraJeEp<>e@H%5jW?bKLW7Yha;^s7J&(%8~FM
zt&Ss97CSQQ4nhWjh$eQpe^iz+-}{csq82t6<L*2kMP{+Y`5A4ce`g2~g_lcz7iN1?
z+(+VA_E)re5E!)9-y2voXNM3aZS`ba$5`cM2gdFMrfHmmiedr`#48mCgSh9|>+Yht
zWdPo|k|yV?**DS&9~WcDbY;Gq5Iiq3Ho6;C1hT1=_Uf8+9A&!VMuZ7vISvYDkH1ma
zI=^OFDhH0UT5P-$c9eQtU8NG_^4(i+y%k(^!G(fDM&u#`g@kpgcxZWKB^G&{TM1tB
zPT}G4?+SnOrB2$a;PJQP=loEgvA+O*_E&glr%x&C3ivCWrN7pP0b`xHE5-<!D;e-k
z_hZG4O0U404Cb*d!reVV7nfR|y5NBcd{CTH2!-ZJ>phDr$Yc9t&erW%#Bw5DTDA^p
zRhm_q6w|HC(0HQh66dq|xTFjF7kVe1zvu6{F62XYstUU4*+tylTHE8*H3Ykp?E7K*
z(xe_2%MNW~QM;*C%V-r`_b4ile!m8Hr{JvLRo9i}r2E;~G)sT8Zw*-FtSwJ4Ute2)
z?BuzoiN`hgk(QH_LozLaBy|tSO=G!46z58ukkNf*=j@O`@a|=3&-0gQ43^__`>hMf
z_ugw%m9#`97}v^gd5p}HiCP??y*I64{&#!!?q%FENau<i2R`ree{F$jqP07?4F<Dv
zs*s|Lq^{*hz!2~GN}80Zhmv$xL{s8-Z3j8IyMA9n_n3uzubInw)jGZ6V`Z?_WUbA$
z_Bqj3_!&nU3QU=<no{FCLG#nC5Nilzk$IdWG-OJiS)^-2CL^I`d8bT+{JIp}DgF!%
z_&{Moel^nr%F2g(AP$LN_f;nOc~*<`oFdDU$)ugM$v%aUsDJE)EqT;hWd>RwmL;=L
z)728G0D*A0w75LASopY;S)s87zP<6?@0L4QS+-F(iVVQ-NsmToM)VOtRl-24a?L-3
z5f}(7<AZa+Q2dpXIFY?F9EE8+ioHIthY)4Xx~KMbj%ND@utE?ZadV>WS&E<6JtP0=
z<UA&R=3IbB7lINYuBk|$ymjRh&D1y0(k1Vj0tF&JpPYplZI_H%H>BhA082!dqfA=d
ziWW;6`yufMCy1vxnFDbZmr905&1k8fGG1b`R>1h~-3acd2q#?_x{5M(yw~!Rp*JQi
z19zOPGxKc3%eck!&;V_<kGdpP62v(zLSZkis$_cPjaG=(knf`LbGJU-V!E*00ITv~
zoGwrI7Mu$|(t5s|yXbqAp<-mc3|{srxj8Y1E)o~3#Qe4oMt@GL6=p|_z5S>j0GK-c
z*&d>(@XkMrbL>>;glGCnS-KJ}PoPSxGGNn7!&%}FeTttdb<(5wBt2`5WQ=Hg#)#+q
zwm!?`GWgE6_{;iQXo_yLIvQ^=)_2l_zoqe(Ch3Xu*)eh@slvf$an!W#gK`1K>e_l3
zy$gggwzK@UVR;!?F8eh@aD9Idyn^R2hQI#s{orlp1S!w?@aoEUo_v$I5{t(Dg1+nA
zx^?@p6X-VH9qA{>M_KA+4!a`Kcv-o^LT%7Sxv|jAgDtd9wMGV@v)}X2?R^W4=^E<$
zT8_c!dJ#t%HLj*@_Y4xx_19N}rL=a<-xIj&B5{>XHh6(74jL`E88FkTv8sVojj(2I
z18-XuKKVslGzG4_v(H8|2x^cLf8v2<c6u@rGD_RfkVV&$_i9Gh34YV+WA+LoB)vhH
zrVlbt;;cJvD;PvhhlP=tXY<?N&RxHCgosR=zDZ~i9+V|<M>FJELE_m%XWV5tu9T6{
zC`|mVCfT$?HBv`KCMDBzGo%OTsR7I6J)}=!*0mL_m3%S^1(w>HkdnBCt$ouS<Atge
zI0zpPZ@cs0L0klf2uSbdb!=QR>)~%Q8ZG5Eho?)H2;ee<lk*b%DV#DWXqH+HYa6Rs
zk|^8<PJmA@s8{#YY1!XDMmY5mAcN9T`JKT&ljSqZQY%CYMW$nY9$AvF6H>*Z^Mcf+
zrJ?xuNO#NkQ?fJ%A?n#v)v}QIy=4CPT-d<f{S|8YVLr6apamj)q#0dj&J}qVCgO<<
zK$nAa1|CDB=Ktl)W#xEh<0fMv0|vP=F2djP)tDOtQ?QBu))N827$~G{kFKg{*3>CX
zY<Ir#K^jl<jfP6O=6AWTf+{B!Q?3?hmpGYeEDkPd&(jICI^yP{4uzkS@wPEa$ktZA
zXQRTQ;_BVGH}PKPE`L8$kdR-x@zOF_gr-L;&=2o2?Dp04X3*qdT;vJjuryrvgF&~H
zBi&L=RXDf{7X_ubmial-3xh`U;Vr~_uY88*Sw3s>s=}i(W`pnAJ+KB=hQ=>>k>C8t
z@9@g}v@Y_foOtk}b<l3xS_Q>bmgkx-Un!)A;^_MNMmz}O%AGrRQ%^ok3#{bvw{G7m
zAAR&O{G+a3Oq+mzcnjm=Z<q7xzS8>8Lg{R7ZawzH>^9!XL{}qCr!X84Q4LduW8pSZ
z6Ud`Wv{pP5%fXB^P6q_hj9>}=ZkKT_O-uK3sM+eEnI_Vdj=!8QKqPLy%nH?dYr%59
zdan;Hj|@e+ce$kii-6#dnrd3p2rw=Swmyg7xD?7IBNZW%mftaPXU`6<unB^hmwegd
zQFDaYU27et$z3fd!h@@wuq!(GaVd}5)=eOx#{?yhMCK%=cZHR8xB@5e;1XKR|E;EW
z^!#}yLgU9KZJ0jkWFlG>aV2o6sX9*)zcjyPIudL41(5!R>2s%35h4v93JEnuHz%gw
zBx%ctZL|5bT$;wKCTkiAQRENt`&+nkSKHpE|9;2fbFAH`;9UIkwwpG|G=^9Rc2?%>
zj`0(fA0j-W#B<FY1D##YNlAWfZbhYFH1ssn9*o&}1r-2@5P{;v_|EQrtkbpiQS!yj
zVLK5X!d4jS>J_#*l@}0rGVg*D@miANqwT{&akZ5lI>)kEjVrBF4i2yqdGC0KSqmFr
z?A)Ssc7U)Hm#j-THyVh$ihDi|1zem*(!J+V`56!1tEroR2j(EWq5x2g!b7*A3Ph9u
z>T_P9;dyY6`n6<KL=<8!6!04}@&MhR!E@4jmr0AK?k5s=6(YuY&Klqd^LG`OC+cc(
z+6EVA*bbj<o9<ED<jTA(C&t2j`uXSO36`xcHxJ)*W2blD1vi0xKK$eu01KD*dp@G8
z*(^&sRB-u;gAN0sCq-ClwTfZlV_O6x-HXHG-UZ_)Jy<k9Lq|SjjJz}c!pXFO16P>q
z42GsnJzUbeNMRa7gPBEIhV*KB$Jey&YUvH8X}qId)@Mk%^ka#e>1KSEcjCOb^7QGm
za`*ndoZRbiJt}=F74}1(p|!1RS8GJrdL)YFIyGS*+W2Zs3NsZX-MwxYKR!7^;KGaU
z-+%D<-dzvfsz(JoSRU;wvr^NO$ysQde0lTDH}hc=k1weJsSLAqHVll=ey3A*b}sn4
z0juUQ&T`uOI=GhA$~3(RE!})c%Dq-M8z_JK&gWTNCYShG>!=m9yHYtO^wfzcA{cO)
zjkVYUfhM4VbC5=6=RH-LN{pQS3Q~~X7=^JynQ;vqEkgqIeH%Qr78!<v6fOJy{qpb|
z-^iN&Rei~?yiy)wJt%07AUffnCX!zhyJ>;j<naVlm-yPz2qy9`ySY$zg2W1O#w;g~
zT3#3l&-%aJlOYkhG+4&mh+9D;qmlVUQ>AQu=W4HUJCWDrpeh<+rs50r95^9QIUf1$
z*hM2Itp_;9Z%&+uY+LM$7L;0!mYKxihOaDZr3^P_-t|OT-hKJeN9nUnN5-VJ<ms@Z
zp<gDv3L{X@R4X<(;TM7A#cwSO$7TVBa)p3UkoetxyJ8ymYG_>y`@<m1{@x*0L$7SC
z@f${OW-X6;(lqd*8j04Ozs`NQT1Ogkt-k}WuiKy^<YqMQe!*}6@%g>$!^3JRIp?Ed
zp;oIf(0Yuv&v?t2Y+x7{{Zp~fBGBC>oMiHDAk0@Sfsu1rP4RQG+Odn9iu_uSSq(=$
z!YepH-O_@VO$fv`SU$g-RxLbjkNZsQbUstd<@agsyzxf44L{gG%XKa%jGH!DmTf$t
zJ?#?$;+k`ETC^_4&@Fn*SneS-4!vl1+Dp4^n@Y<LOwBnP(>Y(G@UU#l8@MkASYJc9
zaV<i_3h*<=L_FysxJNKXm8LLv;^-*?hPH(V&#0KPoOiO1a2iqo1Ahy1@`)$rGo5#F
zDg1-qj!ozqcqNXjvUdV)kq!b&?_9OUS<S+o%eoqmGqh*<o$tK2cTITMHr;EMVPQ2r
zKY1sfncPi(uB!3~{0EHB#^y$~1Svy{RKD(<$<fhqyh?4K$nEXzeB;Tnbaj^aB;SkR
zR0uJyu4MGE#<=s|{N}eFuZ|`5OA6RwaGzB(5_8TEtGgmgZB^~kxe|%`um0+<f?yV4
z<J&bK{4Fq=pzwE)^`*;rJI&+ls=|e=xoWx!P-|%SRvs}{$8&}jX25$c{n@SjR<5De
zR|iGm!6O6XD5yO!*pyE0Fq#xeIxSv9gvhL3QK?!jFUmHU#iKQxj8Z#wvsvOvA~7mF
zYJQ65Qo1Ldci^s2$!>NA`xzSd7w-Os2psry#5|Ot^`W-!7Y4nq7#~md)%0J7>6+5B
zwCtdB67CKcq1Dh77_NHp9)Gex;I}96x>-@HQzoM;L_rdvGD{mb6wj8c+e0Q-HNraC
z=Wm&rb1X7M`{mtLWWrqGVIB6xd}^i=p>XyRHZoI*+Hvx`7ES<1Bj>m6cV5mmi6Fyq
zby3K`)rhJI?-)`JR-jN;InbK9n4Tj@w7@RQczG#8{_+xB?_kMw>M`Vfn2xJjc6P8p
z(6}~NNn_h6$}$|Zg&DuKpUxw77BS}s!)SClPmOZw{vnhFe%l{imav*=vqQ}P^9lX7
zEx;_+2W3g5GCzt=*$M)kToSWA5x2Bh{cYbBCgaV`EUDdd)e|tcyf)wAxM!#Jti1Gt
z^24Nvi*iJrVN|3wUD_`5B+g5V$X&;}Va3y?B#D3C-T8jT*mwf8hk)7_zig?};C>|C
zaViUbq)MF1DlFQ0dUhURVO-ls)Q%?!u2Hsi=}L{IN;>C$oGf>Yg;ibdE0f?K@Sf7C
z&=&D7khs2pVS-<Aaay*x3-goL(NL5v-EdGcR;aG9DdSG|Jj)4O)#UHEmdKxr2;mmK
zV%uhMiKl&D2HRkrUdFX{)lsZ?Zr%uLVuW=9agK?wHI4b3;AlZu_|81?DLpAF!|E*I
zVD!V^@}d31gW$^Dd-r^k#V}f~o;o5OX{Abk&KtUr#xkRP@J@?Tp<{dOUoIX`kKj{h
z7vKh#=j-2i{jr-wM6iRSdRB}XBo;gP?AZ=PaUM6zH^2GKxURH5oO}#`Xq+Lym;u)7
zE2b8~xb{3Bj3*U!I#{Mrc+7xkd%2tB<#HUBYF$)dxA>N>)zr%8X_l`NiScnWQN98s
z$&$u9Why|FAVjqEt!(2=AC1{|CaR`!B~Lq_KhhcoBEo^sq>)ijuW5zbERRU8r1wl9
z&2}x011?u9X?a*qTmX!X>2s%U=NjBV7GkFj#!2Xll<j1@K?_9T;N@pQJ&MA!iEac3
z>3t`&Q6Rb8Rz#A~Yk^3l67`M0oU$G9JUhnJ?cF$;pD>94QJ~px@Wwbb+uN=PqAmrb
z3W*F-W*~tJL&tgmV^Z6e(dvqE0(BQ8kITh!X_pp~?LgY1`3`|ig|UL)Pl$?#?$*|=
zlI55R7oJ_p8BAbIHW8MYySQ}4ir@Iq72vYrs)0Xywi_n2Hujs3;!&yYFL0(=$TF?T
z@q~6856w8pq!X77-gK4Oj;bl6w2(LF3Zeb&9swizBh%I5vQ&k(a8wZcd1Jp#uSfya
zGrlw~mWX(J>(QgkJw5-j?ml<S9LHv1M2Jvkn3x^l%AtP2b?V}GmWf-ZW6kfIw1hA>
z%FykR^UT1>>;(Z=Rd7@eoOjFI4C6FHn2ljn9?Tglkv0iS_aJEnWiJW&6dXVXi}pHa
zUuhK^WBbG_tCx<%X;@_$@a(ZOw##G0mO7-N+$pd<RTcmn-B>R2j;3s%NF&3HdxvtQ
zIqA**d9GQ*Ip-3l=e3^>tN5rDS%<K~Oc#$lDL6(M$;VxR8lGUevv)oRevF}c8}rTG
zczMh0cjAoknYdPNi?<x(ytg<*(o?>DwTZT^@t^kIv1`1^bFf@FyAIB43}}616&7V^
zWjMDZ&FZ~q^NUTG$a};O)1`ki<nh_Z&Ns0@?CaC#Ps;9&A7uA?ylNi|_=)GJbYtQu
zv2<bm#b5kI))(8zbkITxJ~sg}ALid1+V2+p?ao@inJyrR$tAOeO_+qb>HvMEzF9{E
zaf=tArZYtlC21|IUZ%@HB_7_XmO>m^Qny6TPjWc8KGZTZ5auUO29k7II_>))A-)*`
ziO6DN+!@5l2;@@|u4d&KYEra=rE0yU&mg%BQcX+YV7dNLS(uKOOrdG_G7|4OtBO4N
z94;oP48cPW{pN!09_U8meZGB8I~52rl`tugNC6U863>2^N{!Z4S~6+#Ndyvfm^O80
z3~Uo+35&*@47SJi3NzD);Pyp@q`^+&)Dqc2Th3Bm;`Fz>JKOxGYYPj6h4VWiwAzru
zLsv#%4Z=G--7bu483BT+-h8vd$)%n$Alus$m+4A2N^&_ES_&H*<7!D<>b?^HxJbWB
zoz9&cKnu=o+`Y98{9W9@d)n)o__{F=%K@Pyb5)U{$7O&;GsU8DZGMC~G<1#@tc4@q
zEI9Vvg`Aiw<Nada<+?C&$`vQXTp7PiT_z}Ohty@7B`)V*gc1J&N8NwI(nS(syws81
z+dNy2f?K#d<_=SoIx;KJgpEwb%iqG)`otR<hqx@>WmzmtBnpM)cu{6(j<n)`Tx$Gw
zKL~>n=Byy`17o^R8y(1u97EfqIpNVF3J~#0`1oD>Q|SRnc+&CY%69S=00sZg#lNZ)
zG=U7Li!10B7MFlMZGxu7jb+BvJ~);#z_>Q~?Oq;XYkTdtFtG|=g7d=3e3a=t7IlcZ
z;)^aLT}N7gDrt_9ij&X5NlJ)oNjTU)LgP!~vd`9G5WWV5Ti)|7e1+g$co}bKWmI8N
z(}mB>()qrYT|@ZQ>^W(vOWN||f3JPx8*!Jr0Lp&HQe{lG5d7lI8VaQ2ltoflmCwN~
z=Uk=X-0d%YbcwK4dUf7-<ITtVBcFWvB$6q<V=7icd2jwPSGfG}hd)fCC3p$iVB=dy
z3=JUd-ogu@)psrU>`%+!ZJw(YA`mV2#d`%?%iGGy60=sE4~eh9(*$kN{7+m<Sc5Js
z>l6ufUj_19vI8v;>&Sq#3izFR{ZoK|R3c18MiDegyd_<P70;#}4A6?GFN7w%s1Cjo
zWVMcpKC^b433#csspV+eyOurm)nu775T?3%)QlaIxL9CJ5{3d{`*(gP6Piwj%81n}
zT+*pVuP<6tRb+ByhVx%q9|{WRIIPFZWuGEhtQFc5A3W``e`$vo=_Td{r<PYML1toq
zE&srYeDKOib}cHAScFuImN5km^vk?)_kpxN#|O@(H6<Gt$z6T5d3!4iu8wtG*)<%Z
zDe<QZ$w_KI;b~iS4H^_K%Y)^z?xBm$N$}qDvml8mOYWqW;0|{WGGB4~&Sp06i90eb
z2Uvz7Yff9>KIg}0l(7^V$&oEsL=LP=;q8E~1oeuz77#$lkO;V=gA?F(Ro0!%hY4m9
zpEgQaL;CMnc)ZEx`WTJ>G!{|MkDrOxyw~b*af3>L;~<lFyu>9fFqwidMNOh|6`ZR0
zgemjRF^jMkAE`??wiQM`XM`PF-e<`;;~{PYp46q)Y{;rRa3^P}$((rSd05WHxfjHf
z5mZ=gk9a3jmnj`yVBLsslrJtQJak988tR-rx;eAE%(H@K!uT<!7xDvIb^?q&eSl_y
zj|w5$4Q|>O_f^^de3Xu7@iKyf`lXrl7kEg?x~HUfEky>_fBa^wc`N<;Ie;<vs#ig}
zGN{mq&k+okO?j3rgH1h_Zyaf@TX-p4EIGo+ce6`48v<|AwQxgU+}pcWRxa`ygkz&S
z?>>1qk8R2LQ}>f+Pa+h)`~B}nA;<zL`tjOpuSEfsH%LET+gOkanh)N8KQK^1u{_6I
z9()C;jt&oiCAiq@^&iV1vSbu((1bpFcUE4aumNws{dV!=?Jfn2>tfcy)~WVvXq`-l
zW>-sNXz9KhOvhl}<T0HZmjD(C8W3OPpWSAGbXEc551sSq_uVyQ!^pW>n+)F7cnmUg
z5kTlSp`!&NqcE6Ocvzut9TY?6OhEd)vk=}ZlA2~_sEAXU(;`|@6&_dd!<$7Sh&C&O
zg0r|2ItTvAbjT+`X}xra%Ss{g*dH0M%utt)$62VkhdH7_OS~Rcl4DQkm%Gf>`Xt_b
zlY_KQN-98dE)~yCPAfn(akJ9NHj+0Ck@WUarta8_v~4tnMb`ZLgLE?T%vF%ic9Jpa
zW5s}H;+k_Jy0k=0+ou*RyrN=|N0@oZ5NwY^M`qfE0iI3I%Ng)m87-IIcvPN0+bPRq
z-B@QZPy~X<R={v%e+ujl3_$qmDsoA-V+n}M8rDKR-ed__(g$$GRa{!&eg^ko?|{Z!
zl#R9Z2%_|h0h7riVR%O#E>Fi*h`Fp$hG6+JiHs3tyR6so?k%b%lMT{Y^b}|<R5$FN
zz-(!dE;KqBA<?0|r}V{>cB4Ux3G~0S$XH-8DU{JHGD&)+76N{VzY0EXdG<p=%flu5
zHz-RARq9qPSX!<cwzS}ws_8qHw%fP}aqDzUc-E@Xr6xWEFQ_Bq=-83QXY)nKkT%*m
zcxPNrKp-gK7>rn*uKIGWK|z!ajn+dN@yCN4wIY{C1L~U6UV)_s4FpK9<?O~cy%W-%
zn<#ZDPEKLkj)m<8F0QUqhzSpILK?b~cBm`Nox4KA%g*b~FmI0RryU9)$Bl~UkJ>i<
zrko31UADuE^bKyp+bc|6c==w~&E6Z5hW9dHVe=K3Q&#fKezy?5LTJjjVLnaEOC)_E
z{p_8W>6(!8*$va5JpHl^vDoiFcn|@&p<#ev_c$Br(y>(umACkTwkKF1y3(7AQ|n7X
z>nA*<oA9NF4_|p~CM!``7%WHvc7KRM<!3+p+k6vbWo4W}FxbfX=L`&YgJr#Z`Mw2z
ze>J>d?6V^HE%08X^L;J9CTPHYQD^;K{SyAJxm&sMcN1Qe)8Yg;102(tIE0wPJ1hPs
zzyDjOzXfK>k@5RG`Kw0bxjg<!h^8Y^kS1ktch|9n`!27kTm;VC0+;Rz3eV+l8L>#>
zIX*)O!^tbPrnqTHv&=y16W3Bydv`4T7WwL{uVxj@M?d{(dHUgp`Ffd~0*@dpeb5mk
zv?<GVDbGu0uF#O!B@i1J?TU2XV-1055~uA8gCSl32725jMB|zpORd<x2`>ea>C}9h
z<`zFP_1PC;>^ChW{7l+XhATsKg=J2J+@6OA&n|20Yh`kVa5+9N>szbw&ATT<^BN8j
zf$Oev+Y(>BxM~H!cNxL5x;mtfFl)*M(1EE!d^8+Idp+3QE2o}ty1qg-#!IFL6S-#0
zvc~{?vz_jMpLjMFM0Ji36B5pI(1<$5z(hK+U4DehGO9A<S(hv2aAy}dYn1>Sn4@z>
zUE1&04+Yj50!7R^qTe0bKEzT{xcL2d$I6<TX6!gE!BG8Tq8hen=dS$G+6H%Mm-f1(
zHSS;j4VD!?Fc;uPQ{$#dNx(%B8NBcXck$3A#9D#DS<^K<=SPGRG44j!EqSDCjd2!-
zopW=nv%{XUR4{~>Cm&=*A9r!YLbTeH(bG%t#s^Au==4O`Z!NGzKjek7r5o7#O{YjW
zgtk^k&goP-YdGeZ35@hjz}qL=O`LSEKuJhbq}Phq@`BN5n8g%!&bd<YUrk&d+4g}L
z?7Kpu@rQ)DacR6O0>nB@$CbL0%H)+drHt9tLW`dd#>w1;pP{|CO|`xkWoC|!x<2{%
z<1CGLwUu<0JwnnWX>E&q#J=h3+hi<1gm>6a=e(5#7VE;Qd{@UjuCx-_v^K0rL1DOi
z_ii+(AOHAA`DCq`TVuj3xxf6}F4MKNFUPg``QT5Y^X`U8b7^Xu_GN(Z|4o_}ZXQ!s
zEvH@nZuxC*%O_GApCxewN@TEk_Wdl4%v&V&GEU;pq$d?=){21U)?(1*(X<iMDuk;*
zaBw;?4==7E%|%%PFwrEZj}oX&IA<JW-V&`AgTEIjQ&U`q;eHL#QDU~;_DEM&1R9t7
zJ|s?;<Q}3`IBDte@(PW8G!BpH_Ii#fy944J@a)n_{pDV|%v^OPqmR#-IGI!!J$3q<
ziqo%oZAU^)JawxbXY(2Ok`0UG)2-sB#guOx&kBZ&2=z&B60tbul4Q$};j6J)zYKB_
z7+lIkfTw30bqAetvhPRC)O61QH^Q5;XsAYLn3}F4Erc+LSP_ga%sGmZM?b*ur!cbV
zDa^(*$N=vZze7kcSB42j4#D&#a)^rJ`yJ1oVyx+-%W&PLJ{TeF&QHqaxvm_)zrtN%
z!kCF~;;$eQ2QrpU^xJnDDHG4}<Bl!AWzwDqF+>|4F1YFmp@tw_MUb3bVLdG~&ftxB
zbp~R&paAI?rs)`*q9Jx+cv+E#v^_c8D@S`z%Kp(o86ZeDH*ceG=&Gg+gh@_6h$2M;
zt-r%~t8LR}T~tn%w@LnJ*}&$CeyFVvR_MQ04*g$1kmdto^y8_TE4b&ui7xA|!U34d
zQy60{&S<<`04Q}+J1}=&jx<9btcUh1(ynOZ8FZJ4b^A%*RWLkOrn<PnSzx{1@1zV0
z09Pu$il?zIxU2BlH?5Ql1dRK?vdCl>nxbQSD$M|iKz6@t<@-rk=+<Szv_UOA`y&wa
zrZtc5eESp{;R;Wrlqgb`mNM%-uCiI63IZwo7dX5K;-Iuu^UTT={<F*X2HW4tH<<Qi
zo|m%7FVok8{_&6gBCFs$WYKctmgaszS>{nd?mT%K*OteZtRO@!S6=99EqPv6YMxC?
z=l<P?k5|SX@w=Gy*=`cF!e9UT!}61#{G?1Kr#Um;Pzj-G#$Kjt9W%alq;+yWv`!gb
zerK@$Rz@q&vgdz0u=T3tzj$Yv3Jdek<>j64t=qO6T0XC4mE;R{YMJC0Wy5qVCx3O|
zTV48*dtAC2%0dq$g@h?zjxbso)q2R!h-I*3YMR}F7tv0n%fv)z7b@t=0sGQM8enB9
zBgjYk2nX)AR3hHoTysV-Yur62N-NRRSv5shF-`rH=mElG=cA7@x8e8DU2DGwGw^eu
zekN46f#3Cr@ZcUdmG#qB+ar^(4MI%f)5T@qGhryec(#2$tGP>T9`F31?Mb0r-5o7o
z{O6=oFiB)7!aBKYE_Zm2nJlb$FRa==2sh!?ox8LX#8qQ`^|d>+r4u*PaG;xYz-vGH
zRF9#K3yIcE5HJQe#!@iWS|6r+QN{xp0I=6OQg`jaB(yqY@E+H&1S2{+dR}&(9hQ4&
zYaN7C2#_{*VdmW~%mYSdzn#EWi+8fzeI#o4o^FuwWB{Gu)%_upP}BFlE|vbkWykgn
z!o||bO0gw{1x%UlUZCx+den+bC4s5?MXq%TEi9GgHFw`r2Yo#S$Bs@ESW|kUrm36H
z#S4rNl2ljF$pLL++-0b%F!`;!_p*#wSgBP{PgQCd3&&R)0xIH~b3ZDV3L1X#2OeYL
z4-^`G(t^t}6`A$qoN*(krv+#YN)xW416XmTW<dvK>XOtg5@m?`jPqpVg+*6?mf8<~
zyQ!~_wc(f_!KnHu3}ep`Loi2)lm1G#e6h2KkiRG^tD~~9wu&-=#mZRwoqT!qBEl3A
z5=N_{5Pn6Om8PXl6)*r!J5-czKHoqZX}1f`WT63lwH%=!UW(h9bDRa~)V?&!!m<))
zKZ%bLBn^bt1rPsGmVGgea5SH>JmlG{{+#E5_4iF2m%;q0i(uIbV&5BVhffL!+q}28
zn|aW0y#9L9G=3v~YZ<x)!Sb|TomhYR<&(h4pz@_mI0NUzht8YdeCzS@u#eX8q>NYU
zX0P|(f4_YB<>%3`G+kOH2A}7z`OrGnLi_!4y!n39JA=O)Fy`NTdvRHRqVt>oxn@BA
z>Wi<0l*e7IIfw!fYVsF@Boa81rV9g~-75^tFX$4ReGv|#S)AzBFRO-Q86uII;Q|Df
z)gTONhLU#<R%?sM>N{7riL4S(kepZIwkD*mF}3LR)iKNvLVz(WQPu_mWW2tf<0Kq(
zCp10LRqfq5j(mfhdUO|fDKPx7kgh8&1Tx*YmYkaqyW@7Uuf%IDWGr|N!Eh&{S{q#U
z*Y8odW7#tDeGn`g5zaKxSc&&pcbjRn2pZ|hs65X};h`qv)iyp#bP6cb>%uz(E~{v}
zTQK#riHib`LFj%orHjk+XwzzqT7%AGWMKqwbB-os#PjuqtDu&NhQVQqqt7CYNBOFs
z+GUn20+#(}Pa&MWvbL&F!a{-34pvsN0P4Po2oK#>t^lKlYGs!&Q9o_q#H%g<nbC4z
zfl6Cw|5Cr^Q~MQmYO&VoO0FyNc43%9U0o<PeU}werYna0_*YiU0GCAs*zVp*meNka
zs|DRvq&ow!j+1@Pw21X9NGU6d5(3tp@u>?~tgNnpbK)78jG0AE!EwhuZXMv#?Ky8(
zl`54UVYx^fU11pJNFvV-yEykfw4gwy>{xuf*OHW`PQXLy%~fN%#hkEJa}WMqoYRhl
z(jN}O_=5*r9w+XH?JQ?`fJF-|brnh#%V@-I&fMKQMA$Btjg27+Or2BHBB2yotb0d4
zfx=y(q|2$|nBQ#)gXP_|CkKe?z(}h~7B21)Q)$#DLT}PyEDYLhpIYCvkcCwX=Ft^w
zh&z|(8(v0VeC60n`<YK8NVhG{^hspAFq_3&KLzD|OJ|&U4M{V*tS{y8JRdB}HaQ>i
zZ08yMyezNyWl7?tZ51dLVig|cfcwvGL2D{?x*v5Fic2aT!os>bKlr`B_xKDAO~Ug7
zQSZI?b|j34#5D<f)1X=SP0y_Z^Uw2fEtuy9Fth9Baty}Jr+IPZ?ag~~<adpqmCp}L
z%>5?ai?R&@qb?T)ODMyBrhNYrUxCh#8%b~Qy8$^C8e*NIF&R=1apUn2qB_m*xVO0a
zXtY`zt~Zw$^Jz#hGas>HF#PJFM-5asqv0{Y9W^X9M3;WjmX6Hu65;{*U3uk79EHjX
z%+t+e%d4yTVAR3Wr&*n&OUgM9zb&o6IHNs&PBv#;ajD5?0-LsHW1;=z5^=O1WCUIn
z-W8E0dgm$(BAxzHch3u7-DUY=A$5j1kj}J$J->UF0n)XxkdSkB5^eLn?Qj!hgt~Rh
zgiH&pyRZZW^#l$7_MPgBbu-h+!EsshJRaaF(R+fZ!zN9+@=OM35T;oIOBx0E+V)yB
zSYqOeauwESd6)@!SBSZ5-HmxqpY4~s54K}1C>-Eo{DTRq-O~q`jJgoR)m$F&?)-w*
zrVAq!Bspdq<{F}dOL^ELy$#du!sVT#>7oTYx8YJ)+p|L7qWQYih4=;91y?H1-IS;1
z8{w*gQt?lWa^7!Ie;Z7m8u=|l!txQ`3QCwSV5~5r8|UDiXK|^atCdSB8Dp4Yge~cb
zOj*GJ+8;J)JTFwFWSlZ)Zd~FA0w<_38*|F?Y_th@alF5uyFz63-o3b5RjwS<%M<qt
zk)A&Kp&}Q)xLnsgJ6e>UW^8#LJ}H&@^+%cDA<BbCk>9<&mer#dSSjaR9_;~jB@gTp
z`GinW@JYtp#rdp8<Jmsh<Oo?|#(0J=(Vhra>T%xc0wG7Hiq|k*+b%4{*#!C}cd*Vz
zH;wP)9rs2<?b*xM!mIsm!Fn4n%I|h3|GdC3gg+7H^Bd;#rX7Uzjo;#<&!2tvN!h-A
zCvzQ9ZYkS-hYxXiyonZv(;FZC`q#k+SLq%dp8zkg6;rwM%A;5FL8*^F`l!77?%P!0
z*(h}~-C*Tj7TSW(?Y9k@Z>(2qXam;E;p^gCT#NU23tv|TDM&MWB$y_7Ogk&9YFCt5
z6C_>g5$OC@L(57n2*9jrZ+S19aTONnTVG7j$}ztP;$Ujd&T0taj4-A3mo~Fk->ge`
z{bZ_nb<L>NM7zv@Rr6K><%F_3Wn<|eJhnEsxPz#=U(}jJa@xASGRjdFYVYnURe-qs
zRHnJ}*=G?R9tGhX#{qX;R{1#8EItB+KIEcqiON2yK?>5ei})auzj?=hSUmbkwW^ll
z>b&jgxG)CY7S3tJ7fe}NG{PsQvF)S`+o~p`OTw~Z0TP#^+rd9W`(C>n4WoToxA0{w
z;%Wgl8+ZIz&Y&FaAETj8Ab{<_SSApePx<=)W$JF$15x8zR5Nq~p@hG>u^#293oKVw
z*RnEY#qTFzfq(M$yXEIU{rBbRlfB@?)-9|%#_yW)ml#6@ede+#TlbY`0*OCMSSB(c
zl?RvmIzOi6Aq+c<x_s;>aHW3R8CM(4wOvE{qr1rEzg+~8g0~NGUL!CUd-W_LCp!T`
zS)x%M5@^}oW%91Agt3W>*MLzi8el|lI8OFmB}Uwei&y>pvRWEi11cexGDvVg?i6WY
zMmH&k=j0=;tJXl`;EE?9y8=t$q7`M{td^oKg@MaJwbYyg(Hf2RP8;Gf;=P9>x_YgC
zw**N>b?&`5p45F)x=~yqc7mntQQ|ho{W_l2wRZrnQUAjS8)dwv<pMl1Ccuz%&NF2m
z#{s16G&1c6Gi%?7r<<X5&??L@OYG^LdCjIGBVRPqIV**#@e*(N2k#<C8>|SyeSRCH
z8Iz~s$>^hH%=ilBgkJ^AXX$-6OMk<6X2B=lw|MLJ-tu|3?wdMHGuM{+yXjnQXc=zb
zc>VR)qd0ofHHpIi&F{Ho8ylNB2IY${zl`!?b59QaAQ}P(@O0jM{acTJ^{Zc$U;N@-
zka?NRAoHvNR^+o+3$4M1b~kOix69DVX`yv+KCXqA)B0>(^MH8~1d{Jx)YtMSRl5_?
z#u?yVP8-ucLc@f_^C!N+*`kq%M5Z&C#No(m;&YMCH}KS&mR~tuo9pCw62H1QDATnc
z?vBlBpCFG~D4HgSE8$&0SouwxWWJi!`@08d+}mLoZboy0@Di<Sb9E)(u^7Sp?!59!
zG`;7ad{RDp@4aXZo;&2Xq@6f-A!T!2DM(z|q!})8iSP;y0nnI#v>)z)8|{$reLupA
zlIV<+8G6a+J!VArii{!nLfyha0q5jvo)Lm-!2WPUTq86sg0>7)NE$piaTo0$fMnH(
zTJaf7#Fb<2uwUC+5s}LCFLu!2{SN(l1fZ}x)}=Ls$-}U<?i3Opxp59tR|u=rk2hA!
z_T4*_>(W`YbeLy$=I$Sq=g+=GxQxr)`?s@7Z5JVR@AhW7^Wbj${km`5+$d9*S)Uvo
zB0%ehl@?u!%XPTFoAJ~FanjbK+&vz}zS~#SZWy7OHd;3Aa#P{*NUa&zP0oQC3|VHy
zuyi2uq=h+-fQ`rhUn4XJqi$Iu&;BuRIhvG?3X0#S?vcLl(pCh-^t4Q{h;%!+G<*PD
z6e517WO4BVq17wP3Paie+vEc0saK}sSVXAPMg>GPZW$|grQel;hTr1qG8%gF&}Z?4
zoMnVnI2^Cm^R7@ZU@SyKPvDF$&gY+ho>hV3q0BrBH)h18AoLQ(lQRSZ?Q`e3tD&5L
z_aj(Zh_8Rcjm^tghBMp&FKw4XL@wv4z*=f5GctXt*DAz2`{wdrcelGVKEi?i=)O@{
z33CNt1PDQ4CLhqPCZ4+_y}_wn;S*e;UHTLylYSV)@5aZ{H=bKOxf0j-%#Glhg~SK0
z^lDaiguijVo8`02lxLdRWiHEVFijpp6adN)eh1*IOUUo~Au`@MSEgH9PlEGR(p4YJ
zS?;DwTu;>nI5b)vru@!eFnavXyFUY%Xh<MLYlOiLw{X)a-iJ}N#?0d9pWE;GvJCUT
z=kpudZ^L{Z!^>$6wXE3>LMyx7bG3LAw8V2|#f1eJ5`_TaKVI+;q*9QmC7Z5U8>R?i
zB%Zt^%8Cxv7}JnI=HVo&K3CIH1sZbok1O!h)?z+Wse@>~cw@~!D_afQN%BFzTaNaQ
z%Gwx#VVRiqGD6)h>u3gRw{GW~6<Qt7Km9aEp=f3J?dfZXE#ESy9zD8R9j@$hM70E>
zoy-u)yCDpp`orA$t#&o+b;|(FS|KPya-vnuR&7!ZQi6)`AiZv|EO8~DntrSZE|)Xu
zH&-(kuK5xp4_YABNh4yhX|0TBZV#EJWtiW#yPB)hxhm_MYcOIhwaYTXYS8^>Tlb#s
zq8VY4+}UD0VD1NpFm4zGnv$^AeW+5fzUe19M>!j8dU70M(IQanJ$U1FgvGsb_l-Bp
z_N|Tb{(B!HIF}I8cOxKNvO7R%tBKp}EX&r1P8&j`OA6J)2>GnalkgaO6^1mDO#1BY
zlLExw%ZzJh0meeS7I9&Wp~(mY7bNJS3>5+k#1Pthb%ph^+!#Crj;Aoa)6*uz5n8m*
zqx4;Mv%h!Dm?B_dmP&E`+<F<h2pb!vJ3<yLQ_ZqgVyk6b@iy~DrnKF{+BP!2&OzwT
z5dXy)1&C?XUR46r+C8XGp%bM^oCH4{3s>-{xOi#NsXT#DJOfYOUt+yoQob8ZdyKjJ
zLV#kKOirRX3r@eFx7_z6YTcVy)+duJ-L-wvmrJ)TKh`zvm)&2{)*Lr)f21|zg_-nA
zaAh0GqfofG!+y0rFRqqU7)u)}K;Z|J;bpj?8}8CE523NfLyb2y{^Z@dc$4_{-r#fl
zeUs0tW=Nbc%{$^MKdNQkq@PRM+GQ}-r~KxUmw14#N4a~{iHl+EpDXFc@Erxv1lXz&
z`S}i&f*cgfpH^sRcX#)(NY!?rTd-H{V7=P!G+=gb>6$cczuU8+<!xcUtd@R0&DX^l
zep9?5gg6&kT3#gmSK<iKuDOc<Y9TT%5#Pw9CY=O7pC>)!IraNke-fyh`rBDr9zdz4
z7N$vQYNQ=(YPY615YBznN^1RKnhq|AD?&u;1EH<QW5#9NV<#73NLHmj;|F!rs+};-
zfr}q~l;xHpd6vv_>05Rwud_2Qq1AV8wbgG;`8I$y3OVa+^9|{gL}Ut{U6#DLHY!Ia
z2qKua>7vn4zp%;9RmxY;m_GX-EEhtvU+%h=a1}aBSWpTbg@u}{`yOCvFmB+>vlHx=
z8J*4cl3$Hm0e3=qx+J<wS8>-lf$qfS03n-+a$tUVpjqv{hhdmFg;EA%0E6~Rg>YAd
zl^Zv)NMKB-lVg)0fLF@O%5u5&;6B7NDi^0mXu81m{G|NionM!&?Uiy1i)0DwuRlUy
zAs}U17Z(UP7_*wb?N@u(db>Ei$c9WAnF~<BvcT5mu_5$p`VXGOIsy(t=o|voP1OTG
z1|ZA&y+<KrzkNTtP2J>kB3fAZ6+$Pp#YFd8NVl0&qdq74oxhZsyP9cf<dGZBy}<;r
zT+HKm+XsQA^?UBu5@}CU9#syi1`Mzm17RdR)H}36nkYIM8~4G$(EX!rt|}X^uVIBR
zVrlFJ_nfcNauDBjlZ1vy>#9H74*<b`6&l7FLFjT_+n^S(aCHu@IXMr!fsYJr2=fx2
zr{JW@m@dQPqci%45CTsml-3td3CQHQ3t51VxG650-^)pREtUv2#>oR%vq6`(+P_Ah
zq)vW?k;2Ye;({fe?;2mQeDgKSLwvsxHoS|nHVgjNwdlR^P(xEt+hs7np{4V8>Za_}
zH;Yd@$a8ZiuKhNoG@e^NpKYuBLt1(8%A@qR@-X-Qc%%$8cJ2~j<O5}W^wF;|D1kdT
z>l|j<=pd&8ezXehY-@<2HKN6}`1b7OyO!>MEzFl;m@nt$FdyH_pZ{&t*X5f}`*OQl
zdf*m>xCxepHR4}>TK+7*F)4@NYAZ4?wKAYcHem*!CCVU<L{3r>mz-hLS3F<W-y*5s
zickRNm~aVO<ORWVY&Uf*F1VKe8ZA_$htZtF1Q{ze3YX!1`SHhfNhJ08ZRvdUiE+!f
z6+jA?^i~tTP5`Dy_9J6E^P}@F=xIC+7FV?dmKH9{%5txK`TP*#MIezxAs5R7#%4mv
z!JWnS6B42Aix4uze1T8_s#-&8;v$*f*0&D;3nrun<+^^D1#lct_mIAi6*Sa6cKIO8
z*SHhP?ZNqnT=k<*PL|e>{r4$b;d_31o;qAvWZOMR(p5XI{POdv7iW_&AeWa`SEF+j
zOZkp^AMMs7(OucIM1NOrZI%@@v7E{)k->b%>l>84PTVjnz6Mw#OD-~@441PG$ful;
z=mtX=Kd=s?nYti?v|;ixY=tb)qK&S!Qb0S&o4Ew)>LH|t>*Lhzm}<$%8ZzeuY+Q(N
zc}e@vVM>?unfI>c&v*3clR{^6b1SE)dMM;IR+r;kt(g@@r2b{44VO&3N89^cotagm
z73KVmOkek*7D&d4@z&~ag;^iVMj_*#fF*GB;*|ajdSUKo$CL8x^QW1lS70kty9jXw
zj|z^8fO8wJKojT1OZT%}A~?j~Fl=zB=b{4&I6ic{>s8snB6L1SL8hSBt+caqfB?br
zI&<+v?VDC^s1Z0zi?+W8egnts`=Bk-s^b)Ei{C0F)}0;Jz(s*>I@>9|#X6xBg^2Vd
z9>v1ocbGA8jgiYc9e-hDAB}DN$29UDvgRJ;br!;meKAXW!=s3^ZT`xYe2j~H!ZG4G
zX~<{2-mNF)`OH0d&)s(^m-~$n;{M?WAC%|MpCL5dqca8Ht0khBA!CIgdGy+=)aSmK
zlj<EHAByVmaVyk&yHd&D5q#g$ynMIumSLDLXTIEa|GK(<Q~kzy)v|rx>iBA&!~)PZ
zpe>)FrK?(jF%FDn=B@uFzKv_kXJoXF*+9r`^+&qg^75ii5SzUo&<MjNou={j+IsOL
zM@n^(MHAW;IJzBN(>{by)o7huwQVs?WiaH|opXw|?Pj+H2v3(#-jhxw%^-qAwpzrN
zA?U7BXn5+WKIZYQTUoQN_Gc$EnQRW8b^nNP2I<V>&(9&0+YqbWKRiLpm#N!b!C?Jd
z&T}XVv}Qy&6i))}w|*JZ70;9d1h5DO(fBP-M3!lKRD`RI77<K+DjtiV<Q>wsTMr*b
zxGHd$Tpa>q=uA&wW{YL*_7;}LQJ9cRhecos{tRtMSZMLN`pB`NdvQgapH9o^p$N}7
zqcLyYxdpJMFy(Fp`0aZS%GTXm5kC6a*YDg#APmd#&eQT&|L&c#G47Uc{MK6$9x_-h
znoLv^Jip2@_Iv4>sHVT}0#~#i?;ZpOgXK<fVTG=$r3I`37?r{#t~20qobQQX0WenX
zR(CRA;rYeK^)s}$VA6h?)_JZ4;3#9$-3AED^!Nm8Ym!eaWaFSXM7z`s>m;XI<VBcR
zTv6hu%A!gQ^~pqCktB0;Y@AnAr;b%e5LZUy)r^HpVjUx`&nyuJSE8*l7S18`Z4h{W
zw0j(Pl5-1w%~6;Q5S)kLu=|z9tBg^9xm+w_k(!??^K6Wzc8|^~z)BNcLJo}q>+L(6
z^Z_~{T|5Z1*Kd+^5kyA^$H7}O+jnu_)=MAKe{_E06biyytD-XG86QCC`#W=<;vLCD
z<6hL2&5rbIVaY`%)f(~g{X8!T&*NDjr;S|3wR+oc?}o;kl7_o=8cb_Q*|XnC!`*g9
zC~&nh)0bKLmag4fT|T$VxGdTsO%poeho>k!{ql?Q)^B|~3gS8n({M1Vt19I)jPJ(g
zTD}G4f*J8wyrA#h$E`CK)+%Xt!~Am#^NsXAf6eEc4=t^s-RI+4__{cQabCW+3X`;r
zgDp=k(zZT%Z_h25CIW=$S?U0@zN@}y39e1j*LW?0np)ud><4VZPz%HhG1_YhOP`es
z5_B^uphjqCt~Ajk6d_w(F_C%irZ%f_<&fHW3}eqcGEq$YiZ}`tiCB$PCeet&b|^r!
zPFz{jPR|t)tf^gwtdNpWfE(Sb{TFsJ7>H`k<Ixdrwk1r+_vtSe`Py<{-C<feOVnMN
zQ$=Q(w@LbN0kzVs!s5L`2u#de&cJe^Y&BH1YM1iruF@s3asPhZgh<(=d-o8W({jA`
zJRh&p_pkMlBd8Go4&cSvWjQ%^zC)`(=I%02;g0qMQP^?a6k3(~csH>yrf0`!u?P&x
zxrG2(_0zU6`4xn{R)m6Ya<p51_QSs^n_J`Z=6Al8O>rGGbA<*EVV=TA2CB;>E57KE
zFtxuYdq><6)(Z%7G~_F+BsUBCp`)z+Luqi(-P_?RAhl(O-BoGJE8{XbKsX#8gsI+t
z^r+nb-uKGr&Yd#d-K}GSmZ(5<1Fdc-1&GUD^Hn|IC%9b|=9oIZ{Ht2|tnM5~1ADD|
z5l~zl<1_&r6>ku-0#C-_yo$T(o$tuRbQVRp3>kPJ94Iz)bBTrQ7XTfb-hlRCjd^C7
z*2oEp&=4l9<u<v%BBnv^T~bL(3&0cUq`L?{QJ}lTEqHYkO&H;Sg;lF7Wr{*@%=o!v
z*ZC0Zq8HT?kP)Jkc#f6y+U8sYhHcdPPypH=1-?AMIkLEt_*3W^rzb$oJ{E>>Qdj~T
zKgFOx3a_E;w(vy$Vp?%RW^0_~q;7&~W!kkZji=Q64Npm&{6i5|L&lK!>Qby}TDr#k
z+tv77_}VN@tKayRj{nl0md5{mHs9{Se%XWuUU~FN6t(@mgIKf*mstIyeq4rbIFHxL
zd`nBc#}?Eon{S}c?YE)*emUOob?IIX^L2Q=TxSc$e_ejwaLHB$US)|dl7-#Yd|WcT
zR=(loG6h()c}WHYvN%m(wO@0|6iwdpH6dgP=JHqlHUx3xQ8@T)yy=}_Qp?r%Ts1iT
z>QfNOcB@S&`56Gpm8hL?wQe`@fC^~S43O<-9GokV!OCb8D8FigB0oe0@nt?o4nUlf
zsUouT6P_GOXDg8=Yeg0jlZJ-@(8IuMZDR#OkUdpPC~5d5vFmD(cr3>{v%4Ci_DmuP
zMtIpKYjM?v#LbJ8qYqyaaJlM;_(d2(&V3?YtHXI67Y>XO9&m(cIDWX_)j77o4<;=l
zfudbfw+jcHxW0y<Cx=JWeGT*9C>z_iXg?-63{*2)?MXP>4qaYr>*F%S(zs+y{20!i
z`*+GV+Wqo)6br)*nHMl)twHBF-v67QA-I;x_kQ<xG%d3MO(qRUD0fOzVMZX1D^uL<
zE>nejF`nIWjCCM$UU3;M<9>#v;EJ!|3K~8Ak|@C*(oDmgwG7<jU|JQ1Ot$;cDVaC0
z)1|b9b$08`H={VX8POF=3mzX&dld+(Fe6~ojtdbM;;)QVCKL>&?ar@hMTlQR+K2WL
zja`jf_zJJMab-NT?d$}GjQ}t{3=bTZ344Uh<it5GiVXp|OMQrCfFc8KZQr>U96WN<
zE9pC3v1hRyUonm_dGXeT0v;b84V?Tr+>yTLI2MGEebUvc1*xUto;8`Zi0I*<c4*Al
zXSEoLf@!P;f~}Vw76oj#e>36V=-RQfU&7EiylTBEWa*<Yp#+x(Un$h8v7T}RSMDlR
z(xbl<cy7GH5Sp9a!^my>SAuUH3V6`XFVfDHV|(WL@vNrA8`|%iHV|4`uUSOOZh8D|
zTdc!0_CwEy^Fpt@`f5HYd~$jcD?Y+eJdfqsDW8A(X?P5go?Ov?Jl{A&`#m4p`xf6S
zZjEm7{%+4NhnBVh<~ODNyUL&@E~RNDj^;yjWr?iaQ*_~Fyld_C{R@O?<x2c13Bc%v
zuxTRe5?Ye;7gd1Nw6?ba-uNz@l+uXj4)UqlIoan*C4M3ps+JSqHt#gmwH*A8wXl`h
z+s5pvusj6`gcbiXf+lgim(j`?B(7*h#HqpN^P$A0EaIIo?e#rtYnpF+DA26ifj7T+
zpUsC{Zt&8lDWkD}Rd8OHb%e)s3LyaqVdq4+T3ZCi?20Cj2AVUT+}R8xS+r5)4~)2?
z3DbW8q1H8^K9}wefcK!=FCFJ`K++y%t-<J4usU4I`sxpUP#*m5@8<j@zkTlhk{tNP
z_#Hg`A_Bxsdc9?j@qh`C-`%k;LtWe0LX-8>-1Bnybf-*?-Jju_^=eICol`$`jW@<Q
zNYOF5_uye!zqN+t;l!*ybyqdPWMM>FAO)-8?VtTzOe^31-S34d55`z3gL+n%$FQsY
zieBPGR`}Rg@X*B+XZ$`yfUS<k5%dbuu5K8#cj3KC-&|4)CLpvBKBVdQ2IchVpqycO
zh<d#~g-@nASLz6@?{sG;?YR4$??|{g@bPTluK-q@az5zz_$b0s7mqvTwT`F`X01k#
zC1^WlW97)z4Ud&BWx_Jj3s;u;+yB!~SKh&BN#~vsnYla9T|A=oY)Q^BS&H}t9}0bC
zK4G-VSRp`wxu3h;0U4K^pP{Vw2?38aQIG(H(xs5aUM)v!GR%u+sKmJPY6{G*P;zo=
z0{uBW@|!9b2oc5xrQi$&Kx;4zk@lQ{YvMB)ibW!{5j6If%S8uS83^1I`XlIKnR2DA
z&=0T>Hd!@EVOlrRz4h9z@C2Uii<i$Y^ET5Nj5n_FRu?YmZsjq*9S^UT&-7kC8(KLA
z)3o>e2;5%|E#FO;Ye&kRYm33(Dy@6F;@F_9Z)>Ta0tY{}044x~3AnX^uy;?0W2YyC
zHh1E}vM{dzVix{`Mtn^$%}pa_&kYD)7v|F&zAo+Gm7fy0UT&jxTJ9{L2$M4EV4B`;
z`L30n$*1I#7<f5jq;6IsL5RX&8iA*Vp5ML`n@H>Ug#)X}!!%@?PIQZSBA3ZbDZ#3t
z87KRYuvXM`$gc(}0;}FQ0WA}XYk)j1VI26iJeil89VY+wg9jl1-BbBy3+e5XE2UP~
zmthnOrLR^gAwvWrzwWB|XJ={EtaKBpsb3&0H{3mceu>6@LcjH%krrHNK5BudoN!Xp
zRZJ>vo_{3j`j;iB^v%n@slj*2H-z!@U~Dp(uD*EVfzOccuG0TIw{DgDZ@pFC{4f8@
zvi|5%+57zS^3mIG=eq@)ymy}C8J39Olu$rB(d%w?+jxeC?>Ompl0iTD?342Ri!aLo
zNbWlItgr#Die@$1B{bTtyIUD9edhPjvievaYW=I2=}sEvl+pe&<ubNhzxbQKjR5_@
zKlsD4vULjvHI8Q7w0HLr<RCwub!Q0+CyQmEYT-LipO;n29XfZSyM^|<E8ER=r?lVs
zg<cj&&>u8>kE$2+GENz`!bW&ckIw=Vg~-XXXT)EXRV=49*Y0D1o%>ZpI%eBkMyqyz
ziC}d#Su6$sCLXB71Sx4Fn4j?yN5qHh)F)ny755YXnfKuCCOt3vq|kIpu=uW}8J8Yq
zX~DPv#0gj}FZVn>IXsDwzveRj2u8H1bxOS|2r4&=FngEZdi;%xA9O$VN9(|4Iq=j5
z&=u@Fi|w@Ki;R;3qR!zUV`-b;wUIVm<RCxufJ*5<t~K(h6w2QyB>1X19WMqrB0klV
zHxO8qG0zLbPpBJUp^>|aEW?#|j(ba&ImlT)FWV5S&isTHSHp}C<*9~P$^_H2%kgP>
zT749F^UgB;oiez$^sP?ssmFYCzrXU#y$KV8bEU^9Ft4Csi8uokCeK1N7pZ_zFT%sG
z9M+YDo$g}`yQ%D@O1>`4r)dptdFP*B4()vlzbWl+%1@5j-89w>a|koHToJ}Mm7wQc
zSXHppfv9zAPV2%lpM%UhnJnoQECN$&TWwP05wzy>ifNfTZG*pE-ez_*H5fmr5O<ak
zSKAXlHp4RfVp`VA6E`p|`ShVn*p!a;S2ZH75w(&2QlG0+256@4G#|n|T@~R*JAIP6
zjBK-UG!Dj7R|IvJN5o&1Bbf;8*Fy4m2$_gyV8zU*UWsaDxl@jvM<A^hgN@3;eOw-&
zl4YB~R)*m5D*8UN_XCDt``zCWS0L?`+2lBTh<Avk;9-wl`s8l%F8z-1;Qf&J?fVbP
z!|#2s-21)X%Y4VDKmU38{QdXyc~+OIjz)t_ydEG_E~YRqg(}D_(z<BD)k0bgYMXv)
z_2}R*!Z5@@!>(aE617&HV>(_%_}*EktbN+KSk|`IGikmuUdN(CcnISGS}lFKoSc^q
zTJEoY@lJXA*-m-z=swyj0+RGY7@N#XcjOXn0H}G^=(?C3I-qF5M+ln{f)D1o&}B^e
z2;xhG{1L=?R8A2TaRCDF0e#S)FSGGHFBe#do8pZ)qcCvcf!3%Nn2RP1rwAei$oic-
zWnns@$1+Bm4-VKqEo0{n6y!M{40t$S*GIkADnl2@WW36e0!g@4w@DpSpT%L_X)f1Q
zD;=#MK!LxL^De<P-}&Sc&AhsmbTtKkdf?OvI7Xj32toG`d6dqXG{XCQ(tvRr32yCU
za07$_CsArHPqW|S9EHZQbsj5=18f)#636YA_$NJiqOwQe)BIR`TFx$1@%SL&>kAhW
zNaJeEaUl^G7cC`9qY!-N-&Eer-<YZSwYn9S*8unQwC*cOpgoPhm@XFGtiJHXwAWX}
z&F=Hh5n}YmXUnPkb1HvnciYkOgs08w@baDcT3dbRm3A00OW*RCHs#LVx3<@DuH_gf
zt?2e%LwVcW+KQs-=ZXU_#yu`^^7t+FEGklfq$EOXY%9F|{=33_9-qDbQ}VZb^I<;j
z>)sPfymi(0)Wq{_Fa=M2@zT2&<(XfNE2}qB7Wj+Csvq9pL3{^;K}MmE(iY<4GDkIz
zYhPoE-Uu(=p~bk$$jyZwpqI7&ltr-&63Cczwd`x%K)jP-s=50u1eeJzbX-~qvszuR
z1Vb8`zN>O{@u(&EJL~9qm;DulbLvnFk&us~iK~TcVNoe<w4+&`N!?C%4*QE`GOe4X
zdN2~<(W8NkAnlVVgcU>&L+H2*n>M<7EN2c;kIdYY3uHbrCzshykE+lb&~8{wS<+nv
zECw`Tz&MOx)VI-Y9(?CJW#f%E$``--Rr&BQ|FV4f(MRRUr=ONf`o98AUyycxXE#3Y
zE?RmHz~iFvfr(7Rqto}%g#4aCTnfOf%}42kaZ=qCPmaUt`dZn#y-wQ0xV+YH-;VEm
z{q~)}T1zBnQ^73M%7xXZzy6@S|MO4FcmCeD%l&V@g#~jr<D=ULa*F^FmK7^5%h|yJ
z0>-^5^tA(ny;vxFXyG&fjr*V+9_|NrS|hO>$>pjn2~#UdArd_0h0DL?F{S}S8H2^L
zjJChLJjPnYS^*ah!G+cP_sVUoI9-x()G|GFO}|XEo)(}mFn?txj4Zg}`?$TRL#vAj
z4_}}T`XgOMa)~e87zY;?h!eW0oUpf@3PgpV$6Hia+06Y%KeWQd!_^f}Z@wzWr@Ef5
z%QC~Kfxm=h?J{x8pySY&))V=8=}E<B2ofi2T?~>X;l?3!v_E9<wj-M+X`2i^%vuzu
ze_G9_CkP^x43(&QT)nW=g$SHU<7QkfDOq@qh$pYBC$qQ#JeHoM8!ylMimQ^odFrth
zN%y9cmxy<jr&zxw)-kKRq5k%{UjFd6OufeEJ(og0<3m|qse`*^2=6d@g1?*4XzyD+
zEwnO>e^EE(k<W24SVr>B>hXO`e*tXW2>S4qhfyp6W0c3U$#FjJ<_X|_?$&hR?NS6t
zYt($Ou&)cP!gjULo?CoN_jiTAD~*7&!?vw;xP_MQ#l5w^4o;oie9@kpz@rm{9-S@2
zbY+KHo<ycep4C+3)jx?68U{_}wG1u?S$QNf8uFUI2nov25AD*|YY0Rw3Nb-i(ov^<
z(a)ZvD%|4%W7TG9yM$L@EUsFSp)B>Cj9kjm4Qkg%M~4v{(f)yp8i~Xr!L|u4_hjhS
zx`Y6aF}EcE3DQnOdRd}N3(LrL|Mc<L{R9YwRfK^4_ADnRokA`f;{+T1l{vT>Pq<t!
z3L69s0%b7l$6C_Io$ut6yF-1>dngpU`n&1(N_R1PI$V9VeeZsG_4j|j47Rt+(+@r<
zPd@yx?0oS>*++Xk0<N1{0Wg#a+W5&i+Kzh=V9L(z=t7ZQ_gB`+;qFe^d-^1Zp7EzX
z{r;!4U&hl2oPXJavUO{ORp56!rsX!)&)WKC=8~KP@xZ*n%BZ?-ddo2Ry0759zxtc9
zzk68z;eYkN$v%)lf5b2W4+MyAM;VsX<ybrEeu{;$yzHsOl}R(a<+BgIfEgZU^-zR9
z0yG*jTAhMhE!%RO(@?MgF4|1G2r8HwxRBLU^xNUk!a07r=TofEV+82>D~}K)56c;v
zxqB$CXp3W_aJq6?u^dvVMw?`)&ar9VTmav*y~FG$5f2>qxaDBvDpBUI2P=xNl@6T$
zGH5yb{+w|Vck2QQA5kn2TyBay*vDGNngc{-9oUb@rmHR~5I4K~JIh^geYsu(tT7h_
zP=`WHHK2>dB;KEctL`}W8x-#Tw-w@{+~4oo>!)|D6%^zSjd)stb0-SPxLL(+2Bl`J
zu2uUU+~vLR-2CV`QB=n7oVw5jfQ{#JX$e91f>T(CU!)WNWW=^<o}X3xt5=N!h6-e!
zT7Lcu4n_Fz+ysTc^WJC64}Yo8^W{3ptzs7;Lz*T8y!+ng)Xim|)3;Xc?2?BNnfO}I
zbrzxAefUa*sz;u<$mif-KkwUj)eoWB8v)V^oe!ya7G8ee8rnj8ZjJD_&+}=%E__{@
z_FEv!bp2gB_9C==?Oxqf<`r<>$<M&lWr%gKl3qgMpGRkl<T?C}G`f^@A)F&nG~<G0
zq>sfgE3jH6w51l2IDMC*j>)Xs_qDy|&%Ype-b-kdr3=RmWgf{6$6^3At*>ExXj(9S
zPiA#;@d+BHE0Xk$O9(C-bfchs2@)D7p>Ww(&t3BS5Nc+AOQFsI5NJzW8W7;t)=CKD
z0AkQ0@>?9d<)RlNq3sR4fE~|Hh-<#uS39i$R9lnj1~#;LWhnEd&k(mOs{G!Da~%F2
z=q7`qtZ#0WTd%xU-uR<GDp&OXgP;5)hqtNGoWSsPQ`}oyhGm==7ayNU$W*wrGR!^}
z=NdeI-M(mDJ^%De5cn+Ck$Vj?K}y{xSS;egH4I8FbOnfAvir)L56~9R%LqZRxwV}o
zq$7lflk2@P*4}tM%yOwa$TuZ)r+ob0FUzN&eqO%wJKsjoti@8X4KhjHAykuj87-Ej
zo`TjT#Awmrkqq(Z@U;B$XTM@hJ+BJuVYC{{Nns%_DCEMR3Be=b%s9ySPS5<b@C3~q
zs~D+r$zaILjt}=3A3Eh(Ygl3z<k|V`vn(_AQ^tGGb{NyEGTK<9u84Qq?U59~4meIv
zu;@Tw&zJHOz9WPpkm5IeqD{Jl;6@dH2?|6lGr#ueX#!Q7hi;@D#{~GhXv8zPoTt-e
z=X_4SVJ^PVzpZWX1-!9;3P>oA_AI-ygK~(V9ak<#MmTC|`rY&FBG)~v0Hs}5SS`-G
zWv+m>xrm`o*n`*ND{U2j-Bg+YE$V*LeWd^r$E!iD0>nEM9hEodVLbiXm5^E!etSP|
zDlUbP3YFhK(N!&dl9_RS!HWV5X=8Q|kC8t4J<qd*l~m?@q<lg+3UhgixD<tyyzWOK
zS@POk%Zpo`GF#b>jC@fKK#pdyZqv4F)()Q)EIuokybCKsvpg)vdhD<1o8sl(H3h|^
zS6`)gS4m=>`|&eiX&KJ7J$?4<g#eikHx1x2q|tM6E#5Hy+(L_M`Tnl(ccn4DT`#9=
zzrPya?g0t$HJ!+0xJgTt+Fh2#`ks8zHZ;A7mx0POvs0D<sLZ0~&7Z_hF*z2RyA10F
zVUor%?O?K_T@i=U6-JTwjGv6%X9d_2Sgni2E6WgR+$ndze<9MySWT;2%!bRfByJhJ
zlbrC1EHl()b`H^bjD$XC5o_$1;>eKW#Yw9+yMK6sMRNjDE=B{Bph2^k^#PSX>AxV8
zF$e<_39D-EgYYsx+j<N`hOxxmMIQHbxG~ZrSUL!@CFpG#26zii=I&d+Ro?pJKh6rP
zU;f2k<d8ju<gN#_K?t4m<FbHdblvS|&ww9AT0~p#Vja;~fepiexlFI}trLm7+lRO!
zRNT6!H3mbKaq#E9f_m5<Li6?-md|Z~bWt`pZ-r=_Khd4HjwRGz9wSK9f)(Zq<rD#B
zDZl>3du8Xz=jHqV;O`@BHp*am6owJz#CS^U?(LALxi`Xjh$Ac`&*72@9~?X@zx>57
z5i*0E4+T;MGvj_?tgNfMD3e5i@DCUo@3AT3>PZ$gfH$2gaGdv130RCz-sQC?<yzMc
z<D-SDMYDt@H3ha8XUEyQAbgyg5>ItAI*;af0U#P8vxPzSmr^bbh+?3i$c}Wz#T9#g
zTg5qthKn-5EWm*IYK<+qGLA8yoL$i79rE?d-FuthpjIJPBe<)3%J~`hDS3LX@atGF
z<y{~+JnmjM$tmL{A}Wxg(etNu=(yL<K?C>Tzob@`MF%2#MR?R|S5Qei{<#=ICN14W
zp(HMIlYk%|0s5Pz+0wnxNP$852q%)nwG8rQ5?u<>^%gfbFJ-tg)W(AvkMU~Ey8iY~
z+5WQ*F5jn}UK#ruZ~7J&p=%klOMa9E4zyRk<d}G7SdJQ@pQbgh&#hgi&AVCI24T|D
zRE3e8{BD+vsXP$&2mjgM3t!UGmyfu3M?vcx-)AZ=O@OpU8&bfmq85ysZ$wM`aymnc
zn{V)M3co3har5!>gJhU*M~!cn5;rMkzfEg@_$Bi3;I|W^HGy1U0*EJ4s6nC;QJ&J-
zLDC%*;3qS6kzco14`LR>79e6`Q>J<6gF|49=B13=OV>mWUgWK=rFujNNa_W0Wl14b
zxmioDl*xF0OMpRW2tZ1>(qXOON&hMgveL>v^RJ7<I)e}|-1&Tdf~M|HZ4i{YEyt$n
za1fytBx)GCOx%}Zy_Tn&!6PjcRx%#NR|F>rrqz*CW@SvYNhandM~~7Nh$k2BIEMjI
zrr*~X-@8|~zVVH6@ceoC;HN(gTn}M>Pj`081@{h;#_wEDVFV{G9i(g>Z+;DK5u}X^
zhkDPaZVo(0crku3w=iDY#u&v{-{*d%<pG0`7|A2UfAGdbn7{pz@I1M8x!k&U7Y5fa
z8+Y%(K!^F#pj!3S^+i^ADX>3y=bf_q<azntAO2@$hy}7dUc14!xcg{l+9)Gagkd%8
zJ$=R)=nm1<GNq5t%IV~iyknZBzy`(+f&<0PUEnf)elecn9&M*?1$TALAg~d1CU(xj
z&kTe~%8dP(6u5GE=5ZbuaRWNp+>!ah+%KjlVRW^<mHGEQsBx$pt*)r@BXZND;|SX^
z7R+Lf+Ub?^$rMZCq+Fc32V|0diyNY^!bTzCH)#66(s`W|VCJF>ca0B$wQ$cTgD=qj
z5t7*(Ldi5DmV-k73OaNZqNnIO@8A(D+Q6}Lgp;5mi-O0wFs%vc16B}zpu0JHM08)#
zwy<m7+fNy@){*T9qp!7xCUsSc*D_I8*41&*V%N$c9r1p8T6bmkYVqFViJSvz4F5*Z
z%${v;;5>^@`)Bw1Od9?g{v@v5lSkT@$|`ejWyW&gw<%O^qYUs{MlZ~6crtf?M-cHY
z!pE`+zE3*^93lK{E|@pLvPffE`@DC!UtW3mY8iw3x`AEEcn+=m$z~_nRR9-F{2v?s
zQ_}vYgx0}!{iZOVM&PuxFXDX`paQ50L19(lMSB0wAc4Fx7=py=z&alyastgTnG8<y
z8<~Q$GE3jAgXc!F5R#0NK}}s|x6rhU_7G=U5kiKnyJR@(L#$XoGAj}vt5KhM2qI|)
zL$QRsGA0BSOtt5UvJm?M3^Upqd7O~++#o+M>ds>~NuASfwK}zOTVWl}gLo{*9hl`3
zTC1OGl^}A2352T#DID^FB--pgg!Rqsvb}w`tc=zX5Q8#Ab9A%c5^!DALPPK^!6-a}
zqze=6AWR07H-tf~jr<@KRs+n)ez@Xm5i@uIW75s?tDpR&9D;Pu_x8$@=Q{;VEbF&d
zRPM^cXr)YGAQPC8eWC;9YJkN792FXB*_jXq=7B%$^-_3bB9-xWW1-Aj#w#&&-3^UZ
z<F{BYCX_*Y9e%Bk<?(76z|@zqD*7-{_t(H`(5&lz27|6M-53CgegQlB7}t|ZhYZX5
zfw^Z`bru;P;w~>vVO(xVb4A>8S>M`%p@SPRLEEpp)cG1)+@U;ORQ6$pjW97RQJA8n
zK3H?vu*apt5U58Nmh)ay+d#f6#^*|FWx0bj@~j+S-935lmu3Iy)6!epDjN^q00x%7
zR5tG1E4LrLilPDjxLRp)jAgu7#=zmhH@}Hc8J9KSFkZ!q!*ZJL?<I}jv=N6q|4OU3
zohv4;>6Sd&J1k#3+d~iy!JBQ(Yv@92UPmMhIIG*-n*?+bSX$;0fIPe3L}fv1+g;wL
zXO_?S(su=+`!0l=ZY&8)1x~V6&^k||U=UZ_`{8GqElb7BiFXDmd_WqGHvt@WuH)9N
zTXD^}CutF5rw`4A#<dE)9B*)p=3<$6y6`Y=%DA0qyUaFwZp_2wI5qzBa;S0gDIr1n
zS!ih!!}AN?QOix){+`_<Q1hgrq>^N<v=5%3qTxOBX|#PlzxDX6kh!pL<TJm5h!?5b
zcS-M^JS~5eX@39ZkAIZ1;<}=I;pcaXTs^qGjWzF1^j6VL$1HFzw0B-sX!wsw+upUb
z^TBs^=%xd+xc2P3R*qMbv<B0(d@o-a<UHF>>wuRDj9Hw&y}%L}3z`zo@%O87fN&CZ
zmJI?d0j;)@YC%i|h^1yAV31B0x(iy+2T@6H8=J}4>XkcCbF_3<Z0Q%43?}Dl2|V(j
zC?+$xhS-m1nocJ1c?VCtL5@t~S=y{GcGLE2fxvf&BTd*5jE%CN>>tNPF&>YyBvJ-!
zu`b8;G~4ciE+G0yVV>k#kHl60`8nfJS;tgW;9R4TE+{MzD7par?unbO{3>C;2lJ&~
zH%3axIhc<2tD&xfa5A)KUwlz^ut2`}{PXM(S05d&K>%wTFh$+-7tvxDfq|>Zv^)TQ
z`r?jfSNohFAHm=!z^1O?(F)NG;vtFp&()eM{ZHvvWmv1XVB#BFXz8ag1NyYGTJAmc
z_>y(TXQ`}jZ_rnSm~$osC#5g0(71v1FaGA=m-pZQq<rhGH_94}wu?}Z18aG>1K%;v
z<T0?5z^-AeQ}Vi0`0@(jwdjI?QoeXv-8#A)-1O<v=qt*J+mdz*e*?vVJJi8ltFYrr
zE-fo?LVOf$wHn0@Dv#Fe=>y&2O3o)+>{1p2?DX)U9PjM_H*r{v)g!qXTgKNm>y}bk
z(t2^{{l?wfC^qBr=_d#dU5X&OtG--1?zdI6o++HJyAliwW@Qwu-30*e|N6`FAV-0Z
zGpR3Kc}jqNl?FyA6<T<@z^)lj8N3?;yDr+GE&NP>9czV*AG;ELo%2(XlNQx<PmU>@
zzMDtf((Q>@jq57+pnQF<2Oq+J7?--_oU!3qMeZDn*UhI_&d&ii4`X!vw2EzpFxIkh
zkqFi0L~B<_sd-}n*ZN6M@eW4vcyIiv@|hR>DPb0Gn_^)CM}PTG9$~wrV*w%0$vBfo
z!I8kTJSV3O@LcCiste0_LzEfr!Yg0<gf>-vT%K$?X~ly->w*~YhO*=-H(}OBue6DD
zqa0ZI6dGSgu~-3?ZjL<!7Vygj>V^(UTbJ>+&bC6nF3i81XXf)^9*FbLFJCSAY`U)i
zd=_3#ZyGOydD>Oq`<z!_2`}EaXY)HaFgS?1&L>b8e-4<wcL~FRj0IvI(q!cbW92Fp
zCBBnh&Os<hB*^3^T^rC0l7p@=q70clNhqSWxlaC7#1Qe5pE~V=ny&~!%`hZ2Dzq~5
z%q}e#+ZH!UrJVfr5Qw@tX5Fo@;<dZ7o&46t<j0wOEu(V6QKXE<N4X-ha~TV0aQTEN
zf?%0+e&0j}=sbZ!Ls&>uaRn4C8??Cb#%7j03tf+c7^8VFarc8$J5QdJCkT<F{R0U8
zylk!v%IFpr4w{VnHQXPedrE6VpRaJJer(zWF}sZOT+J6|;X7APMcC42wbZ(riC$2@
zFf(7~rx>GK4{sx|5%fUbrLGFJO*CcaKb#PccB=b|maAD$P7WyVG@9KfzxtrO{kNZ%
zS6|&MtDcfeyK}S%V<$Y+aMiA@FB|e;-X8CMeC+Wx`u?4Gy(*u6`UQgj5-UeveOQM8
z_g|Qi^GP$T$=GFuQ<%GBRjpW=nT*G|EPc|l3z?|QLATNr#o$UUpMG7T)VOzJN?X+O
zCliPs95^|2b(xkF%mn7(!I28oX#FtAy@SJiLuP#}b8s+WR36tZ9?`HY06-`!AasEp
z?CpY|i{<XUEylsmVuKCRgyjPttvcs(WYYHe3i>d={gk<RP^fsWPrcEDf;`J}dGGl8
zK8p^BbGdMJZ&e=PjK&%GB>csfxF8)#@j&>_2tgXoLJ)At69WJbZS9~e(PqjHQ)axy
zp-JY26ui2zNH5%}?(hh~?EH*nl0Nip9i&cOsp&<K=NKP4<!(M(<Nu~riSYLg-%FBO
zwwGnMca7&+Mss7?AMv#cvs#w*C^$?X1(-B(4RSR_*f|W-T2{S@bM-RcO?&ufUCs+j
z8?U|oTKJ+L0#mr?&T>p5K$2muu-_DJIzk9g2w#`phRYaD)5?7LYVTTT&+Yzod0U;{
z+ttz&%X4d2eNOBwO}+a@*w~M&tgDxDeeXb<K!zmqun*?R1hIrm-*tuLNC#M*hJb_U
zN*IPagH&Bxwcnb1J_ixV5y)9N0D?e$zu4=#cm2<GHIo|!MF`VWEj|<IA_kP;@gmvR
zAo6=Dq+}4Jlc`vygyj1L7?uLgUB9-09)mcx|GMlSK*SWeb!(e$E|ya?I<+b-2`Up`
zXhXNG4Ix&_^tkb58tsR$Tv4P@xb?~_Ir;ViLJrrWoc?H~^w7>1VJJ37!s?P%hN$3p
z8jIt&Tx0$8d)H<2_FCz!uaxe1Et(?0D2Hgw3PuTD*60F&>j1<$Ae0a;<st;LheD<a
zjMNm}AHd5hbQTn53SnSIp3!QrY~8<YCt@k}R)%GDZ7tS^OS#qlJsM@`aT`>1boeX`
zcbRf}!*2PX|HZ#5&v%Z?{YTs7-YfUZu;(sk=ORuRH|IXk&OI=3Itd<S$2LO5Nn*#x
zIWKYIi!YvLk%AMpR|_&mp<VIKG4h@m`WT#J9AtJ1Prt_?Llmy|%Q+fxE6Z*fZ{Z+g
zy>#Ul8oR5p6v`bexJ*>LlO3j*GrklmjNjSOKFxK6!0EMZgz=bukq$i23z*LdU~LIY
z=bvQEwy}#a=#I3I79)U<4;j<06W+jpc4ZL)G@)D9<6)eL*Zt^T3hxUHqZ<;Pi}RQa
zl^L~QKn@C0N19Y&Bi#r)g=YN@x(o{ohQtfh<Kl`laP!2z6R-6WqO=J46z%o0J<=`|
zj5S4H(7wE!ZxnVae{t)OE^Vc}4t)~d@&cKtczT4zqM);h;YS${noK*xuv7C(L8O|6
zD5Ko7e~o)>9?!FQTbOdl6aGP6X?O6t)@OMN%6ycLIE6>}3|IPKTI=9av1oiK`A8q0
z!n1H~{H+O$cD4Fx9d{?xJ6LCD<<YCJWu8s`w7$7omWNn46+ZvrDy$Z2K`(+8w9wwo
z$F<M^(ZbiIc{%^fX?*{i;=I3{zha-i>&5@1@m}-PbX-KDtH7w71O}}@zP1@iYe9E`
zgLA>NmPRBzm$@%=?{HT;u{^bX-9nngY6A+9);<x-P@4k6svQa!p7|F<P!n{tvre7g
z{&3RKl{nxN@15KeNogNKN6l9)JrnV!v2RWbnuzlC;pPxV2}$My5^3Von(Qw*Kf5f4
z$0ucD)vxlA?gAll=~y9xAd*o8Dv*Ks4z;i-$CXbWO`@i~j`n`MyBn=7^9NWEe&W^L
zs;-RE4WRYp3ai~GPjhU?bzDcKETh$qw%5yGbCWzPFe>-2Ow0bxUh&hJ_C}aF$KY~M
z8H-vi96gL#7{uQTQ_?*poSlO@owyNCtyM56bcDC?r%nXMcw6CcRo2$F01H+ajBRye
zqq;RnI^Ng<-oWAX5RhHwXcWH&`RD)Qe=Pss|MAb!pjXNzeS7$Dt*mXVF>b&E<|AWU
z>e^12pqeb>mwgdubpz+g$tet82GA>?eetB6Ai#(8+x9srtY1=sj&;j8i4Tsa<z`8C
za0aHJ%Y#uCABB%c)<-J@2gTvzgQLpic&DpVDo}v9j9FnQ9IRCMC}3s8(<{FgxL1yz
z?UzFY<UZpij4l)$z+Q`U_4WqVOtn5dIwXfziq{nAx9O#Y-Tg@!uMRRt5?332u-%?X
z<)r!X(P56g5U$9GXu&EwCzJXebd{dVYuz%o4`oTk$38Ij;;j9$+&V!njf%@CdAt|T
z4zLR3j~(%rvL!4PzD9e(l}zNQi$WqeBo$(8r{DE=+!V&*gZSvYB5x^+c32)X=z^4q
zA9Z7_8sD)lpZr~E*Qi=<#%^|R@u7Xv#(kxRX1iwbm0#L7yD?+*<|jUulXaSxXMY>7
z5RgV9m`q0><W=^=GHsLm%(CP&T7`!2GwbEO@0tK<!8qG#d$ej5ypxkNgm^#8^|OZw
zMdJChXN)^a0+Q>onM8~R91BcmXN9+GKFp_mIkfaIH*P+(G{31F<9}0}S1bEPI?M6i
zF5~Tk`OH)En-8=VQfN<T?3%qGvg!RlNJ~1IuSbMv3OYbpfkeDM>@!yiF;K!SoA_q!
zs6DCm$QW|I5al^o`m0^SC^3r!JvCSID_E5Dw$If;x?XJlvP*AuNiBiU-ReTqZ6H%o
zLsam&9N3KU`8tNwJE2`NdlANVsA<uf^l=$tSb*W}o`_@%<<8yPXf6WAN&Zqc)`#W%
z7_DsCb>FTtN0Wp(sM)&lO{i|a`fAyH_%IXXp3n5<XP<H3!;0|x;D;6I(1tJ1Pk`lR
zS>9eNgLRqF5X*^nE8sewr*lNU=Q$`)t$Db<Ru(}_ItUYnF$CVuZyZDuhlA3tVU`cd
zJp3MexkixjTauT-dc=uas%0wlxNK0jn)#5r{WPq*ot>9i<C3X)V(@_W=oj~--1CFI
z^0R;QZ_9uG-~HdpzeafYEp<Qc^ySn2@)!T+Z_0=7eFWZ2%4ob?R@S#O)(Z<*WWaRl
z<~<m5EJ5Juex6K#Ur)+p=b-G-&lN1Mg)4C3O0Ck&5HO7SlCcoDYREa&mseRO#Jekm
zl4-NlTjl`1_(=ensuqZgITRF^SZgvog%2;&wrq+eU+^T#0Jz?9V_dZ&Jk0Uv`EGgk
zY^Ur$dtN^0@`PKLtvUyCvVRa4k?tim|MSTS%E3Nx#!5zTKYhAe21`>E1V0X?8wk3@
za_M5Z934C_lgS>qXS*sBbhDqk=>5=^cq~J7(Tj5;h%b~1Xo)L=@3P{oN>eN|=;8o@
zbZ~S6EKs5-V@jNhOx!yX!ONK1FKJkw5C&<zTrM%sl6o$+b>}1d;Es&gw9<ODFla9@
zj;c7LU-y5UJFcW_JjY4?#(+cbvv>1p4DoCbjPu!Xt#<^+EdJ)QT<&#jQ5;BP?q)H>
znxZ`lSXah1t0T0}m3p~19_GAU>Lni!xo6K3{6mGsw6-PvnO)W+zcbhl-z(&4MY(t1
zm5X{@u0!vuYdI*?IgpBQ4yGNnQbW6cU1$JmY1(hY%lZCe-hEyCe@r<o-Tb>2UZi>P
zoV1BkE5Td``Q%T&HeP0A$f^T~PoJ(pR2YbS{2-r5>O@l=&{m#>2wa5+KT@VaL@-DQ
z@y)B5N)!yBiF~a~%Lz}H3#t*xXiX!-P<Xgn#I@c7G*De=G6&5|-Cts&OKq*r^nN0A
z2yqNo#?b()8;-t#c$e3mGDc823A(>~lp{WzWcSd%?97FUt-v5%oumfuSLXWTwbEN7
z9gJ7E)W^U4W%>An56a&29W*l!z>{xZ$0ayeQ5$x`ls2R3_uQFHxtY7M<@8yGlvOrp
zu?n1#-x;S6nTsT&CF2}}?zlrO9`d{CuTK7=fu2qyEUu`-Z*8Aajv6gyRNN>{c&<7@
zK6I!3IC~YW$KCUO#ZN(`0C6rr;q>qS^e@Vv{NMlk@@N0*-<4~>-Us8BaI@2wcIeCh
z^66fA|7Y)%U%mGsmeW4UhexF7)~b`^y2R|8^A9d<)oN6LO-`@M7g%KLTbtk&;~^Zv
z6krCzMM5S{tuJAQuXKm!%4`kRp*zxOnH`7%Jh6ZgxXx*rCrlSc?UL`Dw*@}P79|1~
z8t6h}@M)WP175@It<a6FhcL<m7}LTr0&nM8*?sO3<VnWGGmu<a<?5RrFw~uRg&_Cf
z%6yw1!O{1tj*P35^&Xir?0aCSR@4=6?18mv$h5WZJQp;e!K+J3fY3)RUE!hT?2dC6
zW5nXoy2m;&Kd))G!UrJ${q;QC%RUM(>4o|mPpE$-!XlugP7p5io2AjDi)PMUd{j`V
zSO}Mt2Ywlj?T=-V#`0qAdGVZjxaLEP&zSnmCEgm^-8vIbnc)v9(|q;W{8|;JiD!f~
z5h`51mq%EZo)0h6N+05^&!!h{hPJxQxCjT^z~v$Xf8W51OZc_8q&Ka-2Nt*Q+yT$r
zdxr9jGV2m*c;F%yNbP1T#E?!AEXdH}=R-?B-+*?t(B93LH~-%7@^3?{*D(Ly=lS0?
zo#p?B^}l#m0Wu$KjfS$!Q}oJ`KVbmyJ!sJMk;ar2K|vWF=w~T8!aTsO01h!LH1b>N
z4@@9ptIRR;A_cFLmy23>77o_S-Lher-Y;MVBD4J=L70ecooJ+79wnl0TYtKmpK~bA
zS9tQOS3Vc2kb;T1iprH`ix4@o2^yt+(8R*RMd{IJkHOw~en^W-8Nn3jadvgDZ>*N_
z=0^4f?C+hF1GLgTOxDjn{IERv{PSqjo>jDn);So`u7S%|J$eQB$n2J|fSePd{eF;N
zVoaay(yZ^gxfIg9>`Bm{?fFipiHixYwM5_Rp@mou%UWlC!EaK|VA8r;B%+*349pZd
zihsY+Es`skHg2z#4fi%Uep;K1^~UygOm9E)s=I1BIV=C4|HnTq|I?rRPvzv8aVM<|
zMorC=T^$2m0C58V|0x3a;OL@!^s8T&zx~Ny)3#2z`{)(kT_cd62Nx6w9&Mtp|2%%<
zX?ga=m*wuATl5D8r2u7&F6p3Jb9O1yUYT3^?zra<oFSc1lS#OcAQlTk!a6*(Fq5L>
zk$KcmEz-DU`SYK@6<E<Y>0b`@#OifE&GG85qDl4<%*TF)Rv3bZSQ*YMEOueE)R|*P
zU?RQIYVn&Y&WZI_`sMk~ZoVt;8DPeN4H-k-jUzNvhzA%so=f1<8qKL%y9$hRTo>T8
z<!Y5=;ul=6F5+&46b&X1@F2a@B=*HVX>5WafrCfqD=?c|$1zjz#`Q}-EK|I@qz;*|
zs|X!WVLDt{Ngmy(rgt95HcFR1A#xF(GGbswTr31>);hd=GrQBIn~+Iz>3EjjcJh$l
zrZ-2;Wwhhb%H*Hz<ypFLRitAU;lVhl)H;sl%{NSdUCN;@akdE?+m@Ak!jv>x9hPI9
z?PztkkT#iz=juXy5fr}Gd++{z6oF-wT$Q!i5@$kOScXWy+!-(%L9k<nbZ#!(R5*Jd
zq?pCM9NIg>%jLB^E#B~T@7i;_TB!MK?|=BdYIHK=7gDw+XCV0#adhkS5eV6ANIKwj
zBdv3phb-B|M+j0%)N}7FRFFF{iv+4^h^8fRXL$EKq8z_Ke9Ud~IHO^kLYQboB8Ki6
zU2nF9hguGI{(%6tS}hBNAdkNlgK8Z44GcU{G)UT^d<2IA#>r53k%u6uSNE3$=C@Oz
z+;TLzBwZ<!qtp2Aug{OLG<M4l7RnBq^TGaJ**iKa9zlKt(JjDyT!z^nBQ%^#p?;6B
zxPTFc=|Jr6+pzI!LH5@^Nc&Ex))ipxh(DB<2DxQAPHL)kg6H{+uX8q8RYD)N2%N;b
zM%#}yBa&056Y9Dj#No&;ECt6+x5(DL%`(zYThPwNe(PaSwr<_dH_kV2--4kWl>g)Z
z{{K*Z`s1IM0q}CAn#+mZ*(+pq+exIl7N{U|F=}l?fVF@Ce}?e=>%aP0PL*|)ihXqj
zmTi*Yw2VCH(Lq;$Z2LJ~xL{@E;s6#?2TM!%fL_jR!6t$)T9m;ffaZj?t}Va3=%l}!
z>a>a!lGeGhz8>Ksr3-sE+&MqwDl=(7*N|4R8g<-!4vZ!#!97K~v^+ZHc>lC)-bFZ!
zu=Fx<4HMV0;PNPvEI3$O2`*{9c{=a&Ctn6fH?j84Ce9<kh_BAe+U@Of<cFvnC&nYL
z)&8*Dx__@69UhT`_JA+`$#*;}Ojo67U)?vZaswt|nDvaR34M)QE;0gPPTEuYso<~?
zT7b?^8T>F>UAUl|n)XXGfit*E`7WwZct~e1E8pAS2TtIXw80fY1H8_lk+Tz+a>mP^
zTDCmE_RDu>$|=uTvFSajWDynbeIJ@6E=p;Ao#1=hZ(3m@EGQ-KA|QbKNJWsgWVIn_
z!z(D$e8wplY-@NN`HYW{p-k(IB|{o%L;+(u+Yyd7%VYcPm+4JsPfh1@U=8fu=i~L<
z54@4d1vw}@i?e+owX^fr*M$~e^Zc);H@y7bXY;=tTDn&D`~du>JT=a=_4j;et6k>H
z;9mtA5D3#jyY=ux(@A(oljCR}BCUB^odP@q13^+i9UMV#*~A3sK4W?4rmA)Eo_Z7r
z84~hVDA3qY0r`lQ8K@<B+HTUtrng-4RfG_!edQ7JZtAP6PIRr+C4FkHeS}w6CawlY
z9mxyhRb!B_BtE}vsQbWrb&a@_`r=e=o4d<Cu>`FC<oGBIUc{L$prJvGgTVqs*GKzD
z+5op}SJ|lj(KcR3yYb^d9#^h)1LXoQwONFY14NsJx2LV@UWo;viv$Zo?(dkm$xnfk
zPsIWsSH20GGxwngIrC7yLL*waee+ER?Gi?q<7uc%q5SBzM=8stn|@p57AE-i-P>hj
zYrXvZr~j_}xBtz5n=`@gZlFm~w<~ZwLf?53Cs-X*cgnl!MS>IuBt{nwC|o?U-pSRU
z{Mk={_GS6z4}QCxpTLNm!vWUrN0Hzi$<IFiBy%rXf^Ifcu~_aRfGIaZii;=eMCTRH
z96RvEvDZUz2!rDn%-q8o!71Q%c(@nlsB3BJoQq6^d|BQtNPt7dVL(FLoj^|=0@B~&
z{@5M%<9x!@CCtMOEIm&@R!FR1Wgsxzx8xoIkFxMwD3^ol1|1<ed*h|@?6c3ZQ{S@B
z&i2avS094Q$7T1+r|Cnr?ib6>&NK3QD)L&HoF3!@PS*&I9QsI;&av9G05ZP8A^L9n
zfkBo}({B5cUE}oBxeDt98j==tfCeF*D2R!O(qsmaoiZF_>r{B?!W=S&P6kVNx@8=z
zSVPh#WxDF@@DMy}ya0F#I)nHep5i5~b8o`LG(I<GoC$S)J3d|!7Q`j(>~8Q@^I|FF
z2i7mbLVO4#=bd9}5ckDLH>-wTNRwc_#49LFpLTK=fAgAml`oObxLMnL-`eBv+-J|W
zR|QWu=A%cC>KSb_tDL?qJf>MBhUjEUR$_szu$Qj+PMfa9&xdq=F0?c+r+qoTU4{T`
z_B>x_3-j*`H07mW`kJQYZF$I*=P-TJEc@{q04^hQeY0A8+)%STZ4j!f&q1IZ`_9kQ
zZyNt%#ptpktqFN2bJs7fz_5A|T>`g2nT%SoWx0t@W~{44gja)){}-atZ1?n%nBvw8
zA?OxTC}cjydMQ^EUm_Ao)MVAv&u8_Tk0_c{wNY1Bx#r&0HM+Gt-okchUAZrUg36K}
z9JFiGW&`BP2o_d_#X0G+PTmuJu?hqY-AR4fy-gcbc12`rpf3K0$x~$*wXU7GMbMJ{
z{)2!Su8v6wa{yTdqN~7`bfF*^>o`}dQDj$J%CRQEQva;`ArX=J-i7B&NocRV^+w)1
zkKwns?>u}^*4Ng{FaG9d<^TMD`oG3qd1rM9gAg!vTvoAAV$neyPOkgi^wdW`Bz_4s
z^g*0%k11`p-#>rv{j#<>D8KvrzgG_T_7E&EMaE?cv59q0KL3(3{ovCu6QIsjSdYhj
zoMtuL8E_KE(5M0C)dF{5B&_0E5sr?T3jrwO<kWAC01=t#`80E0j$h~ooCrQLM()n8
z!b6QyYqtsx0F*IV9<Bt|e*9{*IYxLcV_np9!eqcMq{t-s0Ab-=8A8SHsQ6tJ)4FJ2
z=Zn28?H-Li7fpBO0L$cQwG4HaWd~jrz)!#UqHJxhg^_ECsAyD1M3YG7iM;M5loxqy
zi}@Sg+Xu1WRD>oC6d;Ka?29yNueH#@8-!&nb#Wb-xN=Xo(w)0^%Xn=q4A_rY`C%mS
zNPKlM$I`NNVL6n>`0VW+Q*SNbkm?AHr-Zm>q2j3R61<K9!8k5gpedYgc#7``KF3{c
zjp0}HX%;WMyemM&zrcw&&mq$y@$_)dE^9&MHY@*TZ50=StMz4YcD_v8(ykV4W7^l+
z?=zP{e7_6)bX7XHs!&l#&ccgA3@uaZunlPqGt9rA4=w%tHJ|3?^1SR+d-rmAe^;2V
z%K`AJ*}q!nZwfh#P%ZWx?GK`r`ARU=8moX;gK}R++yaytji~jD_pv&-yZI@<NpB;f
z{Ta`5L++HvAjS-*xvpqXvvL{i1mPttEVtEn0n*qF+Z6W$&uWipgQe+1Z*@ngQ3v-B
z0L*z&-?Kv|G4k5_!H_T-wKz{Vb?(8<if#h5v?T<Idoc3hqTX`pj>csw@xwHx6r#(+
z6<85)5bGu7oq>!~%2EfipXo1YL{jV49U_6cu0CI)qyIAf_~J>cMlU1U-`lTdI{g=Z
zZkp>Yk3z@^=?u*mUx0z$-{FcD3h<^i(bjDN`E<iLccLZZIZs+3qwz`@`Jenh|9QEB
z!EeAUPW)E66T2|y@!F=PXTE3m$&(ybC_zcE_C;4)hr1eOK9P$Ct0j={%1p1y|K-2?
ze`Q(hy+>~_W->)uL;8LXt#^!-1I(S5lEIGD?z`@tAkGB~9{=KCGj=YTSVF3c3+;nS
z8B^=0JvpZT42ulGrvUP35QVm|bCAU&aXT9&$z$FcD&C3P{1^OE)A!>*;@@C>6=5+B
zy!<xKU_dztvZW<gB^E3Y1PIL8kDR$m&-p_I`gn7-OsV+ek3K3c@!s1#1h<D}u;Qne
zRU~EtUs}V$`qeLg1wQx6+Qv3xvKGdu(98GSd3K_HX=%Vn2m`DLVD0;0J-=_<)$}MU
zm$+2YVhz~G&>)HhcjshWCSMmr^lmH<gGZKEm{*J3e4t_I%mXX!TX2oKh)M`O^V?ut
z+VFQ=GFZpMdZOiX<(aF|d-MKO1%B2qF6(NmJ!>CTo`iy=U|JMU6ci6SjC&hcOItE_
z`=o`hrO<?i^)+Rvwc(~O?YGaf-)SGu)-Udx&(GPme722tEMkG!0qd*`Jz5MACN#7R
z?b*;8)Y7&0h9(e<o4*<$+PnGC-dScVucetUzs1j|c@bxus`<yin=qfg2A{csj5!q*
zFy&YiH5Z<3i>PN20!_qnlF)9M-XkVROh+k6cu`hXW{|#<RW8=i>YBCR@itJlOh7G;
z9!ILnaCMWY9r^(m8>hCb#+t$B%7!kG#8ocFX^y+7M6${^D!5#F=?;4Z0xgOL=>(?z
z6_Neky5F9baX2BjLK`M%fdd$W8l{?Vh>J27`qW!`SVfrjr)crS+up0L7jUDzv`HaM
zpJX6fMEc4V#$kHYED~$gRIONdmRgXE2klxd(35q^?`o>a1ZFA0@JCNzx~?;?pJ>%8
zQCK<ws#fj-gzScO4A5fhlEXz9#Q(pvKLL_#I}h`~zxK?mtgL<OeSaJ901z7qfEz%O
z0x8R)=!ub~(1bNHk{q%pEHg$kBg-05vK(@Rwb%|#j7FAbw1q~N$&p2JB$5KS0R+hh
z5ZlAs-|OzzTkU&gWoE7OegCcdI=j&gLE+PVEAKt`+;jf(pMO1TB?oou^}(2)n24>7
zEnpgm3s<k=Axy+C{<EKr*S>iZ`~yoHWo17(mRujo(nW5<)8f)%%=IWJ4~36PL;;j=
zP`4b^r;VIWY<pDudt$BGiG`bY;s<{GM_}ZgINWPePudX}_jWcAheHTW*W(;!*OT<3
z2dU@e)YNP>6q{Se41puZJ)B+U;>ld}h(NDZ$MS6IqbAII0$qUbAs2P=T?z*k33!Dg
zQYqSPB`vx3#POk_s<Z<QQC1J$=pfHqJFVOsY7CEJbgT{@9Vd{UpbHeA{p;>JtY??)
z2uz2^`#F)}!Gn7_t@-^Q{b=02c`NSUd6)9Y10K=4u}xHR*41$#yCfZlSzq6bxtTd|
z?zmGY`Bpk`M}pky1wojCP8!ERu&Xi+D00%<c3ORQ2T4^Y)GzO#33yeCPYauJ+|DPr
z^PtWkC(d8I7~8b3-jNEV827+vqg^$q+R#I;#X^ZUTN-iXlmAZnnBNTC%TuN7>Ap`n
z<9o~W*)ph`L0U1Nd`Bqb{e-{yj+Ysc);-Uq_hX&Bd`^$j_C7G)<O9%XF-D@~%Eh46
z+wEmElEsyICSJ@_xQaqE2u}%b%HmVFN_lLMu6&+7b0%@>Y{pXsQe@^!f4d9lzRK|U
zv!VOB%%}S*k=9*C8Ok)i>kh^lo&=BK;cxyuy*KY~|E4VO;Wr{mmbDQNV>oA!fFuws
zvGoq<vODFo8uf-23wiK26%<UN6_kjUV9k@uK1E7P>zkCB{=IUDDh5rl;%rzg{{w^)
z!YK(<p=;wSj1*4%ChVsuN&KY(F}^5YS6w0DCVdj746hPYxoCA+K3`>?&fFpqaKLnY
zlV_}B8Lw}w#UzaE;x8mcDz_dyBNE|RL~aqUw8`nIFsQRqB*Ij?)|q@|K5Ohrgfe*1
z&I&IT8^5*(xN*HiPMZWqtt)3v<>UnN5l#|iJr$xIgzw;>Gh`4dcrAJZ4r1H2;*1{g
ze0&0<ledGt)?Wo#433V(#DtdZKzM}g?EIOy`rPyJ&Z{rSzx>DlGHT$w2O;huIiurP
zy_J!4{X5MjWf$u(Y$MyjE=ZM%zwST^8>R>1tS7By*JkKVA$wwEtQv3KUZjnV;-laD
zy?HWTu9W9xtLb_cm~VbM_V<XR4c)P~-QGixxdNJcItUD&`rW=AOy(wo;3W5i;#py?
z=y&D5_{&*&;JBpA>=MHowbgA8l}hflMOnU6xoYKVJh(ZcJ0({e!?C=$5|=NYiHR|k
zg^nl6aA>FpuLz|>T4(eDEwCNL(H?EFkJWpKFhS|uUt9u*<1sTf5-)z>#W;j+Hr98u
zZJV1L)bTJCmM}_xPLxmpIw|7*y}RlC>lL_jfMX9mgYpoHLnEfgu`?H(N+Zy)v`!v}
zC<ggdp5X<GhdQDRt+iXQIJRf~obqfJPwt2<FM-?3&pw+|(05S$dPMHs<|d`m&k?`<
zp6h~ll^(hi9zbNmPB4u@+!|6bC#`eI3+BTmUnIYJ&+mJI`xNAP`%tMQ-+LoX@Kfex
znxbvx4f5l?w6Dxa!`FD|LAd1aJdQ$RjrPmkkICN&A>upNeUOJ`72i?ZX*vFup<8jt
zmt|ctaIe=fF+E-If_Nq2&-lK~sH}MTYg~5$-Opvl-S5lL{jJyI`T1Pl8@lfe<@?9)
zi%@=BzBBII^DQqMs;raGrY$bvm*`+dEcHRR!9WmbS=!yuhif5G>*nWq2t1b!z$XYU
z^5dVmKo0!j$^LY{HI1RDGYxDvi^3nbLCag=07i;9K#?HK$Mlw=myi}10@N~!<7Nx5
z#4Xs7mBjH5VnN<;`5tD6fIKWKr64dl>qJnrbP?gyPho$Yr}t$)I$+PApQXG#ga*t?
zeVx6cwV}750C6x_>nvwKi4(h?fZ6UDm6-&bj6+>qbf}UP*U1pzK84und*fXH(IL()
zS5lZcQ;NEoSFWBnU&^o>L+pwNt$sIv8$_t<5zsKeUI<Ii9Jeisy~%(DgpN&)CeB<9
zfA!fLF*!RC|K@-G=drxdjEP3E7Q}<5^d=Q7dK!*-*fpi{uz_W!iJ6&bI_rdc4GQa8
zZ#00-nO2UQb+V3L16G-OtgY<E2R`t8G#Y);+}K2cqCmEtMb(UpmoHFG6SlX^PHr9V
zbY4%9)CCboxdjTB)OB<sjX1D-oW_jjo3z|?()QJepiE~kIbM`)0A8dC1-10#Bng^?
zw9pi=x(z=Frl=zXcP(Cj<u-Zr#?@<6D9plJbicB|nmvLhk}eU@o=fi<4n18bMI7NN
z4Ah5mQ^H~5c3V4G@69-W{z^=rn@)U>O;6EYLs<E}u|u7=H@Bm`+l(gs)K&=)zq-AX
zi_)a0J?SFPSU*bZA77RGp4i@kPI*FGQ#PI#p7!WyJx1}GN9)xX!P^`jsl*tb&}f}@
zt)VPY0`(!hSPUiiZ);J$2V*(oDtAn<y=gyt5RRai++DzCmqfAVow}>#t}&S21?iH`
zx#Ur4%%D7xPNesO*JX@C&g7I?;*2j9hw<`u$|UZk`_h{*<eDG9O<sGL#_w{M4BA~G
zjszf1g{Fb0T+;Y(oUGW%LFfwOs>oZ~kRHsptV7v7SJb2kscek%x9b~&fAto}@Z{Z<
z_cUJ>2p<R_9~ivv{(V|_+WYRj${-Nk=^uZ7JaoS=@5_o9vLBZ!=>eF`**-p(-}qZz
z-QO2+rZ-ih$JA*ZSBJHhv2d`O>|@rlZbPs+-@dIS$A^@wt6e~1`CLAkHw5oxy6&<q
z%eGQc=@RGnrniB}GOatIAia%}#KgTgba9^>2UcC->%GGX{Yo0@J<yXYsVfMWBnX(m
zU^&J5fx^0x`OH(Cxeb9^PYev!;?_Gi<NW1IF+Md8qqZR^thKbd6(kb<5KM-ZudoKa
z=2&#!kuT3$vkJU&mrqlqLQH%*#nklxB&06MC|oLHr;L_3ltKK}8*-m9!L}NnfJO!L
zy<I3WKzdE$492#;j*%$b8m=#Zc^oTp`m69wO--a?G4ty$ynrIvjL-dx&&MdZbb*@!
zXb2qGCFS<!hpkplq_7Lmt|}0h)}vmCgWfWo`)H{=oc@`x0GC}`0F#5<DmZJiyu606
z>WdG2{KeQ>SfqA6ImLBzbuBJjy`0|Fp*u12FK4T%+!55CWg;%948JFMe^dkl(by1w
zH3a1TE`pr0wEi6XaMoQx*M3J^TYcIhw^6Uwfxiy@KzzL@8S35KJ%|N7j)kS|xU;Yl
zw-?s&+N$yFjk9U3=d3!t3jk4smpoG}o+EQ$wa-@QhY;WjVHkz<&>!D)PzHL2uCqCF
zW-iWMxD=PJUW`juF2>pO=hKU_UEBxGcDBYY5_DfBcVpgd;*DuE*((5^Jwfx_+37fU
zem>5hI};Z#oI^>?#?0h+jEtfjs{N#E<iM^|i{%la%e?th!|SSGP)YyNOmlZHm4}<A
zCJn++(viZshjiLFo~JIq%SQ#@6nvcBKRg?x2O{57BnAbtWhBmc&aUUv_a(n)LzT2|
z+I(B^tXW%@`5H{0e0`cn@*8>TdD$gtc^==OqSMopW>g^dKID!F)L;HLm_rG>;k|PB
zE!)`VlpX$()=MQ=*2!PJHVrHn720)8{ri5#7iN%|l$m$^J}s05cYj}AkB7(O-vjz7
zq5HkRR;Cza(qfmejV~(89rwcU<b2DxB5e_T_ItneQb_9dy1Agj&xK6JNnAOl5Q|u%
zNzI&J@QoYeai4wB3UTfg?B3Xz*#N?Xm0;tQilYqKFbZemfW<m^uN9rgT~c4Sm3DnX
zzULccJ4B*Kg5d7e+IJAw?jqo#up~r?C#R9_yHXeepso&X=8n2pv92(0!}yy^EAfGk
zyjb-4BBb~@`%Wc1<$fEb;y|R+be&N|P6##HftRj4x6A4fMeCXkr~kS~l9sdc`}G=J
zk*!B!@LY!q0!Ir{!V_L+6{(0^(R#4&p;z|v7fQofQ+hxkQI(wC9J2@@8Dej9GwKNQ
zvB|MGLbyAtMncanC!hqZm_0L_zmqf5F?Zo&eCrFp8+YHh6Vs&4O$WiI?R{j|7z#w;
zuL`t{of>I7o1ZJ;^)&SUCSV%dY#&cTfi6zl+-t?!r@lu$9AtJ}Xl->lKJ)MY1o0>*
zafIcza`)Xhd+}o8+D#E1gtqSX)tg3|*~cri`&4?$-ICn|5&Bc;%D8#~dMJ8lp5G1_
zsUVz4AQ{<(;b8aZ_yo$(aW&eKdJXheVtH{r-nhFG+ilOEaTCkEJgdG9j?d1G#^h8Z
zcGg$a9JDliZM)e7(2}sF5deK0>5T*507|0M-pfrAHRJ}NL*Y5b%RM<LJgl}`pWsb+
z2;0oWSX{eyEw10Vg2KAS{pEP>`5W<p7hjBLZaf>$K65o*eBpXLf8$a-f1T@^O6N?B
zqbwSD7H(T3T#lh^(JpTBu94SC8g#1_Ck1qJ;>59=fZ7$<IgYKZ7I-_#ZXLZqIdBl;
z%fWpoh$)m+4t6){5%1tF%181WOzGc(M^A$^AdMPV@NnTNl!D%8<%>L;a))PWB)tIc
zZ76d~8RQ42-xV^f$fuA`#l5gdmk9y9Dc#x=P>e0Xo9YM+J`F%<Lb>L*dMfFy2(RA@
zZ&%*RCvK2YT-2YZ48Aiy%Rl|D{3h#4+yq|8sbSamGpS9>51;V+q);N%Gy>>v_tlMX
zgK4@$3DncV<L`ZbSWY2`AC~hFhT{2A*vq&wjlrl=f#{Z-W*;J};%%fyhG5RK25|ke
zA2*d3M4+I~a+J3UOwbNNA48~;g<UB!93|wHTcPkxIa@0U4LB?>OBW{cDC2A#2~7cK
zw}cj!ec-}c?5xX25R79XcC(pl{xd&?J%pg(c0rzsFfCQScN4-Kl;_gQzJ2d@%+Jrp
z^{ZE62kSiXLKU@$PwZZ5x3JVai4Ip@LL*+mpnwntEoRX-G*CrwAcXkF?Lr3eT2uzP
zzQpn&b{C+D3wQNY0D^&3rYg5%l@a){{^HHLA9URB=m_shYqgpdzci{KSBMz2{7&r7
z+1`uk*_p(J_!%7;h}PCd%$++Qjj_qx`ekB#CVu1RKOaZy8{vtH?txaEtay-XfO^T-
zbss7%2iomMtMM%Ew5T2Lu-nXTE4`Br3TF=irt%Obke5QpAX9mc{Mu$a29EdQL!bI^
zG}k@i_7LH`mJ8{mH@z3VroEkA@ZCiZT<FoH7ZM~+^f($Lbp$e&CLWgxyi#$C`lH0P
z%&!Niw<kTh;(L6&fnstSmCZQ9NxFS!CGM>6Cf-zr!fcyVfYtFhC(4bFj>O(BbwWXC
z$EU%BHEZ(&Aeu^HX1jqmto~!Z-P_$Nx*KWdoTYb2Vb%o&6TL&Z&ZpU2kByDhxc^`&
zHda<*Wn(?IP%PU!+p*W$i#?Q3+s!Pgr;8&U3)*dUV#{5ep_S(5b}X;0#m44VF8H%c
zYm2yD7rx@P>}_vG2chq#e|va$N8rgF9NbAd@R)_o1*vU}1-aO*O*HK4;K*^FCh07*
zXTURQ>>)T6n5Ij<Dg=0WrBDYc$*<h|o5Gk-K1<Jr!n5EVzvfvOmBnvq?W;IUUi=o`
zl4U22kTz*w0S|si4o*(LH!l>mGNV=-;n$uB+rr%jiu_5GhE8^&ac_{$yfS2lz{~q=
zZ^|<i@}Q`{_rg_lVHf#MPEF-{pj05fOoVk^PYb>)Gkse6C%u1Knx}>C_ufAmif7*!
z@65kwFhd#No&Td{mERZN`b=t&a{_aLi<FQO0r@1($=`n>k%lyH8Ob!hb8w44d{^XY
zUI|wh{32fB%IETLes9oXArI1-7g^DmZe#7VVidrs;PQI~pF+j1Fs)Zz)!ZGGd&d;C
z+Eekth<YI^F#F{l&~~uhJ#2QHtvnF_qaXfAxU{V8+1oI@LwS~OAGDU8`$Q>cU6hrU
zEY_I<2+$%ohRkuDL5N&NAPr^M3J#o0jE>dxIY2|b(j(E6ljuo<%t?z@jQEXpvyKj8
zYpvTIqV)@9=k(j0ZjCT9eRe6)7OvlML%e#OS|CXE+8of;Bb&c?A-%UryoRmC<#_$K
zzY@a;i|SA<*KRl+_Xy>14vSbN;$XPlQ!Wt9%?g3naS<6S?@!CLTSZ2cnN24w3UJ%V
zXO*qz%+N@2=gqg`(|_=XVjujrc3ZKryp&@qwUJ>ljc|1Uy{MC2sKquNv>lgTU>gs_
zy{N3eYcN#q(p_QU@_XnpuZ{t^9~ZPqyW530IW<X+v<dCMySW=T7q(&p3*9vldGe-p
zvMlofM>#13r7$}^2~>sfb5Q<J<H@?}Y4a_qd6xbW!U!y<pPyi4XvUB-X+T`$=8}3T
zxt)t$pyqQF9tnGh_vAR6U0+^~we6A5PD>ANKXy8Y(Zmzj0cSfN9UyLj$Em8)g`S?<
z=*Tl}@aS14@)sawu#Jv7!f+B3(=#aj{ycCj>qNaBf7D=CFt>m)&o~+ELGeKE@J0*o
zEENZ7${qt{M}ZS-DmmLu(tLrdEdTUA<qY?w3`)38pWn-mD4)e`sWeQN1Md7U^YAM3
z6s9yT?dIj*A-J=<DwPp<&q+Dp#~m1)DMv1;bo^F>(eI1dZiSo?jx67N&7UtcbjdKk
z$@iv97=8ONSoRcjJcc*_L<M3fGkH9e?@Mh}K0h9OpU8Sjn)2P#LihXfzJSNeJd0n6
zws;n41$<@N^80VkN5q!-<SRk}uV(eY5coK4Y^N{wxzY|C<$4R^Gw@EKE5mBdB=Qsg
zltEmchzAaAqylc=`I!waVfhiTWFr;?Dx=5%MYolngJT{NjvvCvq*d@Lq~OQQ(6Jx$
z7c3QqO3=YIXF-V)g}#=FR*3?85Rc*B-8(Tqb2gs2b|p5~7Ypl)#9)K(RUR-FLQtz-
z_{_t#3^JhIGrUNJ;>3frG+}1VW<9AqYzZ&K8A7g&$kPk?HoLOK4`rmF^bX`JXawG}
zg|7{>J5_m5cbu}a8;klmn<NznX%y(PoL1#9LccMJhl80dnk?7B;_0(za<8k|3m4=5
z8@FTm_CnN9Ai0Ma!hZVf*<1xaIz1gDV`J&%m~UFal$DI-1&pakfWb6w1#j1c)Rw2Z
z0h4&~@T`Q3cM2u<l-j}zxqN9R`|ni*+p8<N9>qm}Zins^OV3wH(&3N7!Lkss*`Drr
ztC27Rvsz!fEcAl1Eod82>>gzN0QWv^)*sVzGwHP*P@W#&Tlb3-<e<{T<IwN`_~jPI
ziLabp!C%^*h>PbYVhCDLp*XuM4|bxhXjQ*1>>b|8550r#iG=4vyXQ)643<0?i!vYz
zXc^-ICFgYIIKm>PE-tif?z^M!ZW=8rT*n$*z^l@<oA{vJq|H$fyz4o3+j-JariPTt
z!`1gr;;`SWF!Y>lC<cI1ST%U4pJO5u9#{rE?z?6iDfm<%cHg>jqNKcsvJqAdvfWmp
zjO1|XJ}>Um6CmDadC-tTmn#MG>9hQv!FT-R_ygai%;EC6{HBmYzSFybH@MIA`T1$y
z<Y(E&3%_e~Y=b=8MJOpG&o_|}xU7GUyMO?V%!CPg5tghwI5p2K7Z}pWgXT1TT=j3)
zAAksoe+xLdOy3QcO1+`SKH5-Teft<lcPQh_cja%1xTgi*7YO?HJPqIJouT{v;}s}`
zf5z~xgzHgwo|JzXr_%ZMcYII2YHiP4u>Vxe?h%|RsPTyv&S|+33I&?CKvBXa93VcK
zyND~SjC_$PDJUDC9P_(WSawHoIsTyK=af>DmjtUomx$8ifDlv^yyR1I^4FXtB7*7D
z+fb;%AzJl?B9aLd888&C{KvlUd!tqvjD`F6@>{1rCX*ouC^gqa6l*t#7cTNl9HUGs
zdNL{{o{iHocBYU7Uai#9N-q=_ijXo?M%HJaytRU~P{AJMN+%Gsb>fmI9JF^k5vS{l
zL%Si|Vm#-w!vN`y6My1%C<q=3r=EpE@dP{vUyoXyICJ$9f_5-Bgj_&@4E9%YTZ;iM
z&ncg~crm-1j#WzJ=XM?nZy81fq_Rp6gE&t>w7bhSDt7;<#8h4?d_55ri`3_p3%AHG
zcQc^Pj&|1K{U85uT8Eo>LRQkfxGcxhAluE|WO8X!4??^(n+VN=lk{5b)1H7)kK1@n
zv{6O6qt3RCU2BdbITNf}tHjLQIM!x0J<tw<_?0&oqlrcBRwT4=PFuE{Q6+Dh?2g3{
zP>1*T9mS>dbF>TiLnv7p#ivx|>5ASY?eS0Hd_bC%r5*RaQuuSB6ct>BF=F1uIATuM
zhL7yZYys;L!rLj#c46jm2!|MIe4+St(u!kw8XoeI?4}~j9RZ+qyZj&;Qo;g!k;=q7
zXc&=LjDG-wyCW!r@*pw0uYjQi9Tk%S@Dhg|KkAQ-?OhaQFGk2P9+I>Pze`^-3%}Ax
z-gB9s-}oy(N(aV^qxbln&@Ee1E~Km|6pYZC);!I}Hb}XGQ7e*-Q^-pn2GeFBeJ*6B
z%)&zjKhO%d38z2^X5QlYr;H#t1|n~nkC%BD<sxUG)l_Pkve;QdS?BwdPQD;hjRN5>
zVUdUJ(w)NiN(EwMendhq6PFb<_+cXAG`<j?MX`qRo9_EEzwUJ1;XA!Ebieo4>tUSt
zrxxN<%K1)lk17zGR6z*LSnlFT{nS^1_!Y{^wG`gC#e7$OTjW#V%d5cE!)N|v&V3L@
zHiwFZI8awGhr|NGr*P*!`}76JzZ9Daf%IBbIgrUs5}Jf7>?G4AwsBo#C5#5g4h~P8
zKTnwur%J&xY_kaj=ezH|n-=Qk=6dWPBu7RkvBs>l+ivXV@wZyC3U?V%n6genOSuXo
zhsE96LWMU#Ii3CEn4F!#;vb3OkzoX@Lg&=o=H77>*V<Sar=5!6Jio#?1X875jY{uO
zmT%S4Iuf7eV|uD4Bz?fsK)J&nWPuX$?DC^dOw5kP=;TyPo}G_=(m0qnd*M8F8;SPj
zPTcvumw^>w3%>L=W-eUFt;kg#D&g#&qAqraxfbL-W&>}IcR1rpc&xu|=zd#H_f@z!
zz1Il^?wMsbSSmLd)|p~(C(7?I-uICg@TMxUwX{w?Cs7}3q{XfR?6k!<Ry1%sp5%C&
zio+SokQ`QYBdS>2{m{`+_HDcUeX$Q$j|%yq6~n`WapufyjMZzJr_jVfy!!fLY&8#J
z439%uGBrLDqZ6YDV9(nxh+Ns7gR#Kr6xb^_X3`jN7LwjaaXyFD&_lKEU>^77koq6B
zQQ9bvJRy)4kw)MQ^0lo<m+jo2MuXidc7gTu459#`35dd-52SI&tu#(tVeSNr0f=3t
ztl{RwjC~ZH-81rLtvV8$TN|0~<jAp`V{nL~*Lo(M@y94$K(X*t_zF804EpOpwnErh
zU)H~mHnCeb$M%4s*|Cf8RBrHVHl=)#f4roN^h}6@JTv6I^lIC4Z!nKi;O2N=*2%F{
z@-RJDAw$FqWn@}#K|Xr8CC?V|@)PoiZ_-n+;S7SwYfr6oyZnJc_!GrwcXm$MCVy!*
z6`1hxefDyYm+$h7b=t=si=(1JKnv-SOD;gQfb7wrjk4at&G*(v!Z>&CVxd6H%&QFL
zefjH$PkL|g-m6Sg-j|^}ZFhJ)&oUTae*gIU?tBg9`!cWYJiG79@GxDs0x@`BT+mfA
zQ4UxmfYa3{F6YOa<WUgb3r1%SG6Z?6AS?sa7cVk_aVjhBO_BE!O+h$3LJSIKJO>C}
zi_zJv0~Oa-NW{myukp^=HI8c(%E5l#93WQ+q8t=1_Io;8!{4#-F)Xp+c=ff{<Km@D
z@u~0sfwWYYmX>05dHHmnymRCCQh5mQ0YXIL%&nVG@#Yrmt|x(NNLS4=6+ZiiJ#qHT
zbd1&{OazaslwnBqgThBxWmNHRpEn}np;e|Om4pk^fCsxJ9H+@Cx#C1dhp5v#gK&q2
zV1R*Rgy=|Gk;C;$%$~nQKBgJUL2m~ZC+DVe%IN)<Uyt?sTQP!gwVrlaIY8cAT#WYm
zdUic|>Besmr>7%~GziS4_J&?ySUsX#kVYNyP$HQeOsSL<B*r@<Oph;DuA_+ThV%fh
z^H}zylcTY-zCl|KL}POLlok~b5CgQKBJ;GvgH|(kcXzTMUu86la_mEBxPx&nlC#T!
zvRj?)XtkR;J85ciBI~A*lHuREy&CJ=t!U83c8}C5y;%Q|1I(_WAlvkC%JBfl3(iiB
z#Fe>8JTB^w#-Rw>1%bg$;sN+hPVCAZ%)O(WI3dir7g@qJm~<}13tz%XyZfG+p;i2=
zVnGlkEqQ(kN|N$q4Lv>a?gRnXY~)!n)W;o-9pm#{b-Vr?<Zm@;V?7}9D#q5JC}5Oc
zbGKpW$@Vl~gX3q}4P=`VS&Sn%^%|oLAacta1nGMU#B_XD@MIx)OQD+s*|s@#EQPyi
z(re(o?P@504c>_tE9^Hah5{D8=cV_`8dK#OCxY-=r<^M5d&*D6Aq>J}`F!ubWes@2
z^=jgKVtgVe3+QPHSC&V72IBlSAuE7Ndi6%7ARM_PvVw?rhV1Ug=&?H1&nuM}h@6`{
zBOJwvgo!L(79V91?>!qz<aEcCAq#%&ozKQUEj%r+GCb|Qaov~cy5r05p7j00cTZCw
zr176x7$mw4hy#d{i9K8yZ%V!`@m1#I-&_NsKqQ@)>Gx$CE*ml}4N^Mroy0@Vh#eTP
zAVfaJt+b28e%GE<6qTVWja<nA<Jxd72`u*{vOga$$%A~V!$VQUf^>V7k;ZV&Cd#wF
zxt#vGx4Rd2Z{CS(SFXgzKJ~F!URuPmZpTDpED3LWdn<|0siHET#3cc{Xw6_1QxPfz
ztaH{K0!F~pYV}xJUx;U~UB%k<$W{anjA{3gyezJT-L)b;;PRlgoz|^zYaR7tm1+su
zHjam&x?-60dTCH|;zj`>P{L5D4)7k!5tuw=Y8+uaK0BR?%{ufS4@7gb8FQD<gy(X<
z_OCu4&DHJfQ+K>%WMU$A7Zy^{SPummjTtST?Y>Zm$xJE|<5hI7{MB;RYE0aE#)yo`
z<xCU>n`0ZoEVE}99`_D1I-75LZZ^(6cP)0n``*TCOrDuXIB3ZtAW+Z;dM_#9j^hA}
z+UcZjchbPqa8<b5r8sHf=m2ZFxtlQB4z|_Q#58bF4{+*<i*LVmH@4T?MLUwFic-(L
z!W2+6h;-YcT@SE0741Iv(=L}U)T4pI)l#<$B=@K4#mdLB&ne!vYu`|Az2hEkX(-uc
zBu}LPCO67+TDkON_ew5qGY_RUt>?y_;#I0w06M;vlOymjTKjkj)X#I&?dCc@MERiP
zRGO}X+1c8LhN{qWB{ny<@J@jL)VOmy60%QW>%vP*Lz5Ob5^vm#-x5YWN^#?cfDY>0
zmE*!j$8<_r2tnresVKbXN`*n3?~<P>CXGeX=Qjk?W}4HG@!+ad8ou}5ybF1R+<<QL
z;H@mHfT4i5;J;K(r@vnB#UW4X^^wfq-2oaS4V2=3Y;A77XP}i{k7aq8w|VKU0TuYH
z(<XW%xV*gA(@Qy}@sOU09wf9$T;e11)a=kZKJCIX;}QuLU?}7KHTbc?xU%vF@83iE
zX(-c{zfTH&|D^Y2+~egMyzjmYWj^IqK0hh{hwq9yKKlAJKkxWs_sUSkv?(`1Xi@JX
zMS%yA34IregSf;UiA`}pgaqy2Tz*eOXz_X8gwur!w_D`|o=G4?S_hs3?pTL?wmUn!
z(cIaKZGPLGCRP|OJ@17>1|P<%t|LTU*WnJWxd;yHU6`HW(!>gO^D_q@Km6ej$K@-R
z;`Uo_#_r~JY;COo%T7#8&B5$il^)4jC^qX-^!<u6;(#w#<~ys(x>CM`IXyjvwR04=
zZ{Lk3mf`B^CJftyYkM~Po;%HL1TReNf<5X#z<0XL;%x}a7>uUCP(Y>YEa8F|ryb{@
zEKKB7<|M5n;G^y}yUwV4F9KL4GBz=mV+zg9Wwl<kme%6_>u<${=dY5kH@^A{zZFx!
z<N6+t;$8UaS94{#N^8$EAo!+&pikvtmxl_3dj-ufio&rF+gfJ?u}%O0cD+eNK~!Zo
z?#z=M&_;QoIP?&9@7~Q>Tnz`~Nv~Iv<4y>0m6U_z?osya2XCZ6-dcK)X`vkIcYyL}
z0s9&_!n?_eqDa9<YZqZk{W{G};=u=S@d0^NfCt5(F@d5LZxC73Df^vw@5a*NcGQPQ
z^XS)^sp053M45osUIe7;G+b@6)5L3}arFiUP$Sc%yY|d{^eGtdM)EK(>gK9;8XpCK
zVx$e*lrP;{uKGy2^<N4ztyKO=AL8nOy4lSq9-As1?p^#Qz2~?G<w$RyUg<e6v?h3m
zR{B+99`J-mVw=#;c4avU0q%_%Xl`v~IhBWO?6`}<PPjZj2B@Ji>SjAq$Mj72)mRV)
zVU@1*qU1Rj=&Hyp&u%t}UYHI3RRJ0N#(duMM0oan**#=jrX!7cWI5)=CI93Y5#N+@
zGV#l=V}J^H5S?kAes8_9S3;wRcX?PC=`~`C{7AsB2Bjy5O1Cw<XodY2G;PpZRxvvE
zW)Q|wwwGhbbv&1Yj!GQm0az-p-qQ&~@~G+4z!j&Imvt=b$-j}&acR~rEP?l3fe0^w
zHI&Z)k3ew00$%=lJ+4R$K6i)5pA(?d?;n3xhB8f=|9AT4@pt8Sh9{*j<BTrS7j@(5
z^eXZL4IoUx<*H7E8U(4Z>xI8^fKNdOF_5@8n}bia<kO|*Ugl||(Pb2Sgwl<NNb3+n
z1A#v|QI82M*6Hy^oSB)63+LzK+O_j><Hn_U_WHHBe)SR-;n}!!;apt0bUx0`&yaR9
zE!sw{0fRa~D+6m4gChj1=XZDZIxv*uAzUz!n7DNDVm$x+v+4f6{PH)mk6&-VYp?BA
z8m*j_q#ImXNhLP4ycOoo#O=d6&UdLmBF>&Y8#iy=iC_QC-$uv}#M;_sEFipZzJ5FI
z-@BdTESE0KBFrYzDz%H};J`7LMtW6;ZD$|Z{pQMd*M6vAV3w*3svx3F3Q9(xO!u#H
z`;il@rOF_}y-prj=Dv3<024M&sL%HO`!PB>9+$r7#aMgm^*Gpp2@emVJ~b5`m`h8t
z57=b7!eT|R;#IgYph{$jd$(h6Zf~cTVRwLdaeTu)xenbI3%DlEoJn|&d2V>rCuuF?
z+y_6HgY}1`)w59W3+K7#F2_4x{z~G#K01+tX8`7x5nEW-rDD(nX>RPq&f+rd(ucQI
zk0TfBf&W}%LOMN7Ck!Z5kHMpReJw66$HL-9)KR7z+dBw{S`5=}&7Fe+zbYUH+>d*r
z<#--ON~P~O&P>+ggYUnd-KE-<y?BIuxi@}4LKeD}ih$D{m+jsf#>%xlU1yQof2i!C
zL9h&+YY;g54;mr<5O`PDHxlNY8Fc7$afLmG63XfTqrg)j4^dFZT+YbK_JqH7@U-Ob
z<J@ZBv7ZCrI*O5zF_h$5(x+#K=+&tA_VH2`ylL!!+oWaNn%|^nX$gUP2p^bl$^qba
z`=X|YsAZ}`rj$HjP=NcaK~UzE&(uvNq0(2_DhvG9VBV%tGM4$2vM1xYH@)|EpYgz@
ztWzr%@-$^J@5>1mWjCDVNjsKhU0iSF8ZW2NZ)|`UzLSoecq89<GN|4|8b!2^Z6%m0
z9<5*L+qzf<^R$iz^ENNLsqL~7c6CA#5AFc7hWB#nffN;2U<$vPnJ6pT74k!0p5Ax=
zij4BU439sTNPIm0JB4l-p7vdLp5<>@R(E(bPQ_Eg{4m{n-CGVAg1BmB0K@`=c;TPI
z!yq%~LOvS7xhXVf60ob%oq<!w&9|#18Haqvuvo`N+@GmvV9PKs@m3r_g%v<LXD#K4
zf4p<MhiY{wH+s}P9ph?@jpTU>V<@1pu~F{%MX}^N^7npXd<^$;JVr;yvP)tCp}MlN
za!P!_gEf@3K}cxjYE5OgiPjJAtghV(GPIUcuTv&5GSWKXQ_s{`T3L%<`^~SWAa{zT
z^~i2F;6FI(kA=HyaqsS8oV#{52X_w;g3cecIrW|tXa}8kcE>qw*;zq*ds|p|#rTiM
z$%@}z6tM&4PU%(o>Q&T+?ANcv2|`_Oq>lGh8K@wb$FaEgVY-u;x^Ovm@2y8|bSfH?
zlS%xY4TKr(Pyu&2!|GIt=yk|Q+2@Xer7|eZA(R~g9wp~stX!8ymG`92u0&vTVdLC$
z&!sTgC;ua-A=6${moKOCa8aIK;mzOu3d;Q?-uENlm&~lOk+c9|*`+x|`_-prlQEBu
z`l5}p%Q2qDSk3}dkfkygC$xi}k;cFb-j!#GtSm0!i8iu3!hNKsXGUUoeH$1N$OwGL
z5~Smu)=@N3AcN4@{B$K=c=l2>Xfr*;+}?u*vfBxYjE<8r22d=-?d|TMxQBB5hz178
zQ$CTBpoxB9DrV{xf>kB515S5oce^<iPU-@?leGSGS~f5=-TTVTBxyHyBG3>M&pDe5
zfr?0@IPe87YeO|?6f1jk7h3L#Bl!qOoi&y$3Jv816)w9MOK(8|ui=ohk;qFtIxA75
zXnVT}tfV7t3P*W_I+0zWBzP_bYt~i*=E^*IOo7XN*`;N$%n~=IHP7U8(`HnWN5WRh
z+|y^<sECIKE%UT|X-4>s7uK?D#}-vCj$fMA7r74_`RQSzud^;G`;cia^mPWIv-gw@
zE<lw&3+06pPP4NJ*3onQW%{fQ&#8#G_1Erkj6A3D78Nco1*@rxLd#3QyMt-FL;3x8
z3gvqd@_5?rvb+qY@xILa@o&20%Wuk1e%Boyjk6rTJ$*b4na^pYo`b~f6HQ73@E4|6
z+p83E?mEbIuPiNYyD~-)WI0_DLFm3b9_8sYT{m^hMSoaQ*(d8o!`rRpNr3hjyGCJi
zeJggbAa{40dEm}A*6B9Z>@I?76Ki*`xgE{sPM-L-yT>n<+79o$T-CeF^LDQC-Nho=
z$bMdxfUsyyl=Y$ZDU>8?iNOu>R3IIM`aV}Olc*q_=tzr*`sY~{2<+ef%B#`l8@GZ_
z0wa;>b^jg5aXe*rw-XOsb22-g7ICLt^t0~mY==`hb-7(nqB6GryI4@-$h~|V6jq5I
zyGNH;=G$J%8$l`8Yr`m3JQv!aAK1rd=MggwKw@nH@5Y_Q*xx#ggXU38%+JNdsW7)}
zyEgPd6pFbJj{1uug<3!HIrc%^E?$U>6Nks9qUtnSzo#q*&_PZv=oIc0?%>odQT*L_
z<Bb@jJO#o5N+7L4ygX;7efrP*hrqOk5bGqKRG=y-1)rgc0u(R1TP+mRM9f~k5W6c2
zX=SEZqy8#i7i2cKw_>DHi;21ESXo#^X;#o{)P1v=_;EK~SAl!BhP39<vMS5%CW@Qi
zxzT~Ra%CE0!0lz)F4;k;B1BN;=&#sEp!AZb!pSi*$90@xr{a|dvR@oLm0g@pevqzR
zKP7#2jt^oJ`t;r|G;1ho_gwdZaUv`VG-q?Uy@=C#9rN4Ub73XOf|i8YwITKZ`0N<S
zUK39nqe2Cxu_L|;tD3xkRXJt5q*st-W7GhrZ6l2uFMZmKdRS(y=PBQFTL@@=eJ<#-
z=xHe9QVN<D_}>%q#u3WFZ3TJCk<&}O7>rAWV?4q86w<u+o$!fE*O#f_1ky5WKZEyK
zuHSLx(FxSu^+Aql$f&ukKWU|tvK%K0<QNW*3Vp}8G~mpuQpL!{^WTTobIgi1QK<=w
z7)iLGVbdD?wSLyARz3AV3I$^MiKf%v0xiY;!{0JI>A5@3`$S?_5CH}eQr?%rwB=<e
z^YhuX-FX|={cI@Xx_`@1rhW7~%PQ*K9f~x5Q@nRxxm^{xNgL1Rs*rW2mPf<ZN8PXv
zYuI;aeyyfMF4HNv-Qr^etuOjru$QJ1`6tmJh;jos>Nhrym8SKG@{nmA2Pxc9iAGoo
zW#zUJdPhK+#8whlQD5%!mjZ~lKU$?EBcz)uA!wDP<y*8zS~kMMcYd0Ey}Yyg$lB@=
zWFI<~<p}~zt9x;6BW}KZ3oG5hWi2q7wqVdfyO*k-`++c0$x`K|rOmkUz8iRF2r`tM
z3*mBb9Kq=v{H&*fNDbs?0HRvbyO2HYvg<>**-cdK9Yj$NL}PRWFRvcGt%I1kbSXwA
zr^){?_SaVUb|ALyFGWwglU+(%w{B(qavcXAnmhD*M65frx`nsnO;jY;yKJqmCq5j|
zA0F<H#>5m##VuSg22jYh+tm5<Y2B)n#xGn*L9qJr%ekjkbz&kKXU;@xc{yi#na*<U
zqMCo<O3YlnK^}d;uncxl;+4^ya=Ej77dUoe@r`@&+E?Btz7{iQ=3{FKSeNc*do^a}
zQt9umuO;ox&CExW`tp#D(aQ2lv=91X63=PBgHVPH^jH)wZD4JJThH4Vr(QQMO~-h>
z68p4S$CgF_D@ar%2Pb%O(7VS7FD)#@_~b;?@qDwph59?a*=`i6Ncu_3nzC|i1AKbz
z?6+gjZb`fuy@(EqVi%lh^*U`F@=h9dHjke<Rw%AKD?jDYA&QrG3OY+Ne}$^kp7-Ga
z%W`&>TL{5sN!P+AFBR*lG<Z&82-u{5<5VPC@vfPX#@a2FVW9xzB6-Pn)>Ak5o8|MH
z3P}bb_}BbxcfUym#BUjl6EEH42Fa&9CqMJ+x2Zr*pS@CU0ZqYqMYolFl!}>mDna4R
z2@a-}U8uaj_EdN>rTF!n9C_b7EmvOlw_IqbT(X<HfWt1b!kBa7g9GcrUBJ@|y{W(o
z#hl7CVJz@%HyF6-{TbpO2?AsWepH4;L|1tHxjU5a{C(1WiLA$iab>yX{gXoZt~-x1
zZFijakEeO~ERuYG`t)8|Wt!sKB=Bs6Li_8M4^;;dU~cI>m?yb;s-3e_M5<PieZ1+K
zA`n$Jx{L}T%P_8VEps|3OwquyOOJ*|9BGW?V4vH7WH%3&Fxh{bc!8O;_6p@vz-WUT
zC^j3{XNfKq4EM#eeZLYq<w7V{Jc)vIGL=k_%7nD$nF50MDjOAq%18I#ZQyU-d=RVa
zo7tc5Y_MDtfg*8@g5x1tiaFbc^d7vwgJ8XT_d!fekH=_ZJYh`1a|*jtBNZMV@9UuY
zAxfr~_Z9N2<?gwaXw*k?da?t(uuo3Q9Y=r;^fmBqfB{Q;bZR<Arlt@U{c*6m9@7Zx
z36#s;-MiU+Rh^lMJ74>nIx5@ClNFCCw-?W&K0Td6L_BNBYROGZH6pho-*?tnHNB9W
zUvE2j0sH2=@8;ObkctUmJN@jlvG?FXDi_Z=H;qEShGJQ}xgJB6<CwgBHQGCCct0>Y
zR=#xQfm62i?oK=Izq=l-&AYMq%BxYSPey%WGP@b3&z+0m@p%-=0(p19yIw8jAnZ43
z4_91QYQ+(>o^Otr%P|5grZ>3WK8Z0r#uu;FXqRy$KEl0k2%4qs5cmL#k)m-@i8hx0
z^5R0AIeRWfP#$^#<y2GKPXT57I@uvl474n8f|O3HeuwY(!P_B9X$L{wffgNW=<rfw
zq~}Nlfxzo=<i$xGv;}$e_S($^$iC0IseEu<;8l$o^Yz^UO2}2%(zA3VR4P5ae|a^h
zSA%;ePbjE!X9;PZ%dtIYx!Fx?+ZZnmzDN7~8d5<}N0pMHlo9epDjB~sU(4cI#VTDZ
z^h@O+PRjJjtE9~`jL+N(h2wqlaZyBpOF|kd#FzPTQ<ST~r`C4g8LuL-=fJ!a>^Xai
zILk_fFaKgB=#`e`XBQo9+TO$1K#AmOtmLZEoE{tHD>DQtVdNX*(kMcn*d4BN%7ugv
z1*iz30Ik9Iswm8*;4MP;v-c?+Pp_<KS18l^E`jGt#CLsT=zdq;m(Shry~@1GQ09@9
z?0WxrnupJp>-*EE{NCr{w>#LU*g?DJwAH$62Kr*#E+&XMXHwCKY2Cvt$1oODiXJ~j
zI%T-J7;z44#XH^aLA(gN!nE9T^D`_%_zK~MS3+F9R?luR-FgYjfiUYPbe<J0p$c=(
z9)gQp<me$kUiKMFP!8nV*Y2TEc3UXmvwsw3w*R>7)+pW;_eCFg(dFRAi_XCiZdxQ4
z|9RZ$gZrzo(cHrmaJ`Asi7OChAz0liz3*fost%m`4dr>x#1>x59t3{<nQM3<5-jzl
zHlo}9Y)VCFV?Eh+2c2BiZr6^AV{&pT^E-3pS{&`QVyJg0j=+7bF%d)KlQB9o7Q>`z
zE#J>Bi~edY4mS2;lJp0g8#zesV!>?${KnE!&QRMysrBJm9sqM6UX_FD?wO>Zmsve?
zqcIBOfs^C@S}J;#VzDY8q1J3BElKHm8awyy#UXLR-#B|VI%{j$<y9HMARvEd#0*W0
z$Ls&*i!phAIL3jkvja1OW29K@Zf&4U`eS2dEt(r!F?&&^fuO@Uah9AO%+AVAREH<>
ztP>a9xl^z7)Y?D7ka3LT82ZGzh6WUBo@A&nY&p50ZC7c;^-H617DanZp8HOoffnE}
z@ZeaUiX7$9_L$rCn3$Z4;ZfQF#U>5gSQ<&ra?(1MhwL7a7E{>ruVWV~ZM5C=toLHz
z*RdwYX7q9(C{hte8|PtL(CLYT<ShiEbgn0h$F3JIzNKRs!&#6Hy?AI6$#M|i@j_?i
zxgba7;;z+sCXO`4d&fgGLR`6@h8Q?;_MCNg)}g#3Pf6?Is}SH)BKdRWm>194)yuPW
z^j>A4@YV1tWs1*+k}u7}^uF_1MWj^WHhEc!H<a>7-q9#50xbfbGma}|8keE$A<%d=
zf2Ve<OmYQ2mXQ+{ob9J!n8zBcRH=t`7N2%wJARiQ8$sn<jEP!~69uS?y)9`V&{8OQ
z>y)wwSj+m@Lz25P5RqG%7!pwGQzR-9m!bRK(EVH@v5YJ8D?=iX3YBSmHaz}K8E+`#
z4Q0G(M4F*2vkcvN8XkXdcr;FCu>8}f{NCr{w~SMn<~{$kZfxW|1Yj{=TC3o+4*41P
z#ZL-F2~15c;%%=Kl)N*&E36%KRDn4D;CPGuz&5PJ&}m^!kf{TH3TW%D7n4??WpO28
zbD3wl*a<&BLgCFRPSR3@fcz#0$!Uw+${MDUI7*_=wFv^sedaAan49o&e`wz`iqF;R
zORK98<4_D*PplWqbkN_845?-2Xa0xaK%80!_c6MD?Mn8iJN^KbCNpXI2&pr*6nMFC
zk9>xQRUVTFgyYy;-iV!5XGZm8x8D##rnRyj+qZ7T^rhJtKYuxKz4_WVV)1vripMY!
zJusK&tvj=7^PP917Z}!1A}xgp%K4BwIZgzUbG5R9&IN-xLkojpY+@*e$0m6Pu3Rzh
z7>S+>?;QkomHPDM%c-1PiLU49IupG#g`v-G*f@6ON>s<jvWrs%c68W^nd=u~5aoCR
zqf+bG+un$w;d(6IUBsJMj@rmjZrcGC!J)I|+<t#EhA7K!wfgjY3W$SFGmQ_&%WSJE
zIMbRg4(TeoY<3P%GJ7X6H*%7L=4h?7AakIa@^ecJ{^cw}Ec>;kwOrfcRu#gU<7Uu+
z69Q6LrB$lh(YUgGB^ito?$@_=qIuX$TO*i2b1DxMT?#20*>Cn+7&Lkim|4!SI@w3@
zc$~33z*PumXq58w=6#kI+|nc$UP{ZvSYPSX_sWHwKFzP2M%JK3f9;}4Lyop~Vutmy
z%hERXdyOaG8>~Z)pPbTt${K~I^v~t5lFfIfHHeq;*~@P;-akASyeD53>Gj;w7&QGU
zT$ykFnu0&3C9eF=_hmV@MOjxBLLuCRtB{Qv9h6#pf8tUEr(C;{VjJG-OWxDFP6Gfu
z>ZzzO^eV(%_F5p1EH6DX-b+XM3@ix;m%Lp}bm?&`69FxdQ6_RAr@YT<o&J`gd@hl1
zDC0^bc8BhKyv(~Bpz^s4W%@GsTx$6;ZTWo}XXt)@Jda1?{NA!p9|_)n`*$i;m7Dj+
z2+dOsjZjp9lp%?YG<qqHQSeC$X&bQg2#!=Zkb%S_3!)qRkhsFykV4#pE9bQ%l-=WK
z(EeJP2a8zZwt>?%C3zqDIb$ggo#K1@E1hLg;=jO&b+NA8Noc~!d*3NAT!UeL!k*<h
zC6I62{nb8iaiJw^J3IK<M36RsX=QB_CXc9L(WrDh*vJ9)(&d-HjJNAU1=koK!SXK#
z`Ocg_8?GpJP@R@fMsb`#Yd@zLQ?BPZxSHEDGum6*X&GyQ3dg}VmN*`oo&1w$YtfjV
zjpI%$P7tQeg+<C7iLs04qxIlHR8c?^?|WbLqeQeY7v6q5PEZ7+2zAfK-rw0qk@V%d
z2;q<ct+W5e#;eIBO%#Y0_$Ho)jF)}T)KO;M!_zqTfe+-^(Ejprt~CkZu8of7O7+&e
z@5b=lTyC)FwB8m17Boa-ehe6|MBmVGb}MXetYqEpzIi9xsg7smL<uRytv8PG>Ly0;
zl$wjNvACX7xCeUip!&emQ6WG&d%ICb;W?vb&~wtsw~f`m+kw`44&vDxF0QP_F7e7>
zcQQD^g7*yl7VX;Khl1QciJi@@+(PA~2j!svrXBS{wfddTte3ivaB{()U1QFpP^W0%
zxHY=_WVKtgKT5*Id7dW|(8n>)F8b30Z0nK8XULh{e~oxI>TIcu6P{u+gXOAN93zot
zbGK|hv#neQq<5xJb|GoiDXpX#fPWO41LRF5bK4sE#G_c{Q@i?XN4v*VB+{%x+Wege
zqny!`RcUDPE3C~gg*=ySZ(Ege!u#wp=KCC@pe#ey&wBA&D2YO$6)Y)F7I+mVyG;`&
z-lb9}uFO9T8(>oT*&Xh^30*H_3Wb02H8dcd4h=fRyYTW|AELKKroiRy4i1>NbC#ia
zRZ@7!oMj1v2ee^%k*9S<h8+|}m32&MLOOdY#F;%L;H6kdXz-=CITequjV~)v{+6Np
zS%jP3LJUv(w!F$vmT54)Y>+Zd`D;26T)xYSbbb4H=>D#}FT=yQ;`?p|Qsn>Wcg6EV
znAG;Ul?Lz>Ae<^bZ~gUKnk2tN?Axfi+0K+oh3prnLR$rtf|75*mN`IV;;ne+)Lt!E
z7YMGp@C_!Y)rQk!aSX+o7dE1V>oyQJssdjkmBEF_yoE`n17##Z7ZxJ`a;eNL+4{&J
zGLN$|9OKF9eLQ=%g$h)wRuXcM&S}MyXQyL(Ycqv{?JZ#ozl17YoF-`ZTUx8QTb=zw
z(jkP`77?PGF*7@dpjuBjgb4|e__h2TZ$hax5w=c?cIVs<!hYx8gJi^Ayq`P>YHuqp
zfAj@P!z)36A8v2P&iX*q#>Y}P*!8k~?_PQsmD$<2|E+Ju9_0)m+$$)SrJFY+>TcmJ
z!}O<Mvl}h@vT38K*)c4(Vd@D3Qg?R>u8kKPA?hV5Tn;xkb8Gl97YEV~!{EVw_sQ$m
z;|PV~IM>L93sHCA9hkP>y&XHt+qB(5oPF`xuqRtMk5GOtXnXMPLNcuFX4hoSra|}~
zwYOtp#_i_a+8?DpJP`*Yqu_P~nD9n=3r`huK4+8dY^;;7dvUc=nP0y+mnZu<J1-CJ
zqHQV|1~@MW{x)@?jwqWoJiQ!*MSys=yIq#Tr-pE5)m{g@qhvaJ2M92P@wN*UvE&c-
zQfRp#ZxcM(UFFp5gJZlk@uYB)*nr6a@M1P2UNtyVLGiyZjA&oI)*P>sLZRK3V`9*b
z-8Sj@BR}=#^*B8WxE}>HWahx;Mj(iP+Nzy<n@Lyh9-!szhM9VxiCb|FTyFi7^iP{f
z?*eJt`YWyFrkL^;X$;oGv9Od$w5@6UwwyjJ>|QA`PV<mIOfP?yyl7gxMbmKPIh6qS
zPTokF01u=bC7YD5r{%dgI4AWG=MDvl)XcvaSkEp$;I*9Dxzl53`Bq$)UY<sh`TH(C
z8otkQS@NV6$Wo3XYw|05BuXXaHzizlm-B7UdxPkOp!Ai&##9&-p?LQ&bU&vM<$65L
zcM4^Ce+}K=KB+8$?ha4;{_$_i_lEMDA{5^i&!#ETJ({M-PlPI%edn}7_n1<^I)ErD
z{RduouX3{i9lXOk&?1N0TQHUIr+_srmknaW*&y7|SP%hBVtI#}sLnmf!E&uKzQ=lK
zA7HudZl}d++o&`wPQsEH9TYB@uds;h<25Al@lIkcgJt_{*Md;_tk6YoQ3vZ?^!KV{
zQVFP-(z5H%zH6CbW@>_Tg++C6<YKI%`$2r<0!%XYEbUx9j!^3DftV@B@5d%5a%++8
zwRKyfU?kvCNGq5N20Dqo4cAdrW9H(eJjAHAu|OHUF+4p+noi7Ky&A)l)6qCPAFZ9e
z*xx&fy`=>#bp$fPY3>uB$OU)3D46A2w_@e~{TRM<DHibzR@YXdb*x8by<jYEn+ROn
zStUO{S&6Z+Myx#8O#C*crebSpDFv!0BDPjm@_gtcJfc7_kMn*6=5}G>@%nnS-+VKb
z!I0x1V`I5kQLkVdgJ8eC8MDs<`!sN4VB|@I;CF3lBk{4<Bv0_FH?oVD)R-8J;hNJ2
z5SI1P*xlHTd$;e!+SW##Kx<nl+s@W{cAquZHX;x4s`kYCN+%i!jLTQ2l8&}__xZjO
z{VqhL9?oP^B0G+^wY8hV+%Y(}P|-5Y$sHIqcC)tZXNNA_O~JJ@UV4<-B}nt_ANIyx
z8_T$bQG?Z--KGR*@ww>CS#<~Y*`rvbGsh}49;8{jQmA$sNYaR1p-%Qt_(@X=K>5Qh
zTS$=tJFRkHtPJQa9A(^5hrB6M`cd#xU<%BnJB$u@AJEHD`PeqOL$CD4x2H^;<>gE+
z`Gt2HPx3<A_{61r@Rw(KO+Hhxn2&Uv%EgKsNLL7O^H)y5Z@g3idSA#4IEMQip9GPm
zur39)<#~K?F(%>uR~T!&w;R}U?B*sn(kc)1=8j_o!^g6>@V3OG?X-^qF|Bpf^AaXu
zR%vA(q_@jT*{{M@9=PDN#82`C_vS0E9KZ*!y+1>YRm}{%OsK&8ZWM@V4W)oDzc(ae
zo^q9CiNx}oGOql#3@Lm?=4l#3nYO&j^xf|b<u~2=74IIFNvhMUJFW~xTHo8)YIffj
zt8sN9iAxb&!cur36$DON2{fF<Rn|d<6s_5>2tlZv$eBFszEX%IsP`S*a@F>5DhLPg
zwNBdz84V0q13N26LQ|+8A(-tha~`+ehfJ9bO}^P}C0yB_-WL`PMNxK9vt-_cf<Sv9
z$+BO(@B|<riJXM4Dath>K1*26+(0q77nhcdCm6~YGOVy@T{<YI6`zB15T*6)bXr);
zLoqcqlRMH%%+i}MsGutK5fsc+csihh6sI8bYHc@TdwnrR=O=(qMm>(H3m0P_AzB&1
zQ&>BSHVo6=C>9Kk;ROtzJC_W8_Z#1cV;C=pU&1q3#EUtkEY~=U&o;ozaZJqH=kG)W
z@CGs_CWp9YV(HET?c(CL!&tlR*6;`zgrPHisxa0_|54Onrtz8Cm_#}0+V|iw^#Y6Q
zMcibujnX*LqeIDT-nxx2>qKRumIM7etIM&sxq?zyiN(7M;6iVx5PY5H9(d`^{kL38
zV>@~>;eH#z3!S(|Xnk`dE$iWG1N`DCfV1JzMl_M@JG+N*@ghpCR*#L1W-b<-K=C^e
zZkLlQ&!rc)%yG{&7mU{O*kezD1P+7_YCq}l5U*mtb3(a?2w~`&hRLl+py?WA<0#;P
zbPAe=xKz51lR0QB-$)-BQU=l9q)9pj*NV<!v8pozRVsF;6c%z?%%{dxcGZ%<8*fUy
zl|c*^;I!MzH4z3acqe$|cnFt<ik_VL9a7ii@l$@(J5nIa6Lu}DX!IIW=x1hyLbA=x
z&-?P*d`DcCqry3jd(TiKKb4%{8YiAhrI=|=;ve2+Zvi+?KINT8RH<B3+2MVq9O2vi
z#=rbe4??*?jE0g6d7T-ll60)cddb5o?&8G4Q#_K7vRCDpb&}U9-zmGoV>zZXAAglK
z{wCb~@*lneUqt3^yoTae@QQ>_QXr*(EuRffdp7OU!gu=K&>iQm@H}32*$Ca~%KI{u
z-x$i@GOqhwS?@>V3=i`x-#G(;n_RdiV;IjLqPQoi!db!*>CQfpNVDN3INs;^>bx^=
zg|L<<&VCFkJO`^Z+HP*r=U!8Hurg%~tqS{bvGGwP&ai^95ujw1^Xly)awk$1jWv;2
zEDTc5Up)#LTMH(;5PBhatPX{`+UtOf^6(%uR0@0E<zTYJNBXpW_&)p1g&fbrK3Lzm
zQ|dtfU><YnLNGlv6G=ZR1oy{s+{iJD#1&=fMNCmY>t#7^+*l|jp2@@R5SdZswzRev
z&8?!_XJ~jZj>$^q>Km%Wx#wSq0jy~&@#?StPIT}DT*XZ#q91R-af<~!flUN>AA-ca
z!B!TQDHrRl{~#*k)fmCL7Z+~f?>XCUtD#VFJ&WseR_-mu2%f^)t((cPAUSBH7-@{f
z{LE<7Ydujt+>48!_yL6PNbG&(D=`4<qaXZWbZ+tu<qmnCI|6s*o8OE*gno1XBqpw%
zi?K7~)ZZ2GyRoyr8SlRKI<O4pqE64WmqsM>$?0kJ2(W>3Jb=yh?W7yWT8<8&r*;Ry
z-i`rK;Wq4BDBI2LlbD<zjZ0T%qPg9Pg~hd)oE-yS;E=X9V+FR0RC5b(gtpzJxy3r~
zT;z8QO(7-I+LV4=sjnyF)aG0p1m0`IjikReN>M44a8+tirCoB82yJM6lH#R*=uN>U
zFF6%doE97=o%`2`5*SEao>}8g2RZwQd=yD(+=>e<ts~&@G{Fv@XFoLQzF}_XBmdQD
zf4xE#n4aGzMnekxQ)MFU+U=Knt3j9YmpdFd{^4`s;ZO%~q2fvpB;ka-NMkpcLEg^s
zl2bWQDk8`9jQ88DpJkAzao(44=IMB*N+OLr-isT5%_kKp{G(!VcA|2|t&7U<Q!xTd
z8Z^KwKb84AKI-9Y;<P$c92Wpn6~Cmn9QV*u(b_GpA*Het4!i2?vbJk4$AZ95x6BoP
z;^Z*}Vkk7^!{_dI@}|P55T@nzq|p8T@v97FK2HkSAcSsMy2~v?x`n4{9?!2k4=>Xi
z%Cy{ZZ%lFj`1i&YSMg1L$Gr@fu4exb)~aHiSeXaE+|;_;E_jOrtTx1cS|wRFLL3e%
znJ;IVz$iT^gZ>lZX#0WcV9d--#oO=PrJ*4#1hSUC4R(m~(0bJEbXH1QgeVZtD>*=U
zc+#5t;JD>OuHtn-AL5ksty|meNqD!p(~M?LL#7_~Ejze}kZ{r2!9lyg178VisYIM+
zI#?M7b_e|mZ_L>;YRz4&UM<YV=y;ZIeN$oDPhmQhXtojc92!QT?UJ9~)G$ipB&X)O
zmIKnxv5400PA>LyeS-o*0n|G{enTo^ytskBs3Mr>uU<_{_rcq5$D3dI7Rsj`9R%SJ
z-itGAR_v;BLrKcs#^T<*dou<bhf&45=*QBojky)J?l^ckY*E*K1T;8AiS@KM;@XE^
zq})1!6l9RjoqQ)}rtv!ZqtSa5V_52=BV#c(F&vZEpO4zieDtFX#y|SesK4++Onmy&
zF)%q9$5?~T+ByI)GNyY)9iOyf?!{+f7$w`YjX+pgkD~_<Vg#lib}|KNTvt3gIufHa
z;WTBA@jU3UtNWBObR6}b!<ZSV#r#A)rbh>2n0k!J=qSO%&31ffz7}K9+UDw7j1Sl2
z0^Ub&YdeO)`5d@k*;=8#2qfA_kJxiw6e0(?CCXk5(I!q^-rd{H1(?!{*0KUe1EIgS
zk{(G9^i%^M!tJ<8vD(>fXo_x4$Jg{|s^D<cZD*)+4UIC00?95Scp#^4L#GOEm5lV5
z6F2aT+_6DLD;;@?V6*8$Lc7hNY)H&=M(lQ)24}PI%LFu0fevTzeiedE@UQ6Wp$?<K
zGC-LX=wqC;{m{iAo^Xx#b?R2741Y(d;{<6Z$ae&OuFDa`m$Ig+U^P$D16U5=j{^HJ
zX@{t1o$rRp!||CR(hu{ULf+jI2Kmlk$Io0KJ3xBWB=_K!^eWpbb+Id41*8`bHzQY2
zZscVbp$bZ6XWm1n_fBfj%Sc6p;Wk>WM=wft5Lqw?_^?paz*QPJ7+^CPAkL(eK6^=1
zfzC1=FxUk=3?9wjS%-rfguswf+j%bx*@aaI%u*<OJu0*f-YZnTUBDLMNpX({zcqBH
zeOi8Hyl|8*-{ar=T*h^W$MY}4<M*aBX>o7t(-lbZ>1p}-*X~s;wknpA7Lobz#(D8N
zx;e;4BRZ&+9tiJcI2oV_g*Re($0!*Exa%KW1UES|6-%B?0f#skU2O4O44C^-A@Ecj
zG7t={@Jk^LgW0(GTUZ%d50+!OmL*I;n^vMO@5=T@>>wyq91=%%JAiLzWVpSD1FgFM
zDl8QhW)d(_L-NW2MPRWmDk#yTwWyHE@`z0(LR#;2&+}OXQhsZ9J7(wS`3AvZy!az!
zbMJJPjD$^6ceCx4<DAnEJ~VqA;2WEnjq^8dAmDoA&MR-m)~22dN`P;jedYR&<@@&$
zetYO~Tz2ZX-?JI@xtZvzj*t)aq5x2r@Ve_O>K$6MOJgu914r@fM?Q?zjiN?q?=CIo
zI*(rRYgB8rRVB`T@WU{AB`Q5!wMGuIpCF_L=jPJd)nIAezMTwMMcKJ<@r28E+E`kT
zXP>=<aH>WXMLBf$Zj5j3#98vaj3A%Kqj(E^pF@a$9Hzevtdn>fXTWt0Bj5@a{#@Tl
zTpH?)3kc$~#Lo>4##!)L+3$(-cu+raZ9c}aR%=vr9$|SNG|mCnmC8u;Z8f8@xf5gi
zC?xQ<L%Z0u0no*|5_rz8Obr7Ssve4_zcYzc26p$k4&gFQKMv-q;P^U<y9V8DA&}8a
zNpo7ZZ6y6D^%(})b<)*{@3GIny&sb*5ommmc01II_7~do+H*D@#ky0kU1(mAP6h?3
zyBoL}s8;kmFnt`MIf55|0h%4<!ztd)0?QVj(=^Xl8>2Bo{YHUd8az!xuj8Z{qu!&y
zbOx_wf;!Hi(56T;3jfZ4w+3bP1Mfv}GUh$yH_68!IS&KVDCN6DaoMFc%y%l8?DFK@
zFuY`Nj44<3o1S-eQMsp;hMckvVW4zK&qk$C2cEj}SXn}SoenOK$yW{QPJV87sp1&N
z1BP+6@}o{&CxL6**?*3)k=`=hCMeGdqON*NTePj7zmt08UuSX26J&@n04@1U8(9~7
z7aY@4R_s%M6iCm{Bu4^p(Pbq%zOw@9elEkKLifp`{NB9F;PcbIEz_0C<MFiJasC<}
z&+BRLeJ<<h*hUduq<b_E?~V7qAQ(gOUC|FXR7I$fOiQ{@cHokCd5^Vz==^ok+bCu&
z^EoZizHV`UeAG@0-(7w$p1%;ADb#nPQXNj~U)PmlXfl}yFGS%CYJ|+`zV<Sxq*4&l
zsCG5jZ*3QXb=>oaRPxF0B0L7u*mdAm*$OzfPx07TiPkzepf3SBj-e89c8=>Vocd>-
zk2U?c$@bw_x)FzVRk{8^Mc^EDag>B8q?uMls?~~B2H_hwfTdc;lQ@Rxo!Z-nr&TJy
z?B4}PhbYKHP<4VOtydu?98`2%VD=1R6UFlC?|z-{_w&TT6Y7@xC;{8jy?e1s{Tx&3
zui(YhDp4K73LmN^F6}3l8HLgA3NdG!?(ex<?Ll0B;aV)+zKc*pc>z-k#XfuSa!jK5
z=AV5w2DIF`=05SsnE1#?B6d)IcqzRwn={2)ckaY6@%<>Y9hBLFmtKm^<>lB1j`Q2C
zxI8f!ix<zwa?e40X?Z37#l7XY2XikXa6jE@#!J-mI!fUJZTZi@-4|*2n*%5D4Fu~~
zv17jmE`J;P`W=M8Z=)!_M%`a(9mUu1+SVp2@iGG8SGU^nmF9kYi?)1?Ho94>$IWVm
zxF&*qAnxIbzK^<}?LCeqSAzF=h6l|<vuRkkCA~CQ473(Btl7WU-iv2YV9$Z`-+?yX
z?i|J)8r+?TXP~VIEj(e`yoKO)<-Zoc7=8og_ZFFNpoo@G4AWTG6}*g%-F9r_LBkq(
z<yaI-(W#_%=Lk<uuT5AGyxb3Z51m{Ew$Gq+ztlSrx9YWc8G-pZyx40a^}xi4w}9ye
zH2HOC<#)+viSO?~N4IGE1@gGZ?+Su-aj-w`lkXkq=O*oapF&sgj5aHSvCMA=+7tmF
z=KEgiu_S*&XP67w{q-8}4=^qQ&vXkO+Th(b<!$lJ8uf1h>kj3)OW2;u8ClRGU5EG%
zdA4ak<Bm`!UWe4l?RGGyQqi5z#w`@Lv)G)C)d1h?<i9O{;$iOcJWG9t>m#}Aaxb*M
zUK@-ic^s0TTlwsgexuWhMGVJvVA@Cgw`s?Hc(DaN?a+2@;N9oG4b3?U*WsIk{vPtz
zkUd19_QxJ|KUE-wpnfPgwft2m<@3XL-GaEh%IEJUl!Chq-!8C=(4BXg{z+-exTob)
z#+O$ay3>ER3Zz*3@n}AJ2016X0&@YU?zgx@HD#UyH0&Y7nfp9tUMd;;fAKtMY=0Gy
z-k+VC;=7Z$zi^+ta5-U0+9<7Kztc*0EW-RGT0IUGk>e=NY*885E#|Louinwx>gs7Z
zz)C)LaXG`tLC3YVHH>;-MnJU@Fs-I*PxhnDdso%>9a9GwQkONmx*)Ov=ZI4e4;tcS
zGH-5o0zBFGN)7Bs7f06E@0^aT^(y0QRSja@I|D|GXJzRDied;WXDA2ChZ?xt5;8(d
zeCe6l9n!IT4x#F9ur8oe88#*-V*czol+|9m{L;$^c*jWWQp5woM%><YL&>!mX^{W;
zPz;R?$Kd!xdQqw&(1Hc+7BhwAtpaqT$et4fs5{zDjl`KtXJQX4eeGS~#2WkPAO6GH
zWpRj?vHSY#F?0EHjLy#HbkGxLUcK=~t~u#Lx$SVj``|%T@RHVFeKi)p{`J^Ed9-2t
ztCd=OZ0=nAW~|36Yg_U8-}nOF(o&qKo$hb$<_h$W<5_)kv>vn2(@?V&3*by#|L!;6
zig(s`;$1w51=8Im{R5QI@?MAgow&WW6RQaK&4YH_!pnJ=w0E|4V-*FxhSFHr+>STz
zEymLNR?*ehe-dwDbX-D+KM!tS0~dDJc{-)-r}1MSyz7CaL$^<H#?T<b`A-j_*tU0L
z3ooG`fx3sMc5}NKm-)_Z=-0{Daf(h0`a=1&Q8MSCwS~QQETZ@t1J!8K0KIqvb0|Ge
z{n*R$p=9V=-p?@#ese=h;^i@|diS<csXR|Z{s?XQTPVvd1n&LSrMTN}#-AK+#7{o|
zf%qa`(%T5kKSY|(ZEwa)d%LlQ@La<)+T`6L%4HLwxCxCeZf(XYihG^-P2MkqvqjS1
z-`Rq9Ix#yr9h+d`4QTzdD5Q5O+ciYzq-zY1Mc`4MY@ocBDPs%6rAa<JctJbdw+@T@
zCW={)%QYH%#JTRpof=$Q)25v4y4x?-#PnB&bEe%g@HJ43dN6L4FOLu6!R>>Df!atK
zZB7S&p8IXSTXF|(%FwfP%beEUCWaI=u)9ThPN)D5+9(h65)PF7?p_lZ_JE-c3|!!?
zMV{8(XLn8RrEROUtI7l~8>ygh;;(|w;C+tlqh-pVU^R3L|1$W__)_?m;|$#)34r(%
zET`$qP{x;`{N6Y%4bv(_%U?rTUis~l@+hCnbpDp1{HD0~ulJAVV|w8<-nv=#!!pWX
zzIq`e2+pFri9Al>t3mvSorBl~`8geyEX`l*+J0SVjd)z(`e0nes&y955rRxh+wLc4
zRH!HvcI6Be)sy1@=}Az&on~e%O0A-VrE7eGu<yrO?dz+M20W5R;qQ2fV>P*V4pv?R
zL6Fljv1%2l6p@TM&<CLm*J70SGOY@z;dD%x^h6;{`6?NIo#o+ph_F_$mWA8;ZLO{2
zN$DD+q!2W|b0&(5rSQcOs0%28vvCb;etT^LPo$k?>J>Gy;0xTV*xC?xC#qOejghe&
zU_N*Le0=gVpNWmd<@nMs|7IL+Y@xgwScdIrOf>i&0dVUM3IrvD?CZxu>_t(zKU5FG
z*fw%NIK3tQot(&k9n7t2>~3}9?0hXg`h73vxXaqzW=x%bHg5mMuf@UAQq-vPD7d)s
z1K%I#zVG{DA4PGDw{e7rGIa4`D)~*6#_C&dMgR5d(Kn6Y+1!j1EWpvb_u?!9_-EQ%
zv9Pri*Kb^iKl;Lp@%Mk}SK~fHyfR#g>nNoEGwt{PIx`dRN085Vj^h8Zv<9JI<=$I~
zzdGKCpO_gBq&lPvU7;AzuE5@jt#|H4WqvY-X0U`sq3?FLBj(OT%w8gH7n5}}-bKiL
z_N{v{Gcg`D9Kw;wdi*VD<iA5v-$ZfO@doX_ax6_FK;>VoJ-}cZ9*zHK?<D>%^!g1H
zydLZ>?LE^NOGDuZ;rZhb_ty}1>(HA_)=NEH$v+M)zK`~Q8%6Xr${QUTj&b+!f+oKo
zZ)lb8e@|nFx~SOgZqZ<}&pijbiIeWDD7DY<d}+8EpToLd0H?RtmQXkY@#kjd<HO@q
z@s9@kV(Y;|>}+qxJm3Fm41}xHjf~0RG{`s@FA!?Z(xdUx0}qrum5*3oNhbXj486aJ
zp*V;4+6N9k3J+XbSdPCzJ-^><Nc(r-^BR1*LLUD&6s~l&!M82asE8M-(};X6|M0vi
z-$6^;Y1Co-k=~vQ@9Xef6VP6UAqT7O`rH>IRQ!FUxrs7afp%Y@E(^$|d+_-2@qSE`
z_wO65$FFa0#1`;;A9VC(_+cA)ZjZtMJo^28wP-mm+NZaT(FeR8%4k#O<PiK*U?oEn
zd0_kqIIUpNIKg5SJl+KEU2uSB*gXrY5SE6*19_O$!!*TjcQCFL&i?xR_*KT2q5J;v
zcV%AXx23Z1zWbfw@pwb|T&6J;ufIJ_aqnO6zx_Moig?o%X&w#6(KrZV$3)!ssmQxf
zM2<LE017)9uvAbINe&hwaLs!JOVh#abu8PVDuRv%_awnA;S^4|2*pu&A{loY@A!x1
zmC7r}Nc19987B&U`9Lp+G{nn@T06pH3)|P6i-vfwMsr4pLc4W<)sOJ7KfHzI=(x#A
z?@?|jd8|;NU0moTEIH6l{q2gge8(?x53qz4xrb6HrfibG$`eMizW7lnm0C{ewZGlf
z+KsW%=-2xqZ|k8p({P}6S$_xi6)MhDJA2_mY_6@wYhQaMcDD9nXnZW0u#M$7ex?z_
zjcQC@I1g+HADF;>sbrX9jHOV-(w8gFsR@=XisiTuL3fawG+w-RA-5sfUd0Oi=Bo(k
zcJzRc#z-}$uAIxQPDW5<1N9tYjn@79z==FUU^P(~Dvy2g*V=TwL<hJoZfwSz2&D-u
z<nI|Bitqiz$K%JZ--us-^|d@-q&_kn!{G4~(9$ai_cNrc(KNRa)aTC6#oKq6;|CF%
zUnbrE8^!%AF#j)t<X^$?_yt<@pFlUiHCByZ=^V$;Vg3K3o$dI!fu8un_#|=r@h{uE
z@r$J0#M=IIhduH4DeI$i^=M;WO!xN31n=HLAP+%<{XD19CaF<DqT&Rv<1?G>ICJZM
z{0u^TU>{)yJ^Td1?19P!A-hc5ejjc1e?)=&D`-fsQgMQflHD|8Tt7{Q8bMz>HHs9d
zXHk%UPVW|6eG^*oC<F)Mov`BAoXSI5tr7PpDf@%9O8h*^?Hy?N{>Ew=S%1DU5ig)X
z{yF)2aG5L7oz=C60rAUx_w(@A&r|-tApc*WPQO6qex)%IzexID0-s+TAB|tfNcyGb
zR{S#0zhpNcIQnDI=@;-s+`r6jy_Zm$e-XI<Il}zo;Qumo`5VADi6UBo-~K+{`+p04
zeT{N%K?847R(6*`|L=g#xA^Xsa0Al{Fl_K{op^sYfN!1O9|!-_;PPeK#6f)x>i>ZB
zyD0g$z}+85Vf6C*241~`-!=05(N-tkB%dwn`Pae!SAby^esYI`G5F~x`Uc}S$!~$Q
zYk|xm?K<%9qEl8e2v^|qRh0Py>R`8<-EeF0;3B+#m-`jsatj!~>n-}P3qj=Xd&26m
z@U%4L^W*V`r^P=hbf;ComY2+3hVFNdhwg744d$uPR^DNmbD74x%4hHYSA{GW;Rlgz
zy9W@B0BwU@kPH)PMY%e;22*+}p))Jo-)V@lE4<6|y!mFUxreYp>pNzm)i>zY5~tl%
z5T~=R)I@@-RcPLMPgCmZBEvJ@sk~0N6%)>;$tjxqG`iD&z2`f)6<OE`^?=JEo#7%D
z+_K(nDxBM&>5lYzPI3kF`o;$Dihk|2&8=8jU5g!HKEN{bj0I1q+r#bN!|in=J*_we
zqTa0IGWAI;W}tFUB^f~_dW?c=;VEb#)<+sq#X@&ON-Z$EqBNAUok%Y@6|8<$V;fu-
zUK91>g^S#rX|=qtfH8^Ljg|P|_7dP9#ps#Y7@3=i$#duP{14%(k4=Q@Os410#?<_o
z>@yypn27<EH*Gh9g1GX+bJ5H5p)UUVRvaQU_SV-^5s58#+uh&Vj(wD#Td~wW@PX*X
zi*#SDHVtz`{>LbmJ?gS}>sB5&x&vO`1cXb|<M9LMuf`9&a4FvZ{EbvhPM{d1{p~uk
z`^K)jUU1!y@V7C0d-X=anYe}K-0#VmK7%yk#K<TX>p=9knlXvhJ?aYbHkK=j)BftY
zk%<^4kE89as7n|K!e2ztTq5l-W!>Gy>sa21uWmKt9OalKH`L?TF)O`_p<WbtUp0E(
zU5^_mu|JROn1-g;X@`#j&tJeh{8N1=u>j3Y0@vTB%?A;7pG6TKQx^>g^VN&^8u$MN
zJn+BgyT4@nVYxS<!7p<C*VUo;ad7;fBNSV-yZs<q_j(2@vj(~RdFpzhR*k;_TrcAl
zEpBaK<sZfWFgg)8!1>SRL=3!XXxxbpUd~jSAipWve}d;3gzr3Q=b+JXV4B5<n8PTk
zl3(B2TGXMf2IWmtmtMTFW#Bx^cN=(#%Xm`ng2Myeo#VSo1G)tscOt0becR2{(TJi<
zm7dDao&gnM$~o$y;g$v#c|uLlHy3ry1;YFu^Zjpe|5<SWeK@K60emMv&x1R8ewg>p
z{5nR~*zM&ENGAhS)Yi0{Gre-M1HYcySS8PAX*1W(Xy~Z4k1QYfJevlnDA&B9Z4}4>
zilk?VwzJ1VqZGh|t$>*#N`YGn)l!%meflax_q+1f&>iR1Ex^mT$KxLl-DN+X_VN6D
zeo|g#{FC1CCGp>$=IQCbb12|^_$wxh@sZxN?l-q~u&|w4Txfk0XzNQfIqePwB0)>w
z9ttx8;khrAgWBm@`;Nv+__92EDQHxMCBnjWD2Eat)}(7O94waT>>?|+gTTV(y{oG2
zT5`H?3t`e~;idwgmjp0~Mdhxj)FKHx6&2+<`$j9?dby6p*;jT??KO{Ld2tI6D=3Ts
zgnl!-WjwFlt~Iy7a13T|Z#Op9*J2CH*FBk>o|$L4TW^?F_>%xB!ifZ)m2KCE&z>u8
z_ntz=ZZP-8dM^N%!rw)du02u7sl41h_5kK~@m(86Igb4}?8CBx+1`EYPQ3c%-^Oa}
zi<yg8V+L>G{IgeLe11G;&tHzIv*!?wuDI<a48^XdM=^WRbk9X|V=c$A#-<1HYBo_Y
z)f8rZgTuK<Z|mOOxc_hdO{~21QtT})<v~;~*6YKg+`}_^^NYU~_g;S;W^~rsW^CTR
z6Som=Ul=%umxdyK4~=mb+#P}|y_0?S2NU%u_#W^nPH7Pv0wsmwu#FWk2<jdc3n<BH
z;QZ=Q>Dk#s;{q^o)j^?)SlicaT3it6I+67?>`sJri@e5B@NO)bQ!{yXDyhOwq0_=}
z$n_X5V#Kn3^OZaCr?%Sh`JRDzcd!;)yW2rEPzF8mvskr1KGYvCw%W0GgzzMfKMNiH
zZxN=K$-52h>ck7b(?nOf{xTHv`w?b;gZTBmW^A|i<Li9$=Mc)DrSAVJ@7k14^%5S(
zpZ)^(6VTM(2JUxJ)=LQTK9t};sWhU2LinGdGwb15AR2Bt@J?AyC3XhVC?4eq>7=m}
z@Z><eYaE=;s*+OJyKj~gC6WetH`-`KKVI||3>YU<I1c3ZX!od*KWc%xfjchgLjzG7
zPo+VADqz=>P(sRq^y+xdS&^2T0^i?KFc<AHKw0N#52to}c8;F(AkV{;>#VIYVW+Md
zjn4Q)dc=9!sScgmD^Nr6jO6U9V(rg(eKcnEpqv~54DM6r{$%pKblX!wxd6u=<v3v=
z&+4Zg_Nk9Dp-ijnQ!v>s?}dlL6yT2~AT4Nh;<txFcoqV^JCy0mcjfi8kbn@n(;8QL
z2mh|2%<sDi!dk#v!1v^DjWf;T_3~G5#w%Z)#*4d?*xGKz`Z|h)hII;K3QLGrW*k6p
zS0P0AxpJV~eTQI=w6q2k9F!sPxa+T0hzzG1vhlPGR3^prS-z8CPZ{34BzOr{k7#Uc
zBpO&oW23_{F@_KvMIb?l4nR63P{wx;9S<3DfVAP!vj|e>rVnZTlD$gFgM|*=Gzo8H
zzm1i@xDA2hQDJfJ;(@HLY$Hq&P9Eo58HOlPF3nCXEiA|8>Si2@BN>1!M#jf-A(zkr
znKWk0i`o8x-WUcxJq))~A0DYk4R2tG-+E(=x`GSf$pKYxxP@gXT{_b$XHX%OP;bOR
z{M6YkEjD&`VrS<;)TRcbe{3*TR@UO}m*0x7|JHBB#_|L3JrtEXa2~f~b8RIy^rY|(
z_7H}y&hF{mk6YjPdi?G${Cw7@f@kDn!$ELep^cq%kVg=sD2FawjE%)btk2<C_~IAi
z2*FmpdNB@Z=cVPf0I9j{$`H<1?{Ht#=0~G4Q;X?muI1iL10cn1KBS=o@H>p4c5$1A
zM^AMWAwesl;PRrL;!FY8hlkaV67#)u<TTJ6FGNA~4b(uc3%%SY%}EUIF9vm?IBH|n
zSYO<TgO+(oYtSu-b)lz%(y7N91KUm4eQd|*<U};^!km@%g_mx{A0Ypufol9C0B*H+
zqXSL;Y4TAad=6UqS(NWz;(mX3CngbcU#EbdLrDK8w9^ohM?qSJwkjx^k%7Lr3*7$^
z0>4K6{wewFlIJ>}kz)ftg7NWLl+u5Wz*We*e&Zj5*EVqeG<A6kuXPnTuMqdorsm>c
zY&`x)=s-SFk$6r`uD1Z5VZI$h35??54na?27*RKX?}eG!xD0-t<M+iY*Wwc&{aF0K
zCqET0Ub`O8oxi~I$K&H4_+b3_Cx0+zKlQ_L;WIxNeY8<yax`9?nvCjm&&SZ@B>7iR
z=qM-J&aHb+pd$z^aVkIAddjo(rucPMneCV|4rWjS$d`6&=awzD34EilwtGwB&xtJj
zx`5Kd-82~VRpe2p@VcG7V-$`(dIWLX*>liFpC<=GXANkk20f2pjJzLX<YUzTd&uAG
zLloh&*9Xb#d%?-4$428L)ZrR!|048s1Nwg+xa*|Xb1~4K#b%19&lv>9xKf~6$@0Ei
z$Qw!_Up{vS-<9bf4`rO+m1!PNTL?l2QMKkD?P@C1mEV`4eD01fzVqJvGb%%wUy-g<
zh#5sF(i`t@cYZ~^{7(2DDv%<W4p_b88$AR=2a6?VG$8cy91bp^!P+inBiU`?>?Cr_
zdP{g}f49YQj&^E&Gg9GkIg`uXcg@53@cvV&h^w@2AT2!#$1?N^B&_0KCIlM7v(Eh>
z?d&-d9;|cF*~|TN>RfspuKMmBRFR{QP-?a^KhioDI{8s%Z=Z|)9Fu?{z=<=dq8Dog
z;uH@1uG@QUJP(APLX7(8&O25j;XCUIwuoVsDNHBaBPfqTpi&>oYhnRAu%D~m$+L}h
ztA*tLSS~=jeEnJq&$nNDBeplzQMCJ%0}jEdtHK>Pui_01Rt8czx=3&X>wDqWt8w?%
zD{=4byRo*kO4+#USZlV$K1xwX@PnWJRLq{8&)Hoql!0q<j`y*ih5L{;Ccaih2;kiu
zA@q8OhjS)b&-i34zjF&FZ$@<nkEQN`Ne77+kQ9Ss!!dRJdTcFj=9um1<!dqf+FS82
zUwJd8ZlHW%){~9x`2JcYzB$|<Q_xWroWH?u1z~XW!D9UI^i-UTR$_$)@r;L}JJ3C}
zJmZ@-!?WAP6Lt}5V|)VG@qAJE(%shjE^X&7ygl)gy(jUrd^b2g5<7UC7qLt)^&Z8S
zXy?hXiQElY&+N6g7Ge^*_`lH3f9bdrE8wX`{XanY|0zQ6uVIKZ!TVcyJTJyT%o6`)
zl*cqi$s2t4{m`0%{0;K0fIs)N8gft;;;@VFCFt}TdH)nN{Z)kH3Y0Mp)%_ZE`!vGu
z3Ow~kNb@G1$zNAULJupH^-;X{pQ(?<1~l;V<U3^-6m6bI15no!ye=(&SEJj_=ycx~
zG2mVRKhIW&<I>!GJU4$fE}~q{5;qCXMsMAW8N9(6Jokw^cjL^)W}IMTd}--^d>KYq
zUtf-0^8VvvvvD{(8~56KahB&}ykf^2T$izcaq)ks)#KOU$rj~1>(DVxcf3|$sHl|>
z8ddU+24;F#;78i$KZ@ZbX8HXQ9{#0@gM9TsJ_BBw;Nu(M>c{wYkutta26m}dF|K|e
z?Ehu*-+-t7cX%AXvcDI1#RdOH;ja&p=KJBt?<L<)LXV%|{*$ErB+BMPcp=YmeF_Hn
zBzb%Y!|~clZ+slwT&2xELwPmo_!@2I?6dU33PIU@6``oeLuFBhQkZ%@{#>Si{F}$a
z)6#V3RfaOpGQRuWcN+?i;oD(*n3uoZSDB`K|Fob;eOMo}PFRVPsU7s)bF86VOhHun
z*p=X#hdk#T%Xbq?&kgD<u?j<szy$6d>S0P_Shk}GjbW@_EjJhO*&QL=mh3kvtj+rr
zH#zMQ<(AWY5!Rj;vDZ3|jV-*Q?X8^Nnqw5?H(DQx*>S9F1jSBsCt)6UF_^*^g{Ecd
zq9@mDxU$s+Uk3;o^U%Apo-SmRuu~}@r~nTIR4BbYgy#0<ZYmAyEx;~T)XVZ{S6%mF
zqdcrB@=#$|7yI2E#c@WBTg>ZO<!-}Vc?2zKoTX(~j5DkHYXecm+i=T#yIOKl8i4e|
z6hk9e^8C7p&jX}9m&ARkMyBTD%=ODLab_|GszcEWGaX?S51_y<zVQBNOwA%_t1!QZ
zLXE_kXRpRUt&v>^rgtrhhg9JL#0l^<JzE4N(gQQPo50Amndm_Y*mZLR1FAM%=%{w;
z?0N>qZp@$nw-Hc#Z{CX`XmpV8@_cIq)yZKe&lz#ej&+n4C09LG<J<|^lOP9%fDu@H
znZ|>P76E2wL$NKl${u3{xOO&o$R9PkU#vYs%90mt2A=KyJ7~Ljw3?elN=t_*nZ@<J
z>{|N2Q}2IF`~M#C2MEhe1lNBJz5F)MZ{ZQxE$jM$pQRpu47#~O8%V2QJN_2J`~L(l
zoWoGEy$zjxXn=ou7Yf<G%l(_A`LCdf3E*2tq3_~>{#D9!!Q!tYB>xWSJoo<r_0uZ;
z3;mV230{5?y!6^d$CW!GlTPoWj>4(&tnzw4iv36MpcaAaTNo6dpKQecw6_)i{adfZ
z-}vh9#@~A7tMNDA_*VSQ)y4Q9Hdo@mU%DIr?b>quSKF)cS8lx?|G#^;;@7|MtFZ;Y
zet&N@erR+ue(Q}_bNaUP!mL#<Jkbl^IR+wg6y84YQ-Aq0JrZCmw<*yG%!_+vgK?%)
zZWNw3zudb!b;=LQ$OXCNZCh*XYdB=D1^ClL(L?UT!;{%gz@huiNejJrmanca#s3D+
z`?E*w`283HKZYFmF>w21r1^cjTk+#Zo%ka?$MFY<|54(8f^`2e2E`wTdjAZ3{$~%`
z@dM<14j7d`sXz)Ls&FlS%TRg{DG)Qw(}V9Hzn&I+R|wnhobPv&*LNEV1!5Z%<$im}
zra8R|0{`wp0b7~x<N3?zJ|RQWqA0Q_e|~+m3rfpWqFh_sh~?##Smkn!#`^kN95k_L
zv9@Y3Y7ORdC1?d<s72*D$Zp){f+A-nDg3?cs&J!0`+J9p*R{1@yax+W)n=F2{&6dI
z4w|vCy+PW6n4X)-bH?p6N0!7Gmg6YiNS?pYdl(hFUxwY(4kGSDA>p;`x$`MVm5^YO
zqEGe2^8@To(X%N$tyXS5fz?YrdJv>`<5_k4Y<v3=eiVqzh{o8MnkUzj$UuF_H-(vJ
zsN2<MI=gFh-Q6~Ph<jI=yAW}xMxNl>aRZNv^-S^AwUwN0wu8_fJ9{=RKmS6Uf96tL
z{=joFcj;P;&7J`d?k3yH4IFC|<58cSDF(^G&BE(%0EhH96w}wABaf@mI5VH!M{Nf)
zd3REqKvC6W<K99p*j)VPxA<+v!1PS)p{(~0+hE4-sQx$vZ@pN1wXvyKy0-$eZ$$&V
zFWr78$4-V&Hu$VLxSCUqp;-wBvBL8}Ql<M?rJ;awS2zz2)>8OncSz32*NR1XlZS%I
zDbcpypaKPj?Suup>6}^DL1FihhihMu5!qJKs9ViATTkzG6@~NWz4iF4d!Hc~{~l#I
z18Rl)pGKh^(4K!ExGKc+MXtVn<)|k<hamfl(A}HR^)L$RtJLhDllPw?t+Rf5)99f*
z1SB_60S;H_|9^S+4eIib`|(II6qa{)a&Y&bQvY9r9#=7P77=*gM}B{GbRxbAeg8H%
zvFmdT`qA)myAXN8JXIe4&Y(Pg5MKJq{8TKAkH!~J3_thM@5C>C<7@G&Z@wPCdGAhq
z;r^ZUGJb36LHydycj7niz8k-TxABGBx8hr?%kk3Idi*Ej^YPc9ga7!#)%ac7wI5?|
zY-T169grMjljG57;00j_$Zg6{+fBB2JVx2zeO|O<Dh=wJX}OG7xxDwD-(p6r@jQX9
z?7pUsxywZIyG9wt79O4HTy7w4GkIql<E@3kw*{~4rjfX{y^eRf4lV3JqZluzSIg~)
zNY`#|<%XQC9VdwFVyF?<+Kv;~$Fy7NF;Zl<o3tpX-Y39M64sB$`K;AjUQc>&c#=Rh
zBoayE)%~tJzRbf=##@$J*WZ8FP!{ue-i8te<GaB5E`o{6tAyM5GB2$MEeB(;7-dp4
zyYbQhFSBdIX9<Z2ew7(VIfk&g(~bw5+i?#I_0H->++D*G+}@4toh<}%6L;9n4s}ft
zELb)&O}*ZLfX8BdbUen##)~+F@I+-eW`-LvNBsQQL`=d^<D;W70<k;8!kHSC^nU7q
zg%YX3g!O*DM_|CX2PgyUG)A6QQh1#(U^SestKhNURSVW}2?xvd8cb___OJ}ycEx9v
zS{1lNOdh*Qo!zcJ$3g4@vPQrou7(g&GLT2*rZS`~J&_I;>K<0`%F;?I)A<V*au&+;
z`7;Qzh|$?81Y;egIhZ^1-g)<S+<WjKdIqqrr{|)9fDaUttL`V}&&Bkmi*e!d^*90V
z=Pq81^DkVD(X(UV0U>v|6OFS7p5Oa20=$x!1K0g-74iI~=sVho>S!PJ?L?)4U|zV1
z0N-|^Q|zpDVraC1V(kgf&={x=#Ma7cbk-ll`#=2yq}h(ud-r4iq)Ay75dlu611wZ<
zZP!Pxnc>;)xEAf7w4)~q&g=qIVapdPUPK6jrP#gJLDa#4N{*=rvt1~r(SlWO=N3FD
zUnws=L@pJPo{~EzTkIRJy%nE4Jc&PrA@RrXE^DM+Bae^aVf=Lz+n*(^efH9Wma<CT
z?$W=F06Rw;|0&?vrS9h`|EDSF48s3EGcDhc9bQWzgyezr8fdSdg%18H`Mf<?MTy`w
zV<aGD<1Rwa!QVfI0{<^3=i*=U{maySnDp*5H3mJqt>zJ);4unW<>5g3$k=GSh$p{3
zQID4&EX2yf{rKjCd+~=RrsH#GF2!%X|6}o`8!yHe-uLnN;tL;*-@f)@eCfiC_~QBN
z@mp73h?mY?i<iz^j<5CA<2r`RyLjLKZ1HX!pF11#&pZ=nZrq5*<*U&@J(Yvk&boAZ
zyF9Nl1C261<PN=4*HjS71$meFaz|YGKu<zG%P~#z@!Xa?V9FG{lV`O0P4Cobi6Qsm
zBE}v8`OxDA(tEKC+Q~lT{yr2kczT9>PpYGFQs)|~V{E|#{*H{t$uM!_b8#{;&+`On
zrsAYAOFX|duHms*!UO+B;Cfvcxul)<LLmSJ?Yj%6O<|Z7do*;vd)oWQ%QBsDskONb
z-D%2qkAL^w1UD6w!2R|~-<NrR_rW|;3!Gk04@Gg-Y4E*1PiGf7!$yYbciQBMd(aHw
z1;Eg{zgTT{Kj=MpIrxpN#mYa%Vm^r`LVBmQA6pQ!-BPQY8+pQ>+mr9?HuGHSot@pB
zQmUod)Cy@~ePDI?o9}kpIpF539Dm)fNq1N{+|_glqN`N;Va!345yS<79wPwi!!XI9
z_&mtIXr}>tLSAl9&%J}U2Zwvvp04A_>T`d9Yb=WGo=T=b2zruX&dy5f3|w*L=6YJ(
z2=@-~*0Cy`;#%*k#^~f^zH>an4f0l2ma^X0pL;e3_71T4_i@pe*VgeE<`LMH>_(WJ
zn~kdDJLKPNDJ+XFoyoK3u^=Z9-hC+KE%H5%GnX!)kZ#1({AKEhBCL-`b7_HkfXj_-
z>OO?0G8**>80yV?vANO#&(v~cGKOZ)#=&tX)|T)-sCHv^1ZCoQ`yTCmq|Ty@zPR!|
z&qjS_JkRymxW5o5QxhnfVVa$`hgK6&r&q5+L~E1p^a7mrt<XhI=jEYFxfz}V=HSfk
zD!VT$18%_A0WZ)e={(ucO)y=v<N%XxW!pGt?uMTZ#=60z<yrI|ZGCds8$Sj8{eNha
zHf^?r(w+d0KUb;7e*+B8;S&aF9ETL)=6VE-4s!l0D4PG0cAG-kJ0*D*xc{#-@(+>t
z8S=1Bt_f10g6O0@ip_npKF{-Cf#81!B|3qDa}PRq4D39(`I8t)|B80KkCK@}NsS=1
zRTjBd6T(e;snX`2&Eju``pm%-zlTMA4G-Y~hR%7u`J=Pv;umKp;~$-L;vYfJ|8Tz<
z{{Y(ghgCeF$wvIcdL{nHqgMQb3GU}-;{SPeF205bx<Z8q4-RADrI&JR8W&BDef)c)
z^8EW#s9G26fu)m*K!xIfzHOFcoBXC6qMq56i?H`MyKQMZI4hOAd88N0z3r6g%{LKF
z+aXMjfg^XQpbd?-Bg@7sP8!u<vs(;W2M@NmUd(Th=Xn&*1m8^3F4JD5ou>Wgp@Z4O
zPK+Zn8hGbZ#El{!8Yc&|%W;g6?q5@$hJ;ct>-i)B|D^D!;4SY9Me(HYG-3VS1oJGf
z?<V}))2Td8Z{G_K>(Cv(%OVMW_g&O4@!(H^4;S#cn!7j{pBD-VE*G<D1?pAU;Kg20
z2wH?}sZ?`3f~%Nu<JCvaq*;VE9*KS1Zb`7MWxKr*OIsVUytNq%8#{4-bt~@a$t-Wg
z!W#EnOG_KEzPuCbE8ASVv9^pdTG@(?bx+7UNDsyV{%XxxTw_^X1$$1fr7m_QxzVDl
zhHV2^E;}CLvkF^bX@_ktT10@j?Yjfq&Z=^J#hGPJ2=JZCrWoJBE0~+33>BGu<_HD6
zh+4H)crP%&N=}AaUS5vZUw<_&Uw<a9p+xT9yNAWu$f?VA2j&_PJd>f}TIQL%&5BpP
z_nZl*1P_v5AHquIJA2`5Oy|NwSMd)<Wn?tBS83zo56@L&d<sQ}@U6|w$JnL$=tEKV
zoa{$m9ghSHxPNRar$P7ic48F8w0dhbcGp(WEn_k2Nr^D)_?fA={Gs<nd#4p!Ya7)2
zFltw>MlW7gj*-xy+4Xsf4`;23>mCI>_|Gm6CtUbTS_Ow=XWrYDsQ^<!tLS)@9%3pF
z=*lxZ>{oYflpc>;q-Wlwu|2YFXg_IdX`>T=$Zjvh#Logx6WILjPmuQz*UtfHe;N&D
zq0)lKsJmlaRg9xoiT@`&|3%u-jVj&M_BD))pW~aK<ok;K`@rNj{s|}bv2F^)3i$s#
z_j@Ca9QdBWQ*v;+PGv1`oys=AOO^a<;7ISqJ;~f<SC7OooPHFTU27HiqL1e{P(nAi
zc5?E=rQv$CFeo%S+@;uEmB+x{<oHC4`AoS}GqZ8#@|Bo|ZuI77&Yn#=l=mvYqnE7*
zvGmF-vHq1W$I;4Sjtw1m4hq4Ff^#9Ho<#0OOuZc3&n`!<a@JLPO1w`VA>Q{%1f;ba
zF@JeZ<zPJgky{9ncgh9$lNL-Ix{iyCvJGr^7s{6V$Js4xTRR<ilwU76I@gWVNt3${
z^E=dOqcDz%kEmmOjPjlL<Kl|+j;`cd6)wD?!YUV#rwL)>6;NLGt$C?`$_0AGcHvL{
zwhaGv0bdYdS(d+EIVji_N+H}GOjp8Re%~F0Ph^+fUux^J4&_zWtLSeuAHV!=f(eD^
zv~f>E3CBZNu@FF0o@1^6hCvOMlLzVa`)#p9u9iy9vVyo2z$y$GtNSvIIYU0&+rN$V
zO-xQ0bijkl_}(Kt1L8a%+T&@p__cI=_R^B4(sqyMl+5ksL9A@G<35Vy?ROVrd%Ybs
zEZH2G9PEjS#u%0!3<L~rC6QfM2<ttpx2=7*LqCbbmL3Ro0iRCa-NQoe?6qNX1PSSN
zwI#rQgp7*h@SyMxk1*98VAXPx*7qGm=H9;Dfg$jLWmueV0RAe}1sD{Xuf6<otgo-c
zXFmJc*j~jN$2*(FT68Aas)seT_hWf!Jr)<1Vz;%0a@mQ_{%#y~S~)l??QE{=ec<AM
z&j-^pY|NgCxf{=?RXk7`jygibafr$5voUvVEQTjWXuJKWp%_l6_dpfJLSD$}IId2{
zVRa(57Md|oN1#n$2@hc))JLdW#MO^}G|wK{?>mUQx89Da^Jk-?heug5rCayAHby02
zD<3(i4vpB}Rg{7jDhX3q<djd|Xp9)AMSp_DI8>=oFQ5H|zbzQ=!!6>Eb!E-WsmSE!
z>3^Lzf`)b>3-ERv?Zcj^V731Y2Fc&S18~#57I2J0KR*R*KhLxDqLCwCx&Gv^BY)}3
z>}Op@2m9ie$?z)e^}VFoMJ}EnZ^S=EL7k-zKPGSRzdnqoi$PL$?P#StuH`PfM_XG-
zLvBA_0d^&gGw`In5d?l8N<(Eah{CBL%o`dQ(1lx&*Ht3WPaT7z7vtavMbbmrqmxtN
zSu#$mKU!UlUU*IqK>_bRPua}`{L+_3jJ*WI9_WSlyAM3+F;SmEl#c6y9N=!f_Dbx(
z`BpSHwsJQG7yDsdrS)&O)*#>L9mzN5on>*UNDu%;Hx|z}i}>_DUnv&gDS0;cB_m$k
zreS9AJ@TZGf3mW&9EyPVJ8kl(O%yG5bUR*R7w|CcQA(@Kp7Q!shQN_)v@%b@GDH4L
zFD@eGh2PmeIsTH;$FzL-xKQp6N!X{CMf#hW3lzUk`}E;A#r<~^%5S>UTfs!?DV$G(
z)o)TGbD5^d$NFV8Gx%J@7s`((ejk=;Tv500CYY{-#rxv<VcBIqrYYX%!7(y1gm5T9
zkS4nuu!J2`u*Gsgpcn5HU=Dg)1#&jC%)h`v(V!BH1CR<pBrwFn8{Q)t_=mz!X^?>y
zyJRN=KxZj<vhLhxcUo;QHth1+w@b@$n3LQ#<JH%0#R?uwo`Q%lvHyP<Z=f+U95ZLe
zfgNSBe~j0I@IYaq%TRtWCl+*vt5`Py;i;_n6>5cKo@@wn=q=>JNgy7=`g2CmetS3X
zP3>77n6NMr7E-;I%EOH!(;6i2=Js~{=I1{b^YioZAN<jujCXI{r*6G*{?g?<W5kv5
zuw(Z7=aw$E1#tMQBHyR{shR2c%uoJQjGns^eZ!+MF+0uMlc-^l)(}LM`eaN$`;i!#
zzYudDx)!q^xP+y-7Ol-&RBSg|J4><l?%VO;wYOux*`a*b?rcN_uLES**&jnwGx7dU
ze<m6eV<_3Zc;$1S$D^vpnJZVK-}XlVrNGj|0&XN|(Y*nzN_Mxc&+ZVIw}t|;>q_Ip
zF%IcL9vMJr+qOL?uG!h+UT=u+foF4L6D6^qN?aa+!g9*%2twU8D{kcHVmPF0w#R<~
zJbwg1`<e}k;KkR9e@JHk40`-k=rg-ifJd*xOAFdb1HzX;@ZBbH{~h1_XVA(t$|$XD
z>iXaC?H|S{I1jvi4*v3-0#!PuE(*%*>VX!LZfUY!=s>Hw56@``SVzFs{Q2{E7@Zgg
zXA{uFgvSbVKgxZTJRIPzX-u6xhmvk!2+ZbUznQ5?JeF2W;`!B31ji^6H|kWt_rL=^
zJ3Dc_fp-XPsU&+)P{+j2Jo{{npF5Yz$?x2OH@ypSfT8Dry`Du4c=Z-N3q<9S3Xn9z
z<mGscO0LGe%EU2?_jpr0lD;$|^#tV~m^<8LQNne_y5o#U`=ntPP39RnytTdC@HFZx
z*OdJ#`5pn^NY$~>f!N~ti~D?s>~SnbsWfc8sfRruPP%ZCj&ensvs>HEN|ja0q2k<q
zzLFl1JMT%>hr;gLLn*Kdq2+V_?Yh4G+d>#W{I2}A437%fhtE$+|9ILbh3;<+-TA02
zWFTJ^m+_^?WqP0UtFG(c7Rql$VF}yA?@Bnbh<r_X{BxIG@Sc&TQIV+4W$2<Ch=w7(
z{hJ=};vzvWJMT08G0-gCxP(F+a4B@MU|#e<#eOaZQo%^*nMqM+UU^FyJli*(&*YY$
zqbwlu=21`FSzM2I?k#5bR6mUDzLI(TEIB*fSjKL(54c*11wD(xQ!*XD+}kar$D>D>
z+p++d+bHCbx%?Bx+DILIRA3Nc>5EYWf@=k2CRgoyK0$TR!StaV7gESb@b~ZCkC(sk
z&G_UG{b0QR!ykw{ckaesa~Gv@CN5vP5_5BtF*`pQ6O+@)EFg+Hf*Z=MVeLNqffv(5
zINZmww5trkFFtdXH>n&79iBQDy)fd?#F-dAcOfPaCKJzJi^=DniN>X~F?Mw(hQ`|<
zvze>T`|Fil^W(;q!{gI&@%=Bx+||ppb2Hxg+Ba!qlpN0$w@<P5(1L<Hm4=oi?U3y&
z?SQM1+DJTqVLYC>Fc%Xw*KuIAN=$eq2Y7pS)%Dkh;|M|4!V@?|a5wk&@BokEkaj#o
zP`9YFJFK;-{*5CCX^}%UJP>yrpp0im8gU<w>OX`|b`SgFm&nV_DOYH_KMg!*@IHPS
z*z5yW$ZHiF(s0wVJw#zqmhJ9pZM&D=p$4~UtDmOr-`d)VaVqr^O8f6YD}Rx9c4ZY_
z)IfF%DLkEi?wK?yCh?*rj|58t%*B#!TsmbpCq`EvUV$si9RpD)H)zj3;yudNuD0~(
z`g&6NKGSN)@4t3EK0JnZ0u3B2FJq9PL@!><i3T)4rnB9XUlN9%=&Y~D{>n-;@7|4l
zl?(BDAD(wVGCG=zO@-A%zpldz&tMpUh2-ZG4MXaXy#~B5S980@OOx@0vJNP-N!d;E
zb@M{o$PErZjACe$$141!r&9;Vvy`(zdy5N|E%qD6!)Xr@=|@Q0&+k6@|0u9jAT5Rc
z@d@|)Cvgo=6hL4vARHJ9Pc&_{I?#|Z%E5TYMGM7r1YFLRw8y~x#N=To!`Sx8;|S8+
zOtBQe-9e%-7++qeB8Q+9G|n`}J^HPo^aLJ$TLkY5;r;O5-z37*t2=#}_VIW_H{9iK
z8CP6Bt314a7~h@lVep;xq9Go8_oQ-492Duh<BQ;<gZHMf1_RDwakEA9vOyJ~2n)AA
zCuKHHW(46$9QK9UO_5*oU+V-}o_QIvOv}%5PGkAWdEulrf$_z=f`Gjfk7?=TrKMw+
z8jQ*F&MsE1LMd}bX_=OH5=^tT4~&N~j*v>L6Bv&WP{+spSYPhk>Y}Y;>a9vkFUTo}
zmQfkR>LT8izzPGcZM$9CSVOwwoz@P5y_z#=hVU-j0{oqCeKTgyokcmh{mDVXu8?tO
zUL}+}_NMm+Bim)LwY?cvpS^_VaXw*t>y0<Co;+KABrS8h!HOeR-HzNbfs<S(Fg`sK
z)3dYWk09$qm^4Ph#f`gLo7wGA9|LA2Z9mEjF2;Lk=lLa-@ezdFA@v6rFxU3_N_39w
zuG@$`EZ2jR4oYV%E`Ru=apj{Q!}FMk_V!l1`|@kK24wcq1w0L`J(&F>@cin{`#Ej3
zgCZWm>ij+|=5JEhGYF{xnEch|UVQYKx!9)O7f|*uAOx<|8*vS|ZjkQ%y#F4`_@3R}
z_&5sTlgFL-ICc35!p+sjpFq%lrhOE@pKt#?+V6Y7<v$r7j5lcWjm_=YBF$euI}<OP
z7xnt<yTy*L+qBVD(*H?>-(Ti;gLcjN|ImdrFTG`VE$?tiXuo17X2*)KF=+q3c%8ge
zN_Y3#af@%<$Lbqo@uOS~Jf2sPBU<cQxk<15D#ZSMaPv6?@B`XeqMD%{exxxPOY^fa
zbM<N*-oH=#jOFDz6pBmO>}Jtu86@8EuCeXi_|3bw<0B}KXKBMtU^_Q4h37dJXT~RE
z4k0;1o#!wj&XWEN)PI(?IoBAA`DQcDwD;ozZG4V)y#ySWsf(K@b`Yk!D6ScBvxB0&
zOZgw3oQPeN_D4wb0rL46zu(XGL!|jMiu5zk?vGO6A0wZiz+m|I$mb99{ztezMb-WN
zEI9jvTq^3n2V4uuN5zSWe*gpPbMVYI?>|N!cTNuDD;Rd!1qPm`iTf7m+Lc=TFtqW%
z;O%bGE>Li8@BTx?or4eNN%zC#^*+kH!Tle_IGQJ)E0py<^8Qik`x%t#H1D4QUiaU+
zK)O-*#`8r~Y$%YvR3MKFKZC;KVIUX(@{!@u^xrOQ4Ugyfo{)P&uq@M?=4s!RX}Uw1
zKDF=Z{iAs(K!v6JeH6||^E3bA?(ug%m!XL7z8;oQJa?xrafmgm0>OP(H0M-G8bW-!
zQ*8=J?x{uwtsvSk8Okga^44Ew)q2)LQ4v|3#gbdLkf5caNn#R?!t=_VborOi5s}uA
zX(=Z?1>muZX=A%dszM=lw{_+NAWq2@u!e){eCPTL7YnK^Fh8>|y*^w)Si2!2LfY+D
z`(33DGeFQIT8GrdV^C9p;38{9?K_iY+&T24>4CVSdux4-x*g?Uwx`-Trs0@~t9ge|
zHY$%DtU<fq+%@+8J=nMRAg&-JW@hJeUCG;Ty&0>^Yk+o;2W(ZbRGq3^A8y2y-54-p
zwO-AQ9LYYdNeAhBJydCLFPaF}$@%l)W|6js!mzoz90w?X1IJLb^bl}cSf`$s(2Fsk
zg*JBnY|LH16d(M9KNXGH=^RA%EQXhV<(FvGlbF7IDSA<=?iOoz;Z-cb&)<AE7Phvt
zjVFQg6X)mRRq!$eW4l7+SKfFl-dxy3fmfqht3(q8wkrNd>v0ps^8im`ZDcsUK_1_t
zo!&-au2A;<`Vd~gQG97*Gro-Ae2M(OjuG&Und$hIwXNJOU=yYCC-8*c2TrCBJMpEy
z!T5!pW_l(SaP%jD&-EE!r>*RgaqwC1RHY&9rqLp;@LY9|F6ifQ9|1$#y9l+zx3BQc
zKk$NfJEWdOK-~w|KgD;qxfXy~&qKpWTGzMvBjo$b;O;*3tXVS!EWdwpCRV{;`{vE)
z+1SW6K5iFMbA}$m-09AC8#<{$ufenN$HB?3uP?+`cQ#@hOZ?2W8!<9W8-ueve?!`8
zz=w@G9$6(0M`=fX_YlsTc(Oat{|4#yP%6u$T?GF1;i32dR{Xo%j|1N>ZTY_}+>I7-
zXUC>u0lcqO2ID4P+)WhUE%5s-==lyx{!JA7%e?zN>hmRV@;lJ@OThelcuH@>2d^U&
zzJd|)YlGGJ8XhYs%mb%fp!qJ>?}0;+{31Af2b{f5zB$H1S!Zdh``mYc;|xOJCHQcg
zdbmbrXnZtY!ytNxbhjz%UcDAK$@c-}t)88WSHSwKwE1oLX?0>88XAn(sqbCd<31%m
z0A3HcnxI`g7z>Ze-bI_{(VzfSuoOW-lHw^XW<&8#%R>QE2q1&sJ*s$$@U-|cqy+;a
zAC~zrbeCBQX45{dG`i!<dqXjO*I!)z)3jb?nGZv$2#P!&eOCs{>4veui)9q|McGAN
zAEwoUAFA}maAg2t>dAgRDLn04^vr9Su!B`w3}S&R6-L4u2-L!w$}R)n`;YkCro^r%
zEDIn&nC-(iC>aRCsk>SnZcVQ8=<65%1^yh6a~qQU62eu0_w*h|17^N^cP+Mni4@dd
z3j@oL{1gzDuQux?zsqN5qdv%Y2sa1*H+K;>SW~U7U4(Z7ufRj0+OgLJGEgx#+#ho@
zvoSw+E*DujuHjiETL@?!XQu~Wy>d0Kc<d|f-ICE!AP?StBPPeEu-+%5HrmK`SzBJp
z?i*)-ZEULWY)gCeBbo^F4}Ih#as9?MaC?v&D&DzyD;5_PQsGU`PJ(Y0$Z!mg;JKj4
zrst>P{JE>K{9rXE5JFdOJeTdWcJD#leeE0Zflqx3Wd|-*W_{IIzx6upgr|mt+g`er
zUR2O7(>H+K_Q#^^AFRh9OzFmzdNI2@yRo%!3qj|hS0hoWk46i@w70X3z#EAlg)V;j
z=l@OIM9_iZxPc)53*Y<x_$T-7#0`YvMEfNE`ZwN)O_Wq?uUG(Rx6L%^Y}2*%^&CfY
zw`Iq$^io_yk_!oGM~#)$wVmuz+rh(8X$_&|FVf~U%D#wzyrlOBj^ABejQ?q6GZ%77
z)^l952(4xCm*>n#hg?bNlr3$@qtd+HK2-!$t=dofI8G8VT*LBJ*g$9J@nW6&{Y8|5
z`M9~`hw%2U@%=Y>w);kp((w=n{y$0Hzl;)H<i1K9JcAJayPx{O_!6*oZr_e8v`sHK
zK0%Q<FzuMk;M9~1n0S#F_LrCA^5$mzm9M=N4`??4!4SgBo1ThulV@UYb)`tl_qG)p
zF9(%9U%$<F1K`lEI?o8V4$f+7g0DLmFJF50{qc(!4L2}K9yGV&uf6hev9cb1c7loL
z=M2IlJqTjEgY;y**YH_g-pJ#mZ8Le)Q4Grw=N?@vPUY3QyomAnJ$Rx$wBvo=i)Uxf
z%^dW_?aofz$#px9t@OtwaJq?c<!%cXpozEknz5$WPRR8k@U%TgIfkK(Azow7-hy05
zLj9Cu?yZ-LOON(bPU&5GcwG&6+yS@=ytHfYdnXc>L1c=kM+K<G6wgI``Mx`@2#<dE
zwEUhNo|Mk-4H9Vi?(sC;?+oRA@olMON~KWbSHkr$JS_XscMt1c{60)m29rL#y6f;T
zts4irvfDvz8(U>z-(}7bM*+Lta;Yq>k4j19VMCH*5_qmcrST2OIAXb%S^P)iy0?{3
zr3Z2XP9T!(x+DJ*KL1!=5)t=)YtZZIU^VUmmov07O^Mgjy7sst*@0NdeQa_x<E)z-
zMxxFU$omMUfv6*-h0gOx^o=m!bAWMTdM3+p8nfL_9_XYep;DTeoy`@+7T3n2-n8F&
zua(w&c2R%_XD8W()oR0dFuM%tDQWi8*08>vru*)@w_{^{BZZyE)TUQ~r4FQg*Fl(X
zMboY#%C>Iyk&mOGhU;Uoyu65#?od`B;5TFC!Mjn%GHs%WY%gal?W``v&e}?BF5ZvT
z`*%|bj-NRLSJMvEE&3f0M+qVv9Mf=rs+~<&{72MLh7OS1jV4CrRT<eW#`_Qg7pt{+
z79oCpdNR(=&&QkO;TVAyt~;+jH$E0GPK?I;@gSbV@VJ0y=ZvQ5t*v;0ceA9Q2Y=_G
zvvZKfb6C00RZ$RpTSur>se|W|&mxe{^6n>5o}WH56R5!WI`Gc}_v^dlf$(Y2{>Poe
z7zeg(+Sr4Sa_es{MU28l<&m^%Yx_&y(wj7((sGw%aqM1Pl3w%hIOYc`<lPt3(7n?_
z^(rTZ@Th377WrjfUfj>}?F63VRnmTlw*180Y@C1g`SeIU+hyj1AB<xR7`qTFw88K*
z&qVFH=b)e6yf$y4;1SjhJj|g=e_X&izcD!#&*C9mt&YUl_Ev7|K1+!+?fsa;Gnm65
zn4xuMDdP+<&7r70Xa3y$T%4Vmi%YX}af7yb-}#I2zGt3~wYj+%J$E*o9X3k)y$|Ey
z1z>yO>W#QU+DqX5A~0S8_h&I`Zs561Qr7muVvNGX!|-$!Vi*U1PK%y`rYHIbVwk$m
zK<}5iKg%~N!xix6Htz1EtsLlszC1n9@v>ofc7!$*do2*CGTn#9+Zbwt$Q%dm`zf#H
z8ZYu5MUf3st{Y+Y02j=k+r5ukHn4aUx3kj5DBG?<XOFrourtRrEceOdi5`f8N^Ae2
z5KL0%QXqJ58vDk*6X1u!*7p)rcX(3VlY;5Y=kc_UdOeSZ5}xkzOYfok-ca0Ynb=)a
zK9_ZTG(7swGP+@Um|qzRm>=S)2tIo+94Ao$`D0kUeS?Js&`wLR6YiF)@a?n;fhyb%
z8W)T>nAWd?sOaVrmnxH@e%2!y7^3oWK-s~^BCSm8HqZ{_k`Ce$8i~yXOIk`4lGdRx
z4iTqycyD!=cZ0-e6H&k^9<nApW>*{W&s{qgBe?NeCtKU?w6fj4WUzu|dto;Fp*J@6
za_=H%sElLvKXdI`ZrJFig`SVGvb2gK*^l8WjD6!q&ZKf0>Bh=~*hT2>x_48%nPVZN
z;}f~a&G<d6stts?%Fh+(4gfor<ao*!R^u*;%&w?8n0p98=>VYh&iaA}YwXq^ZlE|h
zJss!Ho#%Hdx3FHlw}3ZR&)G36x8I6u?|VL{A-e}w1qHH-SG0+hZa1CY*9k&t65%ya
zt4DQoJO^N1WO;%?;JA?EFrIDFf80Wm;hi-`5pGRz<reK=5(}@2U^tJE>cztl$L{94
z0+!#tb0<3Bbr#{_`QH6QDs}|=!cq(&6szNnSY23)?FaYc%=Jrg^Yz!GbzCTIyZX-H
z@zqBL!B;0<e(T-1v#}fNC<XJVk=M~!Ee6NO<L&!Pz*dRDLj-pEu7|O@yBTla+s%Ex
z^bDkCh%xC+nsL&HhKkSc@#rZnjiGe)%Jz^;gV0rV00jvJ9fGeK^_+!HtF(o*qvGA=
zyAAT#+uM_|ayFDZA6G$!r!$`Ax(be`r>0|JOz*9kv)43A4r%Z4OP69C#Ub)mzxK6Q
zf8~|f!z)p#I74wzr9l2UPSU`WrER5!Ba}?h{RSmrtPDag$J^UEre{~!Ahc>%n$xU%
z>Lb}}-~m-0Am+6Q{BD)w%)$Qk%@`$Lrygs}3|_yU?eEdY%isJad5y%DV-+d_+Vr<y
ze=TQ7tpS6p?FUdg+vG3Z%G*28copxZ1LF6gT|HV2tsT-24URzTjyr-cXxKgoC>pp=
zVh{dwinZOd`?R~0pWR5+u}6(I*BF@`d$VXido4(xZAdxJDg!mt3$F!{+kiLSNy1s7
z(#<|R;xPbD0Qh%SAVsh+6^K@B8CQftz)3_8!;|8k6v}ju=lQq-F`Y0zDQ)@A`0jhd
z!+5)i9zH)QJo?W13;&~OyUQu+_c)#m#ueU!?&WAIkOH>~TZPEjI0}SDhqkbcoA8}$
zAFvV}FCkt_!tWo2$zK__sEf0p6c~2RDAaNg69s~*C=>|I>};rnmHhh1S5H8qQn1QE
zgD^RAIPNWP5$C!BXZeW#Zd{8~7?1BKs+G9$?0j}pwAx4U;K35<XrtcaxPJXS%5o$Y
z7q|1w2)%(iFg|nRnHZfIgW`@+I=Jzxg_kioITjZ#T;RGG+bW3d&1m8&tSv7iWIHi`
zW<F-lo`X?`^4yG_t&Lb+U(J1z3^^77b5tO9yXEYocPsNF>M#htJ@rt<<yI`>Q9L*Y
z#?2euBHx)iV{T1?r!zD(oJ!~j=D+jCx8i$$_=jU_aVger-_0qf+spT37)w=UwZ6I*
z7vA>)l&0PhR&c!m4#3iBGcDh_8)vUSgAzfxZaj$bDFhm|Kj<{^u-4)j&n?#k=~<-_
zfQ+V&E(q+jcVpq!O%x^qsZx(YX@~kLI5t;SQM5gA;khgE+E-uCE|-}z)A8o3--=zN
z_8{qKqV#q~#_Qy<8~1K6#%6ObHh1mn?4ulLYy@wyUQGi)uVHWZfcRm^>k!Me6?boL
zo_2vc22{|kLSLTrJ}H7<pNnxdFD%uX%C<LlI(B10TYT%-hJriuAwLN>shH=7JVa2?
zg9sM~dUUeWa%Uzc@=T7i=g!3hzdZ_3zH<@Y3`WTm#zz~4@y@^g*LiHNV<4%VRCuIu
zBhNna8NwSq#<<WcaSC_`d}P=7X<Y{3pHYk$XOhWxwz2z)X_W0#rf^DM1_iVpcgJqW
z)B3n0vkO&wYt<}s83SNtVIhw_=;NJ&czJ0lyIP$#y$!5-e{SJ(V*Sa-ZYE`bIF+9r
zckIVV@m|@bl2ukrP0!}GMk?~$ts3tU=OPt?29@}BMir7e$2T2nu<KXvLHcw7u=UB=
zW<0ygcAmiw{3;Z;y^*fnb;85vGJvN%dkC10dwSyk4}G4B@;Q;+KL7v#07*qoM6N<$
Ef&*k|!vFvP

literal 0
HcmV?d00001

diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index dce0bbb30..78454fd7c 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -120,6 +120,9 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                         <div class="row">
                                             <div class="card ml-5" style="width: 18rem;">
                                                 <span class="h3 text-center">{{ __('FavIcon') }} </span>
+                                              <img src="{{ Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('images/controlpanel_logo.png') }}"
+                                                   style="width:5vw;display: block; margin-left: auto;margin-right: auto"
+                                                   class="card-img-top" alt="...">
                                                 <div class="card-body">
 
                                                 </div>
diff --git a/themes/default/views/layouts/app.blade.php b/themes/default/views/layouts/app.blade.php
index 2c4502a3f..240eb2466 100644
--- a/themes/default/views/layouts/app.blade.php
+++ b/themes/default/views/layouts/app.blade.php
@@ -7,14 +7,14 @@
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta content="{{ $website_settings->seo_title }}" property="og:title">
     <meta content="{{ $website_settings->seo_description }}" property="og:description">
-    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}' property="og:image">
+    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('/logo.png') : asset('images/controlpanel_logo.png') }}' property="og:image">
 
     <!-- CSRF Token -->
     <meta name="csrf-token" content="{{ csrf_token() }}">
 
     <title>{{ config('app.name', 'Laravel') }}</title>
     <link rel="icon"
-        href="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? \Illuminate\Support\Facades\Storage::disk('public')->url('favicon.ico') : asset('favicon.ico') }}"
+        href="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('favicon.ico') }}"
         type="image/x-icon">
 
     <script src="{{ asset('js/app.js') }}" defer></script>

From 9ced34a51b098a5aa9abe04644dcf2256146ebc1 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 31 Jul 2023 15:01:32 +0200
Subject: [PATCH 230/514] available locales is required

---
 app/Settings/LocaleSettings.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Settings/LocaleSettings.php b/app/Settings/LocaleSettings.php
index 81cf2b642..4e38cbe2f 100644
--- a/app/Settings/LocaleSettings.php
+++ b/app/Settings/LocaleSettings.php
@@ -24,7 +24,7 @@ public static function group(): string
     public static function getValidations()
     {
         return [
-            'available' => 'nullable|array',
+            'available' => 'array|required',
             'clients_can_change' => 'nullable|string',
             'datatables' => 'nullable|string',
             'default' => 'required|in:' . implode(',', config('app.available_locales')),

From 4069b5fd355478c6cbba3cb7f4b58bc107bf9add Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 31 Jul 2023 15:08:44 +0200
Subject: [PATCH 231/514] 500 when servercreation is disabled

---
 themes/default/views/servers/create.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 5b8a3f3c3..588da5a40 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -38,7 +38,7 @@ class="row justify-content-center">
                         @if (!$server_creation_enabled)
                             <div class="alert alert-warning p-2 m-2">
                                 {{ __('The creation of new servers has been disabled for regular users, enable it again') }}
-                                <a href="{{ route('admin.settings.system') }}">{{ __('here') }}</a>.
+                                <a href="{{ route('admin.settings.index', "#Server") }}">{{ __('here') }}</a>.
                             </div>
                         @endif
                         @if ($productCount === 0 || $nodeCount === 0 || count($nests) === 0 || count($eggs) === 0)

From 90ebe1468ddc4887715dc1dbc22c10d3a2b34499 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 31 Jul 2023 15:13:26 +0200
Subject: [PATCH 232/514] fix installer mail issue

---
 public/install/forms.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 223b26bfe..98f05657d 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -141,7 +141,7 @@
     ];
 
     foreach ($values as $key => $value) {
-        $query = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '$value' WHERE `name` = '$key' AND `group` = mail";
+        $query = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '$value' WHERE `name` = '$key' AND `group` = 'mail'";
         $db->query($query);
     }
 

From 8fdac0ee46ac7e854c8af895c0cb570c51d2b1e9 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Fri, 15 Sep 2023 13:57:00 -0400
Subject: [PATCH 233/514] feat: :sparkles: Add readable name for permissions

---
 app/Http/Controllers/Admin/UserController.php |  16 +-
 config/permissions_web.php                    | 189 +++++++++---------
 ...add_readable_name_to_permissions_table.php |  32 +++
 database/seeders/PermissionsSeeder.php        |  17 +-
 .../BlueInfinity/views/layouts/main.blade.php |  50 ++---
 .../default/views/admin/roles/edit.blade.php  |  12 +-
 .../default/views/admin/roles/index.blade.php | 127 +++++++-----
 .../views/admin/ticket/index.blade.php        |   6 +-
 themes/default/views/layouts/main.blade.php   |  50 ++---
 9 files changed, 279 insertions(+), 220 deletions(-)
 create mode 100644 database/migrations/2023_09_15_142409_add_readable_name_to_permissions_table.php

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 4956e565c..13898f088 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -38,7 +38,7 @@ class UserController extends Controller
     const CHANGE_USERNAME_PERMISSION = "admin.users.write.username";
     const CHANGE_PASSWORD_PERMISSION = "admin.users.write.password";
     const CHANGE_ROLE_PERMISSION ="admin.users.write.role";
-    const CHANGE_REFERAL_PERMISSION ="admin.users.write.referal";
+    const CHANGE_REFERAL_PERMISSION ="admin.users.write.referral";
     const CHANGE_PTERO_PERMISSION = "admin.users.write.pterodactyl";
     const DELETE_PERMISSION = "admin.users.delete";
     const NOTIFY_PERMISSION = "admin.users.notify";
@@ -361,10 +361,10 @@ public function dataTable(Request $request)
 
         return datatables($query)
             ->addColumn('avatar', function (User $user) {
-                return '<img width="28px" height="28px" class="rounded-circle ml-1" src="' . $user->getAvatar() . '">';
+                return '<img width="28px" height="28px" class="ml-1 rounded-circle" src="' . $user->getAvatar() . '">';
             })
             ->addColumn('credits', function (User $user) {
-                return '<i class="fas fa-coins mr-2"></i> ' . $user->credits();
+                return '<i class="mr-2 fas fa-coins"></i> ' . $user->credits();
             })
             ->addColumn('verified', function (User $user) {
                 return $user->getVerifiedStatus();
@@ -378,10 +378,10 @@ public function dataTable(Request $request)
                 $suspendText = $user->isSuspended() ? __('Unsuspend') : __('Suspend');
 
                 return '
-                <a data-content="' . __('Login as User') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
-                <a data-content="' . __('Verify') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.verifyEmail', $user->id) . '" class="btn btn-sm btn-secondary mr-1"><i class="fas fa-envelope"></i></a>
-                <a data-content="' . __('Show') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
-                <a data-content="' . __('Edit') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                <a data-content="' . __('Login as User') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="mr-1 btn btn-sm btn-primary"><i class="fas fa-sign-in-alt"></i></a>
+                <a data-content="' . __('Verify') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.verifyEmail', $user->id) . '" class="mr-1 btn btn-sm btn-secondary"><i class="fas fa-envelope"></i></a>
+                <a data-content="' . __('Show') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.show', $user->id) . '" class="mr-1 text-white btn btn-sm btn-warning"><i class="fas fa-eye"></i></a>
+                <a data-content="' . __('Edit') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.edit', $user->id) . '" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
                 <form class="d-inline" method="post" action="' . route('admin.users.togglesuspend', $user->id) . '">
                              ' . csrf_field() . '
                             <button data-content="' . $suspendText . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm ' . $suspendColor . ' text-white mr-1"><i class="far ' . $suspendIcon . '"></i></button>
@@ -389,7 +389,7 @@ public function dataTable(Request $request)
                 <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.users.destroy', $user->id) . '">
                              ' . csrf_field() . '
                              ' . method_field('DELETE') . '
-                            <button data-content="' . __('Delete') . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                            <button data-content="' . __('Delete') . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                         </form>
                 ';
             })
diff --git a/config/permissions_web.php b/config/permissions_web.php
index f0918375b..7d63fabdc 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -1,137 +1,138 @@
 <?php
 
 return [
-    '*',
-
     /*
-        * Permissions for admin
-        */
+     * Permissions for admin
+    */
+
+    'All Permissions' => '*',
 
-    'admin.roles.read',
-    'admin.roles.create',
-    'admin.roles.edit',
-    'admin.roles.delete',
+    'View Roles' => 'admin.roles.read',
+    'Create Role' => 'admin.roles.create',
+    'Edit Role' => 'admin.roles.edit',
+    'Delete Role' => 'admin.roles.delete',
 
 
-    'admin.ticket.read',
-    'admin.tickets.write',
-    'admin.tickets.get_notification',
+    'View Tickets' => 'admin.ticket.read',
+    'Manage Ticket' => 'admin.tickets.write',
+    'Receive Ticket Notifications' => 'admin.tickets.get_notification',
 
-    'admin.tickets.category.read',
-    'admin.tickets.category.write',
+    'Create Ticket Category' => 'admin.tickets.category.read',
+    'Manage Ticket Category' => 'admin.tickets.category.write',
 
-    'admin.ticket_blacklist.read',
-    'admin.ticket_blacklist.write',
+    'View Blacklist Tickets' => 'admin.ticket_blacklist.read',
+    'Manage Blacklist Tickets' => 'admin.ticket_blacklist.write',
 
-    'admin.overview.read',
-    'admin.overview.sync',
+    'View Overview' => 'admin.overview.read',
+    'Overview Sync' => 'admin.overview.sync',
 
-    'admin.api.read',
-    'admin.api.write',
+    'View Api Keys' => 'admin.api.read',
+    'Manage Api Keys' => 'admin.api.write',
 
-    'admin.users.read',
-    'admin.users.write',
-    'admin.users.suspend',
-    'admin.users.write.credits',
-    'admin.users.write.username',
-    'admin.users.write.password',
-    'admin.users.write.role',
-    'admin.users.write.referal',
-    'admin.users.write.pterodactyl',
-    'admin.users.write.email',
-    'admin.users.notify',
-    'admin.users.login_as',
-    'admin.users.delete',
+    'View Users' => 'admin.users.read',
+    'Manage Users' => 'admin.users.write',
+    'Suspend Users' => 'admin.users.suspend',
+    'Manage User Credits' => 'admin.users.write.credits',
+    'Manage User Name' => 'admin.users.write.username',
+    'Manage User Email' => 'admin.users.write.email',
+    'Manage User Password' => 'admin.users.write.password',
+    'Manage User Role' => 'admin.users.write.role',
+    'Manage User Referral' => 'admin.users.write.referral',
+    'Manage User Pterodactyl' => 'admin.users.write.pterodactyl',
 
-    'admin.servers.read',
-    'admin.servers.write',
-    'admin.servers.suspend',
-    'admin.servers.write.owner',
-    'admin.servers.write.identifier',
-    'admin.servers.delete',
-    'admin.servers.bypass_creation_enabled',
+    'Notify Users' => 'admin.users.notify',
+    'Login As User' => 'admin.users.login_as',
+    'Delete User' => 'admin.users.delete',
 
-    'admin.products.read',
-    'admin.products.create',
-    'admin.products.edit',
-    'admin.products.delete',
+    'View Servers' => 'admin.servers.read',
+    'Manage Servers' => 'admin.servers.write',
+    'Suspend Server' => 'admin.servers.suspend',
+    'Change Server Owner' => 'admin.servers.write.owner',
+    'Manage Server Identifier' => 'admin.servers.write.identifier',
+    'Create Server' => 'admin.servers.bypass_creation_enabled',
+    'Delete Server' => 'admin.servers.delete',
 
-    'admin.store.read',
-    'admin.store.write',
-    'admin.store.disable',
+    'View Products' => 'admin.products.read',
+    'Create Product' => 'admin.products.create',
+    'Edit Product' => 'admin.products.edit',
+    'Delete Product' => 'admin.products.delete',
 
-    'admin.voucher.read',
-    'admin.voucher.write',
+    'View Store' => 'admin.store.read',
+    'Manage Store' => 'admin.store.write',
+    'Disable Store' => 'admin.store.disable',
 
-    'admin.useful_links.read',
-    'admin.useful_links.write',
+    'View Vouchers' => 'admin.voucher.read',
+    'Manage Voucher' => 'admin.voucher.write',
 
-    'admin.legal.read',
-    'admin.legal.write',
+    'View Useful Links' => 'admin.useful_links.read',
+    'Manage Useful Links' => 'admin.useful_links.write',
 
-    'admin.payments.read',
+    'View Legal' => 'admin.legal.read',
+    'Manage Legal' => 'admin.legal.write',
 
-    'admin.partners.read',
-    'admin.partners.write',
+    'View Payments' => 'admin.payments.read',
 
-    'admin.coupons.read',
-    'admin.coupons.write',
+    'View Partners' => 'admin.partners.read',
+    'Manage Partners' => 'admin.partners.write',
 
-    'admin.logs.read',
+    'View Coupons' => 'admin.coupons.read',
+    'Manage Coupons' => 'admin.coupons.write',
+
+    'View Logs' => 'admin.logs.read',
 
     /*
      * Settings Permissions
-     */
-    'settings.discord.read',
-    'settings.discord.write',
+    */
+    'View Discord Settings' => 'settings.discord.read',
+    'Manage Discord Settings' => 'settings.discord.write',
 
-    'settings.general.read',
-    'settings.general.write',
+    'View General Settings' => 'settings.general.read',
+    'Manage General Settings' => 'settings.general.write',
 
-    'settings.invoice.read',
-    'settings.invoice.write',
+    'View Invoice Settings' => 'settings.invoice.read',
+    'Manage Invoice Settings' => 'settings.invoice.write',
 
-    'settings.locale.read',
-    'settings.locale.write',
+    'View Locale Settings' => 'settings.locale.read',
+    'Manage Locale Settings' => 'settings.locale.write',
 
-    'settings.mail.read',
-    'settings.mail.write',
+    'View Mail Settings' => 'settings.mail.read',
+    'Manage Mail Settings' => 'settings.mail.write',
 
-    'settings.pterodactyl.read',
-    'settings.pterodactyl.write',
+    'View Pterodactyl Settings' => 'settings.pterodactyl.read',
+    'Manage Pterodactyl Settings' => 'settings.pterodactyl.write',
 
-    'settings.referral.read',
-    'settings.referral.write',
+    'View Referral Settings' => 'settings.referral.read',
+    'Manage Referral Settings' => 'settings.referral.write',
 
-    'settings.server.read',
-    'settings.server.write',
+    'View Server Settings' => 'settings.server.read',
+    'Manage Server Settings' => 'settings.server.write',
 
-    'settings.ticket.read',
-    'settings.ticket.write',
+    'View Ticket Settings' => 'settings.ticket.read',
+    'Manage Ticket Settings' => 'settings.ticket.write',
 
-    'settings.user.read',
-    'settings.user.write',
+    'View User Settings' => 'settings.user.read',
+    'Manage User Settings' => 'settings.user.write',
 
-    'settings.website.read',
-    'settings.website.write',
+    'View Website Settings' => 'settings.website.read',
+    'Manage Website Settings' => 'settings.website.write',
 
-    'settings.paypal.read',
-    'settings.paypal.write',
+    'View Paypal Settings' => 'settings.paypal.read',
+    'Manage Paypal Settings' => 'settings.paypal.write',
 
-    'settings.stripe.read',
-    'settings.stripe.write',
+    'View Stripe Settings' => 'settings.stripe.read',
+    'Manage Stripe Settings' => 'settings.stripe.write',
 
-    'settings.mollie.read',
-    'settings.mollie.write',
+    'View Mollie Settings' => 'settings.mollie.read',
+    'Manage Mollie Settings' => 'settings.mollie.write',
 
 
     /*
-    * Permissions for users
+     * Permissions for users
     */
-    'user.server.create',
-    'user.server.upgrade',
-    'user.shop.buy',
-    'user.ticket.read',
-    'user.ticket.write',
-    'user.referral',
+    'User Create Server' => 'user.server.create',
+    'User Upgrade Server' => 'user.server.upgrade',
+    'User Shop Buy' => 'user.shop.buy',
+    'User View Tickets' => 'user.ticket.read',
+    'User Manage Ticket' => 'user.ticket.write',
+    'User View Referral' => 'user.referral',
 ];
diff --git a/database/migrations/2023_09_15_142409_add_readable_name_to_permissions_table.php b/database/migrations/2023_09_15_142409_add_readable_name_to_permissions_table.php
new file mode 100644
index 000000000..473db247e
--- /dev/null
+++ b/database/migrations/2023_09_15_142409_add_readable_name_to_permissions_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('permissions', function (Blueprint $table) {
+            $table->string('readable_name')->after('name');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('permissions', function (Blueprint $table) {
+            $table->removeColumn('readable_name');
+        });
+    }
+};
diff --git a/database/seeders/PermissionsSeeder.php b/database/seeders/PermissionsSeeder.php
index e7738e704..cd3e8f346 100644
--- a/database/seeders/PermissionsSeeder.php
+++ b/database/seeders/PermissionsSeeder.php
@@ -3,7 +3,6 @@
 namespace Database\Seeders;
 
 use App\Models\User;
-use Illuminate\Database\Console\Seeds\WithoutModelEvents;
 use Illuminate\Database\Seeder;
 use Spatie\Permission\Models\Permission;
 use Spatie\Permission\Models\Role;
@@ -24,33 +23,29 @@ public function run()
 
         $users = User::all();
         foreach($users as $user){
-            $user->assignRole(4);
+            $user->assignRole(Role::findByName('user'));
         }
 
         $admins = User::where("role","admin")->get();
         foreach($admins as $admin) {
-            $admin->syncRoles(1);
+            $admin->syncRoles(Role::findByName('Admin'));
         }
 
         $mods = User::where("role","moderator")->get();
         foreach($mods as $mod) {
-            $mod->syncRoles(2);
+            $mod->syncRoles(Role::findByName('Support-Team'));
         }
 
         $clients = User::where("role","client")->get();
         foreach($clients as $client) {
-            $client->syncRoles(3);
+            $client->syncRoles(Role::findByName('Client'));
         }
-
-
-
-
     }
 
     public function createPermissions()
     {
-        foreach (config('permissions_web') as $name) {
-            Permission::findOrCreate($name);
+        foreach(config('permissions_web') as $permission_name => $permission_value) {
+            Permission::create(['name' => $permission_value, 'readable_name' => $permission_name]);
         }
     }
 
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index b6549a7a0..154b9b1dc 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -56,12 +56,12 @@ class="fas fa-bars"></i></a>
             </li>
             <li class="nav-item d-none d-sm-inline-block">
                 <a href="{{ route('home') }}" class="nav-link"><i
-                        class="fas fa-home mr-2"></i>{{ __('Home') }}</a>
+                        class="mr-2 fas fa-home"></i>{{ __('Home') }}</a>
             </li>
             @if (!empty($discord_settings->invite_url))
                 <li class="nav-item d-none d-sm-inline-block">
                     <a href="{{ $discord_settings->invite_url }}" class="nav-link" target="__blank"><i
-                            class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
+                            class="mr-2 fab fa-discord"></i>{{ __('Discord') }}</a>
                 </li>
             @endif
 
@@ -71,13 +71,13 @@ class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                 <li class="nav-item dropdown">
                     <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
                        aria-haspopup="true" aria-expanded="false">
-                            <span class="mr-1 d-lg-inline text-gray-600">
-                                <small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }}
+                            <span class="mr-1 text-gray-600 d-lg-inline">
+                                <small><i class="mr-2 fa fa-language"></i></small>{{ __('Language') }}
                             </span>
                     </a>
-                    <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                    <div class="shadow dropdown-menu dropdown-menu-right animated--grow-in"
                          aria-labelledby="changeLocale">
-                        <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
+                        <form method="post" action="{{ route('changeLocale') }}" class="text-center nav-item">
                             @csrf
                             @foreach (explode(',', $locale_settings->available) as $key)
                                 <button class="dropdown-item" name="inputLocale" value="{{ $key }}">
@@ -99,7 +99,7 @@ class="{{ $link->icon }}"></i> {{ $link->title }}</a>
         </ul>
 
         <!-- Right navbar links -->
-        <ul class="navbar-nav ml-auto">
+        <ul class="ml-auto navbar-nav">
             <!-- Notifications Dropdown Menu -->
             <li class="nav-item dropdown">
                 <a class="nav-link" data-toggle="dropdown" href="#">
@@ -117,9 +117,9 @@ class="badge badge-warning navbar-badge">{{ Auth::user()->unreadNotifications->c
                     @foreach (Auth::user()->unreadNotifications->sortBy('created_at')->take(5) as $notification)
                         <a href="{{ route('notifications.show', $notification->id) }}" class="dropdown-item">
                                 <span class="d-inline-block text-truncate" style="max-width: 150px;"><i
-                                        class="fas fa-envelope mr-2"></i>{{ $notification->data['title'] }}</span>
+                                        class="mr-2 fas fa-envelope"></i>{{ $notification->data['title'] }}</span>
                             <span
-                                class="float-right text-muted text-sm">{{ $notification->created_at->longAbsoluteDiffForHumans() }}
+                                class="float-right text-sm text-muted">{{ $notification->created_at->longAbsoluteDiffForHumans() }}
                                     ago</span>
                         </a>
                     @endforeach
@@ -136,20 +136,20 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
             <li class="nav-item dropdown">
                 <a class="nav-link" href="#" id="userDropdown" role="button" data-toggle="dropdown"
                    aria-haspopup="true" aria-expanded="false">
-                        <span class="mr-1 d-lg-inline text-gray-600">
-                            <small><i class="fas fa-coins mr-2"></i></small>{{ Auth::user()->credits() }}
+                        <span class="mr-1 text-gray-600 d-lg-inline">
+                            <small><i class="mr-2 fas fa-coins"></i></small>{{ Auth::user()->credits() }}
                         </span>
                 </a>
-                <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                <div class="shadow dropdown-menu dropdown-menu-right animated--grow-in"
                      aria-labelledby="userDropdown">
                     <a class="dropdown-item" href="{{ route('store.index') }}">
-                        <i class="fas fa-coins fa-sm fa-fw mr-2 text-gray-400"></i>
+                        <i class="mr-2 text-gray-400 fas fa-coins fa-sm fa-fw"></i>
                         {{ __('Store') }}
                     </a>
                     <div class="dropdown-divider"></div>
                     <a class="dropdown-item" data-toggle="modal" data-target="#redeemVoucherModal"
                        href="javascript:void(0)">
-                        <i class="fas fa-money-check-alt fa-sm fa-fw mr-2 text-gray-400"></i>
+                        <i class="mr-2 text-gray-400 fas fa-money-check-alt fa-sm fa-fw"></i>
                         {{ __('Redeem code') }}
                     </a>
                 </div>
@@ -158,27 +158,27 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
             <li class="nav-item dropdown no-arrow">
                 <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
                    data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                        <span class="mr-1 d-lg-inline text-gray-600 small">
+                        <span class="mr-1 text-gray-600 d-lg-inline small">
                             {{ Auth::user()->name }}
-                            <img width="28px" height="28px" class="rounded-circle ml-1"
+                            <img width="28px" height="28px" class="ml-1 rounded-circle"
                                  src="{{ Auth::user()->getAvatar() }}">
                         </span>
                 </a>
                 <!-- Dropdown - User Information -->
-                <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                <div class="shadow dropdown-menu dropdown-menu-right animated--grow-in"
                      aria-labelledby="userDropdown">
                     <a class="dropdown-item" href="{{ route('profile.index') }}">
-                        <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
+                        <i class="mr-2 text-gray-400 fas fa-user fa-sm fa-fw"></i>
                         {{ __('Profile') }}
                     </a>
                     {{-- <a class="dropdown-item" href="#"> --}}
-                    {{-- <i class="fas fa-list fa-sm fa-fw mr-2 text-gray-400"></i> --}}
+                    {{-- <i class="mr-2 text-gray-400 fas fa-list fa-sm fa-fw"></i> --}}
                     {{-- Activity Log --}}
                     {{-- </a> --}}
                     @if (session()->get('previousUser'))
                         <div class="dropdown-divider"></div>
                         <a class="dropdown-item" href="{{ route('users.logbackin') }}">
-                            <i class="fas fa-sign-in-alt fa-sm fa-fw mr-2 text-gray-400"></i>
+                            <i class="mr-2 text-gray-400 fas fa-sign-in-alt fa-sm fa-fw"></i>
                             {{ __('Log back in') }}
                         </a>
                     @endif
@@ -187,7 +187,7 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                         @csrf
                         <button class="dropdown-item" href="#" data-toggle="modal"
                                 data-target="#logoutModal">
-                            <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
+                            <i class="mr-2 text-gray-400 fas fa-sign-out-alt fa-sm fa-fw"></i>
                             {{ __('Logout') }}
                         </button>
                     </form>
@@ -250,7 +250,7 @@ class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')
                             <li class="nav-item">
                                 <a href="{{ route('ticket.index') }}"
                                    class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
-                                    <i class="nav-icon fas fas fa-ticket-alt"></i>
+                                    <i class="nav-icon fas fa-ticket-alt"></i>
                                     <p>{{ __('Support Ticket') }}</p>
                                 </a>
                             </li>
@@ -357,7 +357,7 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                             'admin.users.write.username',
                             'admin.users.write.password',
                             'admin.users.write.role',
-                            'admin.users.write.referal',
+                            'admin.users.write.referral',
                             'admin.users.write.pterodactyl','admin.servers.read',
                             'admin.servers.write',
                             'admin.servers.suspend',
@@ -379,7 +379,7 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                             'admin.users.write.username',
                             'admin.users.write.password',
                             'admin.users.write.role',
-                            'admin.users.write.referal',
+                            'admin.users.write.referral',
                             'admin.users.write.pterodactyl'])
                         <li class="nav-item">
                             <a href="{{ route('admin.users.index') }}"
@@ -510,7 +510,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
         <!--
             @if (!Auth::user()->hasVerifiedEmail())
             @if (Auth::user()->created_at->diffInHours(now(), false) > 1)
-                <div class="alert alert-warning p-2 m-2">
+                <div class="p-2 m-2 alert alert-warning">
                     <h5><i class="icon fas fa-exclamation-circle"></i> {{ __('Warning!') }}</h5>
                         {{ __('You have not yet verified your email address') }} <a class="text-primary"
                             href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
diff --git a/themes/default/views/admin/roles/edit.blade.php b/themes/default/views/admin/roles/edit.blade.php
index 91fef77df..76dfc3cdd 100644
--- a/themes/default/views/admin/roles/edit.blade.php
+++ b/themes/default/views/admin/roles/edit.blade.php
@@ -1,9 +1,9 @@
 @extends('layouts.main')
 
 @section('content')
-    <div class="main py-4">
+    <div class="py-4 main">
 
-        <div class="card card-body border-0 shadow table-wrapper table-responsive">
+        <div class="border-0 shadow card card-body table-wrapper table-responsive">
             <h2 class="mb-4 h5">{{ isset($role) ?  __('Edit role') : __('Create role') }}</h2>
 
             <form method="post"
@@ -43,14 +43,14 @@
                             multiple>
                             @foreach($permissions as $permission)
                                 <option @if(isset($role) && $role->permissions->contains($permission)) selected
-                                        @endif value="{{$permission->id}}">{{$permission->name}}</option>
+                                        @endif value="{{$permission->id}}">{{$permission->readable_name}}</option>
                             @endforeach
                         </x-input.select>
 
                     </div>
                 </div>
 
-                <div class="form-group d-flex justify-content-end mt-3">
+                <div class="mt-3 form-group d-flex justify-content-end">
                     <button name="submit" type="submit" class="btn btn-primary">{{__('Submit')}}</button>
                 </div>
             </form>
@@ -61,7 +61,9 @@
 
     <script>
         document.addEventListener('DOMContentLoaded', (event) => {
-            $('#permissions').select2();
+            $('#permissions').select2({
+              closeOnSelect: false
+            });
         })
     </script>
 @endsection
diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
index 213a7724d..45412bc5e 100644
--- a/themes/default/views/admin/roles/index.blade.php
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -1,62 +1,91 @@
 @extends('layouts.main')
 
 @section('content')
-    <div class="main py-4">
 
-        @can('admin.roles.write')
-            <div class="d-flex justify-content-end my-3">
-                <a href="{{route('admin.roles.create')}}" class="btn btn-primary"><i
-                        class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
+<section class="content-header">
+    <div class="container-fluid">
+        <div class="mb-2 row">
+            <div class="col-sm-6">
+                <h1>{{__('Create role')}}</h1>
             </div>
-        @endcan
-
-        <div class="card card-body border-0 shadow table-wrapper table-responsive">
-            <h2 class="mb-4 h5">{{ __('Roles') }}</h2>
+            <div class="col-sm-6">
+                <ol class="breadcrumb float-sm-right">
+                    <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
+                    <li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.roles.index')}}">{{__('Roles List')}}</a></li>
+                </ol>
+            </div>
+        </div>
+    </div>
+</section>
 
+<section class="content">
+    <div class="container-fluid">
+        <div class="card">
+            <div class="card-header">
+                <div class="d-flex justify-content-between">
+                    <h5 class="card-title"><i class="mr-2 fas fa-user-check"></i>{{__('Roles List')}}</h5>
+                </div>
+                @can('admin.roles.write')
+                    <a href="{{route('admin.roles.create')}}" class="float-right btn btn-primary"><i class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
+                @endcan
+            </div>
             <div class="card-body table-responsive">
+                <div class="card-body table-responsive">
+                    <table id="datatable" class="table table-striped">
+                        <thead>
+                            <tr>
+                                <th>{{__("ID")}}</th>
+                                <th>{{__("Name")}}</th>
+                                <th>{{__("User count")}}</th>
+                                <th>{{__("Permissions count")}}</th>
+                                <th>{{__("Power")}}</th>
+                                <th>{{__("Actions")}}</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                        </tbody>
+                    </table>
 
-                <table id="datatable" class="table table-striped">
-                    <thead>
-                    <tr>
-                        <th>{{__("ID")}}</th>
-                        <th>{{__("Name")}}</th>
-                        <th>{{__("User count")}}</th>
-                        <th>{{__("Permissions count")}}</th>
-                        <th>{{__("Power")}}</th>
-                        <th>{{__("Actions")}}</th>
-                    </tr>
-                    </thead>
-                    <tbody>
-                    </tbody>
-                </table>
-
+                </div>
             </div>
+
         </div>
     </div>
-@endsection
-<script>
-
-    document.addEventListener("DOMContentLoaded", function () {
-        $('#datatable').DataTable({
-            language: {
-                url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
-            },
-            processing: true,
-            serverSide: true, //increases loading times too much? change back to "true" if it does
-            stateSave: true,
-            ajax: "{{route('admin.roles.datatable')}}",
-            columns: [
-                {data: 'id'},
-                {data: 'name'},
-                {data: 'usercount'},
-                {data: 'permissionscount'},
-                {data: 'power'},
-                {data: 'actions' , sortable : false},
-            ],
-            fnDrawCallback: function( oSettings ) {
-                $('[data-toggle="popover"]').popover();
-            }
+    @endsection
+    <script>
+        document.addEventListener("DOMContentLoaded", function() {
+            $('#datatable').DataTable({
+                language: {
+                    url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
+                },
+                processing: true,
+                serverSide: true, //increases loading times too much? change back to "true" if it does
+                stateSave: true,
+                ajax: "{{route('admin.roles.datatable')}}",
+                columns: [{
+                        data: 'id'
+                    },
+                    {
+                        data: 'name'
+                    },
+                    {
+                        data: 'usercount'
+                    },
+                    {
+                        data: 'permissionscount'
+                    },
+                    {
+                        data: 'power'
+                    },
+                    {
+                        data: 'actions',
+                        sortable: false
+                    }
+                ],
+                fnDrawCallback: function(oSettings) {
+                    $('[data-toggle="popover"]').popover();
+                }
+            });
         });
-    });
-</script>
 
+    </script>
diff --git a/themes/default/views/admin/ticket/index.blade.php b/themes/default/views/admin/ticket/index.blade.php
index 5dc0bb936..17557a5f5 100644
--- a/themes/default/views/admin/ticket/index.blade.php
+++ b/themes/default/views/admin/ticket/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{__('Ticket')}}</h1>
                 </div>
@@ -28,9 +28,9 @@
 
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
-                        <h5 class="card-title"><i class="fas fa-ticket-alt mr-2"></i>{{__('Ticket List')}}</h5>
+                        <h5 class="card-title"><i class="mr-2 fas fa-ticket-alt"></i>{{__('Ticket List')}}</h5>
                     </div>
-                    <a href="{{route("admin.ticket.category.index")}}"><button class="btn btn-primary float-right">+ {{__("Add Category")}}</button></a>
+                    <a href="{{route("admin.ticket.category.index")}}"><button class="float-right btn btn-primary">+ {{__("Add Category")}}</button></a>
                 </div>
 
 
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 9631ef64d..3e2b54d41 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -56,12 +56,12 @@ class="fas fa-bars"></i></a>
                 </li>
                 <li class="nav-item d-none d-sm-inline-block">
                     <a href="{{ route('home') }}" class="nav-link"><i
-                            class="fas fa-home mr-2"></i>{{ __('Home') }}</a>
+                            class="mr-2 fas fa-home"></i>{{ __('Home') }}</a>
                 </li>
                 @if (!empty($discord_settings->invite_url))
                     <li class="nav-item d-none d-sm-inline-block">
                         <a href="{{ $discord_settings->invite_url }}" class="nav-link" target="__blank"><i
-                                class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
+                                class="mr-2 fab fa-discord"></i>{{ __('Discord') }}</a>
                     </li>
                 @endif
 
@@ -71,13 +71,13 @@ class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                     <li class="nav-item dropdown">
                         <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
                             aria-haspopup="true" aria-expanded="false">
-                            <span class="mr-1 d-lg-inline text-gray-600">
-                                <small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }}
+                            <span class="mr-1 text-gray-600 d-lg-inline">
+                                <small><i class="mr-2 fa fa-language"></i></small>{{ __('Language') }}
                             </span>
                         </a>
-                        <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                        <div class="shadow dropdown-menu dropdown-menu-right animated--grow-in"
                             aria-labelledby="changeLocale">
-                            <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
+                            <form method="post" action="{{ route('changeLocale') }}" class="text-center nav-item">
                                 @csrf
                                 @foreach (explode(',', $locale_settings->available) as $key)
                                     <button class="dropdown-item" name="inputLocale" value="{{ $key }}">
@@ -99,7 +99,7 @@ class="{{ $link->icon }}"></i> {{ $link->title }}</a>
             </ul>
 
             <!-- Right navbar links -->
-            <ul class="navbar-nav ml-auto">
+            <ul class="ml-auto navbar-nav">
                 <!-- Notifications Dropdown Menu -->
                 <li class="nav-item dropdown">
                     <a class="nav-link" data-toggle="dropdown" href="#">
@@ -117,9 +117,9 @@ class="badge badge-warning navbar-badge">{{ Auth::user()->unreadNotifications->c
                         @foreach (Auth::user()->unreadNotifications->sortBy('created_at')->take(5) as $notification)
                             <a href="{{ route('notifications.show', $notification->id) }}" class="dropdown-item">
                                 <span class="d-inline-block text-truncate" style="max-width: 150px;"><i
-                                        class="fas fa-envelope mr-2"></i>{{ $notification->data['title'] }}</span>
+                                        class="mr-2 fas fa-envelope"></i>{{ $notification->data['title'] }}</span>
                                 <span
-                                    class="float-right text-muted text-sm">{{ $notification->created_at->longAbsoluteDiffForHumans() }}
+                                    class="float-right text-sm text-muted">{{ $notification->created_at->longAbsoluteDiffForHumans() }}
                                     ago</span>
                             </a>
                         @endforeach
@@ -136,20 +136,20 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                 <li class="nav-item dropdown">
                     <a class="nav-link" href="#" id="userDropdown" role="button" data-toggle="dropdown"
                         aria-haspopup="true" aria-expanded="false">
-                        <span class="mr-1 d-lg-inline text-gray-600">
-                            <small><i class="fas fa-coins mr-2"></i></small>{{ Auth::user()->credits() }}
+                        <span class="mr-1 text-gray-600 d-lg-inline">
+                            <small><i class="mr-2 fas fa-coins"></i></small>{{ Auth::user()->credits() }}
                         </span>
                     </a>
-                    <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                    <div class="shadow dropdown-menu dropdown-menu-right animated--grow-in"
                         aria-labelledby="userDropdown">
                         <a class="dropdown-item" href="{{ route('store.index') }}">
-                            <i class="fas fa-coins fa-sm fa-fw mr-2 text-gray-400"></i>
+                            <i class="mr-2 text-gray-400 fas fa-coins fa-sm fa-fw"></i>
                             {{ __('Store') }}
                         </a>
                         <div class="dropdown-divider"></div>
                         <a class="dropdown-item" data-toggle="modal" data-target="#redeemVoucherModal"
                             href="javascript:void(0)">
-                            <i class="fas fa-money-check-alt fa-sm fa-fw mr-2 text-gray-400"></i>
+                            <i class="mr-2 text-gray-400 fas fa-money-check-alt fa-sm fa-fw"></i>
                             {{ __('Redeem code') }}
                         </a>
                     </div>
@@ -158,27 +158,27 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                 <li class="nav-item dropdown no-arrow">
                     <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
                         data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                        <span class="mr-1 d-lg-inline text-gray-600 small">
+                        <span class="mr-1 text-gray-600 d-lg-inline small">
                             {{ Auth::user()->name }}
-                            <img width="28px" height="28px" class="rounded-circle ml-1"
+                            <img width="28px" height="28px" class="ml-1 rounded-circle"
                                 src="{{ Auth::user()->getAvatar() }}">
                         </span>
                     </a>
                     <!-- Dropdown - User Information -->
-                    <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                    <div class="shadow dropdown-menu dropdown-menu-right animated--grow-in"
                         aria-labelledby="userDropdown">
                         <a class="dropdown-item" href="{{ route('profile.index') }}">
-                            <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
+                            <i class="mr-2 text-gray-400 fas fa-user fa-sm fa-fw"></i>
                             {{ __('Profile') }}
                         </a>
                         {{-- <a class="dropdown-item" href="#"> --}}
-                        {{-- <i class="fas fa-list fa-sm fa-fw mr-2 text-gray-400"></i> --}}
+                        {{-- <i class="mr-2 text-gray-400 fas fa-list fa-sm fa-fw"></i> --}}
                         {{-- Activity Log --}}
                         {{-- </a> --}}
                         @if (session()->get('previousUser'))
                             <div class="dropdown-divider"></div>
                             <a class="dropdown-item" href="{{ route('users.logbackin') }}">
-                                <i class="fas fa-sign-in-alt fa-sm fa-fw mr-2 text-gray-400"></i>
+                                <i class="mr-2 text-gray-400 fas fa-sign-in-alt fa-sm fa-fw"></i>
                                 {{ __('Log back in') }}
                             </a>
                         @endif
@@ -187,7 +187,7 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                             @csrf
                             <button class="dropdown-item" href="#" data-toggle="modal"
                                 data-target="#logoutModal">
-                                <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
+                                <i class="mr-2 text-gray-400 fas fa-sign-out-alt fa-sm fa-fw"></i>
                                 {{ __('Logout') }}
                             </button>
                         </form>
@@ -250,7 +250,7 @@ class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')
                             <li class="nav-item">
                                 <a href="{{ route('ticket.index') }}"
                                     class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
-                                    <i class="nav-icon fas fas fa-ticket-alt"></i>
+                                    <i class="nav-icon fas fa-ticket-alt"></i>
                                     <p>{{ __('Support Ticket') }}</p>
                                 </a>
                             </li>
@@ -357,7 +357,7 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                                 'admin.users.write.username',
                                 'admin.users.write.password',
                                 'admin.users.write.role',
-                                'admin.users.write.referal',
+                                'admin.users.write.referral',
                                 'admin.users.write.pterodactyl','admin.servers.read',
                                 'admin.servers.write',
                                 'admin.servers.suspend',
@@ -379,7 +379,7 @@ class="nav-link @if (Request::routeIs('admin.api.*')) active @endif">
                                 'admin.users.write.username',
                                 'admin.users.write.password',
                                 'admin.users.write.role',
-                                'admin.users.write.referal',
+                                'admin.users.write.referral',
                                 'admin.users.write.pterodactyl'])
                             <li class="nav-item">
                                 <a href="{{ route('admin.users.index') }}"
@@ -520,7 +520,7 @@ class="nav-link @if (Request::routeIs('admin.activitylogs.*')) active @endif">
             <!--
             @if (!Auth::user()->hasVerifiedEmail())
                 @if (Auth::user()->created_at->diffInHours(now(), false) > 1)
-                    <div class="alert alert-warning p-2 m-2">
+                    <div class="p-2 m-2 alert alert-warning">
                         <h5><i class="icon fas fa-exclamation-circle"></i> {{ __('Warning!') }}</h5>
                         {{ __('You have not yet verified your email address') }} <a class="text-primary"
                             href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>

From 7ecc29487e82d076e6cc1658d9e778970471133e Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sat, 16 Sep 2023 13:20:31 -0400
Subject: [PATCH 234/514] fix: :bug: Fix infinite credit exploit when checking
 email several times.

---
 .../Controllers/Auth/RegisterController.php   |  9 ++--
 app/Models/User.php                           |  6 ++-
 app/Providers/EventServiceProvider.php        |  7 ++--
 config/view.php                               |  2 +-
 themes/default/views/profile/index.blade.php  | 42 +++++++++----------
 5 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php
index 566d86fd5..b315f8d77 100644
--- a/app/Http/Controllers/Auth/RegisterController.php
+++ b/app/Http/Controllers/Auth/RegisterController.php
@@ -22,6 +22,7 @@
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\Str;
 use Illuminate\Validation\ValidationException;
+use Spatie\Permission\Models\Role;
 
 class RegisterController extends Controller
 {
@@ -139,7 +140,7 @@ protected function create(array $data)
 
         ]);
 
-        $user->syncRoles(4);
+        $user->syncRoles(Role::findByName('User'));
 
         $response = $this->pterodactyl->application->post('/application/users', [
             'external_id' => null,
@@ -151,15 +152,11 @@ protected function create(array $data)
             'root_admin' => false,
             'language' => 'en',
         ]);
-        
+
         $user->update([
             'pterodactyl_id' => $response->json()['attributes']['id'],
         ]);
 
-
-
-
-
         if ($response->failed()) {
             $user->delete();
             Log::error('Pterodactyl Registration Error: ' . $response->json()['errors'][0]['detail']);
diff --git a/app/Models/User.php b/app/Models/User.php
index 7c04a65bb..584da0151 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -66,6 +66,7 @@ class User extends Authenticatable implements MustVerifyEmail
         'avatar',
         'suspended',
         'referral_code',
+        'email_verified_reward',
     ];
 
     /**
@@ -88,6 +89,7 @@ class User extends Authenticatable implements MustVerifyEmail
         'last_seen' => 'datetime',
         'credits' => 'float',
         'server_limit' => 'float',
+        'email_verified_reward' => 'boolean'
     ];
 
     public function __construct()
@@ -280,9 +282,8 @@ public function getVerifiedStatus()
 
     public function verifyEmail()
     {
-
         $this->forceFill([
-            'email_verified_at' => now(),
+            'email_verified_at' => now()
         ])->save();
     }
 
@@ -290,6 +291,7 @@ public function reVerifyEmail()
     {
         $this->forceFill([
             'email_verified_at' => null,
+            'email_verified_reward' => true
         ])->save();
     }
 
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index 2ac9182dd..cc535566a 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -9,9 +9,10 @@
 use App\Listeners\CreateInvoice;
 use App\Listeners\UnsuspendServers;
 use App\Listeners\UserPayment;
-use App\Listeners\Verified;
+use App\Listeners\Verified as ListenerVerified;
 use Illuminate\Auth\Events\Registered;
 use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
+use Illuminate\Auth\Events\Verified;
 use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
 use SocialiteProviders\Manager\SocialiteWasCalled;
 
@@ -40,8 +41,8 @@ class EventServiceProvider extends ServiceProvider
             // ... other providers
             'SocialiteProviders\\Discord\\DiscordExtendSocialite@handle',
         ],
-        'Illuminate\Auth\Events\Verified' => [
-            Verified::class,
+        Verified::class => [
+            ListenerVerified::class,
         ],
     ];
 
diff --git a/config/view.php b/config/view.php
index 22b8a18d3..b9b20d53d 100644
--- a/config/view.php
+++ b/config/view.php
@@ -14,7 +14,7 @@
     */
 
     'paths' => [
-        resource_path('views'),
+        base_path('themes'),
     ],
 
     /*
diff --git a/themes/default/views/profile/index.blade.php b/themes/default/views/profile/index.blade.php
index ba95bca44..14117343d 100644
--- a/themes/default/views/profile/index.blade.php
+++ b/themes/default/views/profile/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{ __('Profile') }}</h1>
                 </div>
@@ -26,9 +26,9 @@
         <div class="container-fluid">
 
             <div class="row">
-                <div class="col-lg-12 px-0">
-                    @if (!Auth::user()->hasVerifiedEmail() && strtolower($force_email_verification) == 'true')
-                        <div class="alert alert-warning p-2 m-2">
+                <div class="px-0 col-lg-12">
+                    @if (!Auth::user()->hasVerifiedEmail() && $force_email_verification)
+                        <div class="p-2 m-2 alert alert-warning">
                             <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Email verification!') }}
                             </h5>
                             {{ __('You have not yet verified your email address') }}
@@ -40,9 +40,9 @@
                         </div>
                     @endif
 
-                    @if (is_null(Auth::user()->discordUser) && strtolower($force_discord_verification) == 'true')
+                    @if (is_null(Auth::user()->discordUser) && $force_discord_verification)
                         @if (!empty($discord_client_id) && !empty($discord_client_secret))
-                            <div class="alert alert-warning p-2 m-2">
+                            <div class="p-2 m-2 alert alert-warning">
                                 <h5>
                                     <i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
                                 </h5>
@@ -52,7 +52,7 @@
                                 {{ __('Please contact support If you face any issues.') }}
                             </div>
                         @else
-                            <div class="alert alert-danger p-2 m-2">
+                            <div class="p-2 m-2 alert alert-danger">
                                 <h5>
                                     <i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
                                 </h5>
@@ -72,8 +72,8 @@
                     <div class="card-body">
                         <div class="e-profile">
                             <div class="row">
-                                <div class="col-12 col-sm-auto mb-4">
-                                    <div class="slim rounded-circle  border-secondary border text-gray-dark"
+                                <div class="mb-4 col-12 col-sm-auto">
+                                    <div class="border slim rounded-circle border-secondary text-gray-dark"
                                          data-label="Change your avatar" data-max-file-size="3"
                                          data-save-initial-image="true"
                                          style="width: 140px;height:140px; cursor: pointer"
@@ -81,9 +81,9 @@
                                         <img src="{{ $user->getAvatar() }}" alt="avatar">
                                     </div>
                                 </div>
-                                <div class="col d-flex flex-column flex-sm-row justify-content-between mb-3">
-                                    <div class="text-center text-sm-left mb-2 mb-sm-0">
-                                        <h4 class="pt-sm-2 pb-1 mb-0 text-nowrap">{{ $user->name }}</h4>
+                                <div class="mb-3 col d-flex flex-column flex-sm-row justify-content-between">
+                                    <div class="mb-2 text-center text-sm-left mb-sm-0">
+                                        <h4 class="pb-1 mb-0 pt-sm-2 text-nowrap">{{ $user->name }}</h4>
                                         <p class="mb-0">{{ $user->email }}
                                             @if ($user->hasVerifiedEmail())
                                                 <i data-toggle="popover" data-trigger="hover" data-content="Verified"
@@ -97,21 +97,21 @@ class="text-danger fas fa-exclamation-circle"></i>
                                         </p>
                                         <div class="mt-1">
                                             <span class="badge badge-primary"><i
-                                                    class="fa fa-coins mr-2"></i>{{ $user->Credits() }}</span>
+                                                    class="mr-2 fa fa-coins"></i>{{ $user->Credits() }}</span>
                                         </div>
 
                                     @if($referral_enabled)
                                         @can("user.referral")
                                             <div class="mt-1">
                                                     <span class="badge badge-success"><i
-                                                            class="fa fa-user-check mr-2"></i>
+                                                            class="mr-2 fa fa-user-check"></i>
                                                         {{__("Referral URL")}} :
                                                         <span onclick="onClickCopy()" id="RefLink" style="cursor: pointer;">
                                                             {{route("register")}}?ref={{$user->referral_code}}</span>
                                                     </span>
                                                 @else
                                                     <span class="badge badge-warning"><i
-                                                            class="fa fa-user-check mr-2"></i>
+                                                            class="mr-2 fa fa-user-check"></i>
                                                         {{__("You can not see your Referral Code")}}</span>
                                         @endcan
                                             </div>
@@ -138,7 +138,7 @@ class="fa fa-user-check mr-2"></i>
                                                             class="active nav-link">{{ __('Settings') }}</a>
                                     </li>
                                 </ul>
-                                <div class="tab-content pt-3">
+                                <div class="pt-3 tab-content">
                                     <div class="tab-pane active">
                                         <div class="row">
                                             <div class="col">
@@ -189,7 +189,7 @@ class="form-control @error('email') is-invalid @enderror"
                                             </div>
                                         </div>
                                         <div class="row">
-                                            <div class="col-12 col-sm-6 mb-3">
+                                            <div class="mb-3 col-12 col-sm-6">
                                                 <div class="mb-3"><b>{{ __('Change Password') }}</b></div>
                                                 <div class="row">
                                                     <div class="col">
@@ -242,7 +242,7 @@ class="form-control @error('new_password_confirmation') is-invalid @enderror"
                                                 </div>
                                             </div>
                                             @if (!empty($discord_client_id) && !empty($discord_client_secret))
-                                                <div class="col-12 col-sm-5 offset-sm-1 mb-3">
+                                                <div class="mb-3 col-12 col-sm-5 offset-sm-1">
                                                     @if (is_null(Auth::user()->discordUser))
                                                         <b>{{ __('Link your discord account!') }}</b>
                                                         <div class="verify-discord">
@@ -255,7 +255,7 @@ class="form-control @error('new_password_confirmation') is-invalid @enderror"
                                                         </div>
 
                                                         <a class="btn btn-light" href="{{ route('auth.redirect') }}">
-                                                            <i class="fab fa-discord mr-2"></i>{{ __('Login with Discord') }}
+                                                            <i class="mr-2 fab fa-discord"></i>{{ __('Login with Discord') }}
                                                         </a>
                                                     @else
                                                         <div class="verified-discord">
@@ -263,7 +263,7 @@ class="form-control @error('new_password_confirmation') is-invalid @enderror"
                                                                 <p>{{ __('You are verified!') }}</p>
                                                             </div>
                                                         </div>
-                                                        <div class="row pl-2">
+                                                        <div class="pl-2 row">
                                                             <div class="small-box bg-dark">
                                                                 <div class="d-flex justify-content-between">
                                                                     <div class="p-3">
@@ -282,7 +282,7 @@ class="rounded-circle"
                                                                 <div class="small-box-footer">
                                                                     <a href="{{ route('auth.redirect') }}">
                                                                         <i
-                                                                            class="fab fa-discord mr-1"></i>{{ __('Re-Sync Discord') }}
+                                                                            class="mr-1 fab fa-discord"></i>{{ __('Re-Sync Discord') }}
                                                                     </a>
                                                                 </div>
                                                             </div>

From a471cb4021d9a9c919651c96333bd343bb7421f0 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 17 Sep 2023 13:01:37 -0400
Subject: [PATCH 235/514] fix: :bug: fix #901

---
 app/Http/Controllers/Admin/PaymentController.php | 11 ++++++++---
 app/Listeners/UserPayment.php                    |  2 +-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 850f5a93d..66292bd53 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -143,14 +143,19 @@ public function pay(Request $request)
             $subtotal = $shopProduct->price;
 
             // Apply Coupon
-            $isCouponValid = $this->isCouponValid($couponCode, $user, $shopProduct->id);
-            if ($isCouponValid) {
-                $subtotal = $this->applyCoupon($couponCode, $subtotal);
+            if ($couponCode) {
+                if ($this->isCouponValid($couponCode, $user, $shopProduct->id)) {
+                    $subtotal = $this->applyCoupon($couponCode, $subtotal);
+                }
             }
 
             // Apply Partner Discount
             $subtotal = $subtotal - ($subtotal * $discount / 100);
             if ($subtotal <= 0) {
+                if ($couponCode) {
+                    event(new CouponUsedEvent($couponCode));
+                }
+
                 return $this->handleFreeProduct($shopProduct);
             }
 
diff --git a/app/Listeners/UserPayment.php b/app/Listeners/UserPayment.php
index 9e1066ef1..476573e19 100644
--- a/app/Listeners/UserPayment.php
+++ b/app/Listeners/UserPayment.php
@@ -49,7 +49,7 @@ public function handle(PaymentEvent $event)
         $shopProduct = $event->shopProduct;
 
         // only update user if payment is paid
-        if ($event->payment->status != PaymentStatus::PAID) {
+        if ($event->payment->status != PaymentStatus::PAID->value) {
             return;
         }
 

From 04940f040b43cee6f9137a025fc4fa8812e577be Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 17 Sep 2023 14:31:14 -0400
Subject: [PATCH 236/514] Aways check if has coupon code in the request.

---
 app/Http/Controllers/Admin/PaymentController.php | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 66292bd53..0b11597ef 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -180,7 +180,10 @@ public function pay(Request $request)
 
             $paymentGatewayExtension = ExtensionHelper::getExtensionClass($paymentGateway);
             $redirectUrl = $paymentGatewayExtension::getRedirectUrl($payment, $shopProduct, $totalPriceString);
-            event(new CouponUsedEvent($couponCode));
+
+            if ($couponCode) {
+                event(new CouponUsedEvent($couponCode));
+            }
         } catch (Exception $e) {
             Log::error($e->getMessage());
             return redirect()->route('store.index')->with('error', __('Oops, something went wrong! Please try again later.'));

From 22413c3b30e53e390edab63f4fb684801698dc51 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 17 Sep 2023 14:33:21 -0400
Subject: [PATCH 237/514] Remove unneeded function

---
 app/Traits/Coupon.php | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php
index 5dd0e7e97..f1d06d27d 100644
--- a/app/Traits/Coupon.php
+++ b/app/Traits/Coupon.php
@@ -95,27 +95,6 @@ public function isCouponValid(string $couponCode, User $user, string $productId)
         return true;
     }
 
-    public function calcDiscount($productPrice, stdClass $data)
-    {
-
-        if ($data->isValid) {
-            if ($data->couponType === 'percentage') {
-                return $productPrice - ($productPrice * $data->couponValue / 100);
-            }
-
-            if ($data->couponType === 'amount') {
-                // There is no discount if the value of the coupon is greater than or equal to the value of the product.
-                if ($data->couponValue >= $productPrice) {
-                    return $productPrice;
-                }
-            }
-
-            return $productPrice - $data->couponValue;
-        }
-
-        return $productPrice;
-    }
-
     public function applyCoupon(string $couponCode, float $price)
     {
         $coupon = CouponModel::where('code', $couponCode)->first();

From fac8668fb8249f9d43f2942995d7ec90badc198d Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Tue, 19 Sep 2023 10:18:12 -0400
Subject: [PATCH 238/514] fix: :bug: Fix role search

---
 app/Http/Controllers/Admin/RoleController.php | 11 ++++-----
 app/Http/Controllers/Admin/UserController.php |  2 +-
 app/Http/Controllers/Api/RoleController.php   |  2 +-
 app/Models/Permission.php                     | 22 ++++++++++++++++++
 app/Models/Role.php                           | 23 +++++++++++++++++++
 config/permission.php                         |  4 ++--
 .../2023_05_05_090127_role_power.php          |  6 -----
 database/seeders/PermissionsSeeder.php        | 11 +++++----
 .../default/views/admin/roles/index.blade.php |  4 ++--
 9 files changed, 63 insertions(+), 22 deletions(-)
 create mode 100644 app/Models/Permission.php
 create mode 100644 app/Models/Role.php

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index b10c1b012..b2c685f44 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -11,8 +11,8 @@
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
-use Spatie\Permission\Models\Permission;
-use Spatie\Permission\Models\Role;
+use App\Models\Permission;
+use App\Models\Role;
 
 class RoleController extends Controller
 {
@@ -182,8 +182,7 @@ public function destroy(Role $role)
      */
     public function dataTable()
     {
-        $query = Role::query()->withCount(['users', 'permissions']);
-
+        $query = Role::query()->withCount(['users', 'permissions'])->get();
 
         return datatables($query)
             ->editColumn('id', function (Role $role) {
@@ -205,10 +204,10 @@ class="fa fas fa-trash"></i></button>
             ->editColumn('name', function (Role $role) {
                 return "<span style='background-color: $role->color' class='badge'>$role->name</span>";
             })
-            ->editColumn('usercount', function ($query) {
+            ->editColumn('users_count', function ($query) {
                 return $query->users_count;
             })
-            ->editColumn('permissionscount', function ($query){
+            ->editColumn('permissions_count', function ($query){
                 return $query->permissions_count;
             })
             ->editColumn('power', function (Role $role){
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 13898f088..2cc535cea 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -26,7 +26,7 @@
 use Illuminate\Validation\Rule;
 use Illuminate\Validation\ValidationException;
 use Spatie\QueryBuilder\QueryBuilder;
-use Spatie\Permission\Models\Role;
+use App\Models\Role;
 
 class UserController extends Controller
 {
diff --git a/app/Http/Controllers/Api/RoleController.php b/app/Http/Controllers/Api/RoleController.php
index 928473f8d..ac44c240f 100644
--- a/app/Http/Controllers/Api/RoleController.php
+++ b/app/Http/Controllers/Api/RoleController.php
@@ -10,7 +10,7 @@
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Validation\Rule;
-use Spatie\Permission\Models\Role;
+use App\Models\Role;
 use Spatie\QueryBuilder\QueryBuilder;
 
 class RoleController extends Controller
diff --git a/app/Models/Permission.php b/app/Models/Permission.php
new file mode 100644
index 000000000..38ed7d427
--- /dev/null
+++ b/app/Models/Permission.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Spatie\Permission\Models\Permission as BasePermission;
+
+class Permission extends BasePermission
+{
+    use HasFactory;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array<int, string>
+     */
+    protected $fillable = [
+        'name',
+        'guard_name',
+        'readable_name'
+    ];
+}
diff --git a/app/Models/Role.php b/app/Models/Role.php
new file mode 100644
index 000000000..a3b7e6e10
--- /dev/null
+++ b/app/Models/Role.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Spatie\Permission\Models\Role as BaseRole;
+
+class Role extends BaseRole
+{
+    use HasFactory;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array<int, string>
+     */
+    protected $fillable = [
+        'name',
+        'guard_name',
+        'power',
+        'color'
+    ];
+}
diff --git a/config/permission.php b/config/permission.php
index 5aeaab7c8..f06debdc4 100644
--- a/config/permission.php
+++ b/config/permission.php
@@ -13,7 +13,7 @@
          * `Spatie\Permission\Contracts\Permission` contract.
          */
 
-        'permission' => Spatie\Permission\Models\Permission::class,
+        'permission' => App\Models\Permission::class,
 
         /*
          * When using the "HasRoles" trait from this package, we need to know which
@@ -24,7 +24,7 @@
          * `Spatie\Permission\Contracts\Role` contract.
          */
 
-        'role' => Spatie\Permission\Models\Role::class,
+        'role' => App\Models\Role::class,
 
     ],
 
diff --git a/database/migrations/2023_05_05_090127_role_power.php b/database/migrations/2023_05_05_090127_role_power.php
index 7eb0d9113..9c8da51d0 100644
--- a/database/migrations/2023_05_05_090127_role_power.php
+++ b/database/migrations/2023_05_05_090127_role_power.php
@@ -2,7 +2,6 @@
 
 use Illuminate\Database\Migrations\Migration;
 use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\Schema;
 
 return new class extends Migration
@@ -17,11 +16,6 @@ public function up()
         Schema::table('roles', function (Blueprint $table) {
             $table->integer('power')->after("color")->default(50);
         });
-
-        Artisan::call('db:seed', [
-            '--class' => 'PermissionsSeeder',
-            '--force' => true
-        ]);
     }
 
     /**
diff --git a/database/seeders/PermissionsSeeder.php b/database/seeders/PermissionsSeeder.php
index cd3e8f346..5ddef8f4d 100644
--- a/database/seeders/PermissionsSeeder.php
+++ b/database/seeders/PermissionsSeeder.php
@@ -6,6 +6,7 @@
 use Illuminate\Database\Seeder;
 use Spatie\Permission\Models\Permission;
 use Spatie\Permission\Models\Role;
+use Spatie\Permission\PermissionRegistrar;
 
 class PermissionsSeeder extends Seeder
 {
@@ -16,6 +17,8 @@ class PermissionsSeeder extends Seeder
      */
     public function run()
     {
+        // Reset cached roles and permissions.
+        app()[PermissionRegistrar::class]->forgetCachedPermissions();
 
         $this->createPermissions();
         $this->createRoles();
@@ -61,10 +64,10 @@ public function createRoles()
             'user.referral',
         ];
         /** @var Role $adminRole */
-        $adminRole = Role::updateOrCreate(["name"=>"Admin","color"=>"#fa0000", "power"=>100]);
-        $supportRole = Role::updateOrCreate(["name"=>"Support-Team","color"=>"#00b0b3","power"=>50]);
-        $clientRole = Role::updateOrCreate(["name"=>"Client","color"=>"#008009","power"=>10]);
-        $userRole =  Role::updateOrCreate(["name"=>"User","color"=>"#0052a3","power"=>10]);
+        $adminRole = Role::create(["name"=>"Admin","color"=>"#fa0000", "power"=>100]);
+        $supportRole = Role::create(["name"=>"Support-Team","color"=>"#00b0b3","power"=>50]);
+        $clientRole = Role::create(["name"=>"Client","color"=>"#008009","power"=>10]);
+        $userRole =  Role::create(["name"=>"User","color"=>"#0052a3","power"=>10]);
 
         $adminRole->givePermissionTo(Permission::findByName('*'));
 
diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
index 45412bc5e..0fc9d8002 100644
--- a/themes/default/views/admin/roles/index.blade.php
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -69,10 +69,10 @@
                         data: 'name'
                     },
                     {
-                        data: 'usercount'
+                        data: 'users_count'
                     },
                     {
-                        data: 'permissionscount'
+                        data: 'permissions_count'
                     },
                     {
                         data: 'power'

From ee5b99ce7153f25a007274e50cf73cb7c892a3f1 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 1 Oct 2023 09:59:32 -0400
Subject: [PATCH 239/514] fix: :bug: Fix the infinite credits exploit in
 development.

---
 app/Listeners/Verified.php | 4 ++--
 app/Models/User.php        | 3 +--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/app/Listeners/Verified.php b/app/Listeners/Verified.php
index 9ed9bf37d..c6e759127 100644
--- a/app/Listeners/Verified.php
+++ b/app/Listeners/Verified.php
@@ -7,7 +7,6 @@
 class Verified
 {
     private $server_limit_after_verify_email;
-
     private $credits_reward_after_verify_email;
 
     /**
@@ -29,9 +28,10 @@ public function __construct(UserSettings $user_settings)
      */
     public function handle($event)
     {
-        if (! $event->user->email_verified_reward) {
+        if (!$event->user->email_verified_reward) {
             $event->user->increment('server_limit', $this->server_limit_after_verify_email);
             $event->user->increment('credits', $this->credits_reward_after_verify_email);
+            $event->user->update(['email_verified_reward' => true]);
         }
     }
 }
diff --git a/app/Models/User.php b/app/Models/User.php
index 584da0151..246cb0c5a 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -290,8 +290,7 @@ public function verifyEmail()
     public function reVerifyEmail()
     {
         $this->forceFill([
-            'email_verified_at' => null,
-            'email_verified_reward' => true
+            'email_verified_at' => null
         ])->save();
     }
 

From 754d4f178fe57799feec6f314935cea61cadec17 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 22 Oct 2023 11:11:49 -0400
Subject: [PATCH 240/514] Add encrypted migrations and closes #897

---
 ...23_03_26_215801_create_mollie_settings.php |  2 +-
 ...3_03_04_135248_create_pay_pal_settings.php |  8 ++--
 ...23_03_04_181917_create_stripe_settings.php |  4 +-
 app/Settings/MailSettings.php                 |  9 +++-
 ..._01_181334_create_pterodactyl_settings.php |  4 +-
 ...2023_02_01_181453_create_mail_settings.php |  2 +-
 .../views/admin/settings/index.blade.php      | 44 +++++++++++--------
 7 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php b/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php
index b32027e30..a3b6bfd04 100644
--- a/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php
+++ b/app/Extensions/PaymentGateways/Mollie/migrations/2023_03_26_215801_create_mollie_settings.php
@@ -6,7 +6,7 @@ class CreateMollieSettings extends SettingsMigration
 {
     public function up(): void
     {
-        $this->migrator->add('mollie.api_key', null);
+        $this->migrator->addEncrypted('mollie.api_key', null);
         $this->migrator->add('mollie.enabled', false);
     }
 
diff --git a/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php b/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
index 3c0110579..db7d0bdd5 100644
--- a/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
+++ b/app/Extensions/PaymentGateways/PayPal/migrations/2023_03_04_135248_create_pay_pal_settings.php
@@ -11,10 +11,10 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
 
-        $this->migrator->add('paypal.client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') : null);
-        $this->migrator->add('paypal.client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SECRET') : null);
-        $this->migrator->add('paypal.sandbox_client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') : null);
-        $this->migrator->add('paypal.sandbox_client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') : null);
+        $this->migrator->addEncrypted('paypal.client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') : null);
+        $this->migrator->addEncrypted('paypal.client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SECRET') : null);
+        $this->migrator->addEncrypted('paypal.sandbox_client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') : null);
+        $this->migrator->addEncrypted('paypal.sandbox_client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') : null);
         $this->migrator->add('paypal.enabled', false);
     }
 
diff --git a/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php b/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
index 1483732b4..c320c80db 100644
--- a/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
+++ b/app/Extensions/PaymentGateways/Stripe/migrations/2023_03_04_181917_create_stripe_settings.php
@@ -9,9 +9,9 @@ public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
-        $this->migrator->add('stripe.secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:SECRET') : null);
+        $this->migrator->addEncrypted('stripe.secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:SECRET') : null);
         $this->migrator->add('stripe.endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') : null);
-        $this->migrator->add('stripe.test_secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') : null);
+        $this->migrator->addEncrypted('stripe.test_secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') : null);
         $this->migrator->add('stripe.test_endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET') : null);
         $this->migrator->add('stripe.enabled', false);
     }
diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php
index 1ea8309da..90b5a3283 100644
--- a/app/Settings/MailSettings.php
+++ b/app/Settings/MailSettings.php
@@ -80,12 +80,17 @@ public static function getOptionInputData()
             ],
             'mail_password' => [
                 'label' => 'Mail Password',
-                'type' => 'string',
+                'type' => 'password',
                 'description' => 'The password of your mail server.',
             ],
             'mail_encryption' => [
                 'label' => 'Mail Encryption',
-                'type' => 'string',
+                'type' => 'select',
+                'options' => [
+                    'null' => 'None',
+                    'tls' => 'TLS',
+                    'ssl' => 'SSL'
+                ],
                 'description' => 'The encryption of your mail server.',
             ],
             'mail_from_address' => [
diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index 3de541759..f3b5b37d2 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -10,8 +10,8 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
-        $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
+        $this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
+        $this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
         $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL') : env('PTERODACTYL_URL', ''));
         $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT') : 200);
     }
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index 56953b780..8437a61ae 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -13,7 +13,7 @@ public function up(): void
         $this->migrator->add('mail.mail_host', $table_exists ? $this->getOldValue('SETTINGS::MAIL:HOST') : env('MAIL_HOST', 'localhost'));
         $this->migrator->add('mail.mail_port', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PORT') : env('MAIL_PORT', 25));
         $this->migrator->add('mail.mail_username', $table_exists ? $this->getOldValue('SETTINGS::MAIL:USERNAME') : env('MAIL_USERNAME', ''));
-        $this->migrator->add('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
+        $this->migrator->addEncrypted('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
         $this->migrator->add('mail.mail_encryption', $table_exists ? $this->getOldValue('SETTINGS::MAIL:ENCRYPTION') : env('MAIL_ENCRYPTION', 'tls'));
         $this->migrator->add('mail.mail_from_address', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_ADDRESS') : env('MAIL_FROM_ADDRESS', 'example@example.com'));
         $this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'CtrlPanel.gg'));
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 78454fd7c..799e426de 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{ __('Settings') }}</h1>
                 </div>
@@ -37,13 +37,13 @@
             <div class="card">
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
-                        <h5 class="card-title"><i class="fas fa-tools mr-2"></i>{{ __('Settings') }}</h5>
+                        <h5 class="card-title"><i class="mr-2 fas fa-tools"></i>{{ __('Settings') }}</h5>
                     </div>
                 </div>
                 <div class="card-body">
                     <!-- Sidebar Menu -->
                     <div class="d-flex w-100">
-                        <div class="col-2 p-0">
+                        <div class="p-0 col-2">
                             <nav class="mt-1">
                                 <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                     data-accordion="false">
@@ -109,17 +109,17 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                         </div>
                         <!-- /.sidebar-menu -->
                         <!-- Content in $settings -->
-                        <div class="col-10 p-0">
-                            <div class="tab-content ml-3" style="width: 100%;">
-                                <div container class="tab-pane fade container" id="icons" role="tabpanel">
+                        <div class="p-0 col-10">
+                            <div class="ml-3 tab-content" style="width: 100%;">
+                                <div container class="container tab-pane fade" id="icons" role="tabpanel">
 
                                     <form method="POST" enctype="multipart/form-data" class="mb-3"
                                         action="{{ route('admin.settings.updateIcons') }}">
                                         @csrf
                                         @method('POST')
                                         <div class="row">
-                                            <div class="card ml-5" style="width: 18rem;">
-                                                <span class="h3 text-center">{{ __('FavIcon') }} </span>
+                                            <div class="ml-5 card" style="width: 18rem;">
+                                                <span class="text-center h3">{{ __('FavIcon') }} </span>
                                               <img src="{{ Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('images/controlpanel_logo.png') }}"
                                                    style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                    class="card-img-top" alt="...">
@@ -130,8 +130,8 @@ class="card-img-top" alt="...">
                                                     name="favicon" id="favicon">
                                             </div>
 
-                                            <div class="card ml-5" style="width: 18rem;">
-                                                <span class="h3 text-center">{{ __('Icon') }} </span>
+                                            <div class="ml-5 card" style="width: 18rem;">
+                                                <span class="text-center h3">{{ __('Icon') }} </span>
                                                 <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
                                                     style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                     class="card-img-top" alt="...">
@@ -142,8 +142,8 @@ class="card-img-top" alt="...">
                                                     class="form-control" name="icon" id="icon">
                                             </div>
 
-                                            <div class="card ml-5" style="width: 18rem;">
-                                                <span class="h3 text-center">{{ __('Login-page Logo') }} </span>
+                                            <div class="ml-5 card" style="width: 18rem;">
+                                                <span class="text-center h3">{{ __('Login-page Logo') }} </span>
                                                 <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
                                                     style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                     class="card-img-top" alt="...">
@@ -155,7 +155,7 @@ class="form-control" name="logo" id="logo">
                                             </div>
                                         </div>
                                         <div class="row">
-                                            <button class="btn btn-primary ml-3 mt-3">{{ __('Save') }}</button>
+                                            <button class="mt-3 ml-3 btn btn-primary">{{ __('Save') }}</button>
                                         </div>
                                     </form>
                                 </div>
@@ -182,14 +182,14 @@ class="form-control" name="logo" id="logo">
                                                         </div>
 
                                                         <div class="col-8">
-                                                            <div class="custom-control mb-3 d-flex align-items-center">
+                                                            <div class="mb-3 custom-control d-flex align-items-center">
                                                                 @if ($value['description'])
-                                                                    <i class="fas fa-info-circle mr-4" data-toggle="popover"
+                                                                    <i class="mr-4 fas fa-info-circle" data-toggle="popover"
                                                                         data-trigger="hover" data-placement="top"
                                                                         data-html="true"
                                                                         data-content="{{ $value['description'] }}"></i>
                                                                 @else
-                                                                    <i class="fas fa-info-circle mr-4 invisible"></i>
+                                                                    <i class="invisible mr-4 fas fa-info-circle"></i>
                                                                 @endif
 
                                                                 <div class="w-100">
@@ -200,6 +200,12 @@ class="form-control" name="logo" id="logo">
                                                                                 value="{{ $value['value'] }}">
                                                                         @break
 
+                                                                        @case($value['type'] == 'password')
+                                                                            <input type="password" class="form-control"
+                                                                                name="{{ $key }}"
+                                                                                value="{{ $value['value'] }}">
+                                                                        @break
+
                                                                         @case($value['type'] == 'boolean')
                                                                             <input type="checkbox" name="{{ $key }}"
                                                                                 value="{{ $value['value'] }}"
@@ -277,7 +283,7 @@ class="custom-select w-100"
                                                                                                                                                                         <div class="col-8">
 
                                                                                                                                                                                 <div class="w-100">
-                                                                                                                                                                        <div class="input-group mb-3">
+                                                                                                                                                                        <div class="mb-3 input-group">
                                                                                                                                                                             {!! htmlScriptTagJsApi() !!}
                                                                                                                                                                         {!! htmlFormSnippet() !!}
                                                                                                                                                                         @error('g-recaptcha-response')
@@ -294,10 +300,10 @@ class="custom-select w-100"
 
                                                 <div class="row">
                                                     <div class="col-12 d-flex align-items-center justify-content-end">
-                                                        <button type="submit" class="btn btn-primary float-right ">Save
+                                                        <button type="submit" class="float-right btn btn-primary ">Save
                                                         </button>
                                                         <button type="reset"
-                                                            class="btn btn-secondary float-right ml-2">Reset
+                                                            class="float-right ml-2 btn btn-secondary">Reset
                                                         </button>
                                                     </div>
                                                 </div>

From 03f8a7d614853ff350386bf55fadac1970e417f8 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 22 Oct 2023 11:18:50 -0400
Subject: [PATCH 241/514] Closes #911

---
 app/Http/Controllers/Admin/UserController.php | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 4956e565c..b2c7b075a 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -340,6 +340,10 @@ public function toggleSuspended(User $user)
     {
         $this->checkPermission(self::SUSPEND_PERMISSION);
 
+        if (Auth::user()->id === $user->id) {
+            return redirect()->back()->with('error', __('You can not suspend yourself!'));
+        }
+
         try {
             !$user->isSuspended() ? $user->suspend() : $user->unSuspend();
         } catch (Exception $exception) {
@@ -361,10 +365,10 @@ public function dataTable(Request $request)
 
         return datatables($query)
             ->addColumn('avatar', function (User $user) {
-                return '<img width="28px" height="28px" class="rounded-circle ml-1" src="' . $user->getAvatar() . '">';
+                return '<img width="28px" height="28px" class="ml-1 rounded-circle" src="' . $user->getAvatar() . '">';
             })
             ->addColumn('credits', function (User $user) {
-                return '<i class="fas fa-coins mr-2"></i> ' . $user->credits();
+                return '<i class="mr-2 fas fa-coins"></i> ' . $user->credits();
             })
             ->addColumn('verified', function (User $user) {
                 return $user->getVerifiedStatus();
@@ -378,10 +382,10 @@ public function dataTable(Request $request)
                 $suspendText = $user->isSuspended() ? __('Unsuspend') : __('Suspend');
 
                 return '
-                <a data-content="' . __('Login as User') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
-                <a data-content="' . __('Verify') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.verifyEmail', $user->id) . '" class="btn btn-sm btn-secondary mr-1"><i class="fas fa-envelope"></i></a>
-                <a data-content="' . __('Show') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
-                <a data-content="' . __('Edit') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                <a data-content="' . __('Login as User') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="mr-1 btn btn-sm btn-primary"><i class="fas fa-sign-in-alt"></i></a>
+                <a data-content="' . __('Verify') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.verifyEmail', $user->id) . '" class="mr-1 btn btn-sm btn-secondary"><i class="fas fa-envelope"></i></a>
+                <a data-content="' . __('Show') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.show', $user->id) . '" class="mr-1 text-white btn btn-sm btn-warning"><i class="fas fa-eye"></i></a>
+                <a data-content="' . __('Edit') . '" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.edit', $user->id) . '" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
                 <form class="d-inline" method="post" action="' . route('admin.users.togglesuspend', $user->id) . '">
                              ' . csrf_field() . '
                             <button data-content="' . $suspendText . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm ' . $suspendColor . ' text-white mr-1"><i class="far ' . $suspendIcon . '"></i></button>
@@ -389,7 +393,7 @@ public function dataTable(Request $request)
                 <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.users.destroy', $user->id) . '">
                              ' . csrf_field() . '
                              ' . method_field('DELETE') . '
-                            <button data-content="' . __('Delete') . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                            <button data-content="' . __('Delete') . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                         </form>
                 ';
             })

From a75863909c98772d3a0c18c88da9b7d3902535de Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 22 Oct 2023 11:24:19 -0400
Subject: [PATCH 242/514] Closes #905

---
 .../views/admin/products/show.blade.php        | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/themes/default/views/admin/products/show.blade.php b/themes/default/views/admin/products/show.blade.php
index 217a27bf9..922d5d018 100644
--- a/themes/default/views/admin/products/show.blade.php
+++ b/themes/default/views/admin/products/show.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{__('Products')}}</h1>
                 </div>
@@ -28,17 +28,17 @@
 
             <div class="card">
                 <div class="card-header d-flex justify-content-between">
-                    <h5 class="card-title"><i class="fas fa-sliders-h mr-2"></i>{{__('Product')}}</h5>
+                    <h5 class="card-title"><i class="mr-2 fas fa-sliders-h"></i>{{__('Product')}}</h5>
                     <div class="ml-auto">
                         <a data-content="Edit" data-trigger="hover" data-toggle="tooltip"
-                            href="{{ route('admin.products.edit', $product->id) }}" class="btn btn-sm btn-info mr-1"><i
+                            href="{{ route('admin.products.edit', $product->id) }}" class="mr-1 btn btn-sm btn-info"><i
                                 class="fas fa-pen"></i></a>
                         <form class="d-inline" onsubmit="return submitResult();" method="post"
                             action="{{ route('admin.products.destroy', $product->id) }}">
                             {{ csrf_field() }}
                             {{ method_field('DELETE') }}
                             <button data-content="Delete" data-trigger="hover" data-toggle="tooltip"
-                                class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                                class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                         </form>
                     </div>
                 </div>
@@ -78,7 +78,7 @@ class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
                                 </div>
                                 <div class="col-lg-8">
                                     <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                        <i class="fas fa-coins mr-1"></i>{{ $product->price }}
+                                        <i class="mr-1 fas fa-coins"></i>{{ $product->price }}
                                     </span>
                                 </div>
                             </div>
@@ -92,9 +92,9 @@ class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
                                 <div class="col-lg-8">
                                     <span style="max-width: 250px;" class="d-inline-block text-truncate">
                                         @if ($product->minimum_credits == -1)
-                                            <i class="fas fa-coins mr-1"></i>{{ $minimum_credits }}
+                                            <i class="mr-1 fas fa-coins"></i>{{ $minimum_credits }}
                                         @else
-                                            <i class="fas fa-coins mr-1"></i>{{ $product->minimum_credits }}
+                                            <i class="mr-1 fas fa-coins"></i>{{ $product->minimum_credits }}
                                         @endif
                                     </span>
                                 </div>
@@ -213,7 +213,7 @@ class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
                                     <label>{{__('Description')}}</label>
                                 </div>
                                 <div class="col-lg-8">
-                                    <span class="d-inline-block text-truncate">
+                                    <span class="d-block text-truncate">
                                         {{ $product->description }}
                                     </span>
                                 </div>
@@ -240,7 +240,7 @@ class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
 
             <div class="card">
                 <div class="card-header">
-                    <h5 class="card-title"><i class="fas fa-server mr-2"></i>{{__('Servers')}}</h5>
+                    <h5 class="card-title"><i class="mr-2 fas fa-server"></i>{{__('Servers')}}</h5>
                 </div>
                 <div class="card-body table-responsive">
 

From 654932225a7804e22a3e54176c26392acc892fbf Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sun, 22 Oct 2023 13:48:05 -0400
Subject: [PATCH 243/514] Closes #696

---
 .../Controllers/Admin/CouponController.php    | 26 ++---
 .../Controllers/Admin/PartnerController.php   |  5 +-
 .../Controllers/Admin/ProductController.php   | 13 +--
 app/Http/Controllers/Admin/RoleController.php |  2 +
 .../Admin/ShopProductController.php           |  6 +-
 .../Controllers/Admin/TicketsController.php   | 20 ++--
 app/Http/Controllers/Admin/UserController.php | 47 ++++-----
 .../Controllers/Admin/VoucherController.php   | 26 +++--
 .../views/admin/coupons/index.blade.php       |  6 +-
 .../views/admin/products/index.blade.php      |  6 +-
 .../views/admin/servers/index.blade.php       |  7 +-
 .../views/admin/ticket/blacklist.blade.php    |  8 +-
 .../views/admin/ticket/index.blade.php        |  6 +-
 .../views/admin/vouchers/index.blade.php      |  8 +-
 transferusers.php                             | 95 +++++++++++++++++++
 15 files changed, 197 insertions(+), 84 deletions(-)
 create mode 100644 transferusers.php

diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php
index 1287a57c7..71caaf31c 100644
--- a/app/Http/Controllers/Admin/CouponController.php
+++ b/app/Http/Controllers/Admin/CouponController.php
@@ -185,29 +185,32 @@ public function redeem(Request $request)
 
     public function dataTable()
     {
-        $query = Coupon::query();
+        $query = Coupon::selectRaw('
+            coupons.*,
+            CASE
+                WHEN coupons.uses >= coupons.max_uses THEN "USES_LIMIT_REACHED"
+                WHEN coupons.expires_at IS NOT NULL AND coupons.expires_at < NOW() THEN "EXPIRED"
+                ELSE "VALID"
+            END as derived_status
+        ');
 
         return datatables($query)
             ->addColumn('actions', function(Coupon $coupon) {
                 return '
-                    <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.coupons.edit', $coupon->id).'" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                    <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.coupons.edit', $coupon->id).'" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
 
                     <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.coupons.destroy', $coupon->id).'">
                         '.csrf_field().'
                         '.method_field('DELETE').'
-                        <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                        <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                     </form>
                 ';
             })
-            ->addColumn('status', function(Coupon $coupon) {
-                $color = 'success';
-                $status = $coupon->getStatus();
+            ->addColumn('status', function (Coupon $coupon) {
+                $color = ($coupon->derived_status == 'VALID') ? 'success' : 'danger';
+                $status = str_replace('_', ' ', $coupon->derived_status);
 
-                if ($status != __('VALID')) {
-                    $color = 'danger';
-                }
-
-                return '<span class="badge badge-'.$color.'">'.str_replace('_', ' ', $status).'</span>';
+                return '<span class="badge badge-'.$color.'">'.$status.'</span>';
             })
             ->editColumn('uses', function (Coupon $coupon) {
                 return "{$coupon->uses} / {$coupon->max_uses}";
@@ -232,6 +235,7 @@ public function dataTable()
             ->editColumn('code', function (Coupon $coupon) {
                 return "<code>{$coupon->code}</code>";
             })
+            ->orderColumn('status', 'derived_status $1')
             ->rawColumns(['actions', 'code', 'status'])
             ->make();
     }
diff --git a/app/Http/Controllers/Admin/PartnerController.php b/app/Http/Controllers/Admin/PartnerController.php
index 5c4a6babb..8b65eec3f 100644
--- a/app/Http/Controllers/Admin/PartnerController.php
+++ b/app/Http/Controllers/Admin/PartnerController.php
@@ -122,11 +122,11 @@ public function dataTable()
         return datatables($query)
             ->addColumn('actions', function (PartnerDiscount $partner) {
                 return '
-                            <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.partners.edit', $partner->id).'" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                            <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.partners.edit', $partner->id).'" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
                            <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.partners.destroy', $partner->id).'">
                             '.csrf_field().'
                             '.method_field('DELETE').'
-                           <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                           <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                        </form>
                 ';
             })
@@ -145,6 +145,7 @@ public function dataTable()
             ->editColumn('referral_system_commission', function (PartnerDiscount $partner, ReferralSettings $referral_settings) {
                 return $partner->referral_system_commission >= 0 ? $partner->referral_system_commission . '%' : __('Default') . ' ('.$referral_settings->percentage . '%)';
             })
+            ->orderColumn('user', 'user_id $1')
             ->rawColumns(['user', 'actions'])
             ->make();
     }
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index ddc91fa8d..6ddae3e38 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -223,17 +223,18 @@ public function destroy(Product $product)
     public function dataTable()
     {
         $query = Product::with(['servers']);
+
         return datatables($query)
             ->addColumn('actions', function (Product $product) {
                 return '
-                            <a data-content="'.__('Show').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.products.show', $product->id).'" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
-                            <a data-content="'.__('Clone').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.products.clone', $product->id).'" class="btn btn-sm text-white btn-primary mr-1"><i class="fas fa-clone"></i></a>
-                            <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.products.edit', $product->id).'" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                            <a data-content="'.__('Show').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.products.show', $product->id).'" class="mr-1 text-white btn btn-sm btn-warning"><i class="fas fa-eye"></i></a>
+                            <a data-content="'.__('Clone').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.products.clone', $product->id).'" class="mr-1 text-white btn btn-sm btn-primary"><i class="fas fa-clone"></i></a>
+                            <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.products.edit', $product->id).'" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
 
                            <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.products.destroy', $product->id).'">
                             '.csrf_field().'
                             '.method_field('DELETE').'
-                           <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                           <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                        </form>
                 ';
             })
@@ -247,7 +248,7 @@ public function dataTable()
             ->addColumn('eggs', function (Product $product) {
                 return $product->eggs()->count();
             })
-            ->addColumn('disabled', function (Product $product) {
+            ->editColumn('disabled', function (Product $product) {
                 $checked = $product->disabled == false ? 'checked' : '';
 
                 return '
@@ -264,7 +265,7 @@ public function dataTable()
             ->editColumn('minimum_credits', function (Product $product, UserSettings $user_settings) {
                 return $product->minimum_credits==-1 ? $user_settings->min_credits_to_make_server : $product->minimum_credits;
             })
-            ->editColumn('oom_killer', function (Product $product, UserSettings $user_settings) {
+            ->editColumn('oom_killer', function (Product $product) {
                 return $product->oom_killer ? __("enabled") : __("disabled");
             })
             ->editColumn('created_at', function (Product $product) {
diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index b10c1b012..d3553ae20 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -214,6 +214,8 @@ class="fa fas fa-trash"></i></button>
             ->editColumn('power', function (Role $role){
                 return $role->power;
             })
+            ->orderColumn('usercount', 'users_count $1')
+            ->orderColumn('permissionscount', 'permissions_count $1')
             ->rawColumns(['actions', 'name'])
             ->make(true);
     }
diff --git a/app/Http/Controllers/Admin/ShopProductController.php b/app/Http/Controllers/Admin/ShopProductController.php
index 74c32639a..db07916a8 100644
--- a/app/Http/Controllers/Admin/ShopProductController.php
+++ b/app/Http/Controllers/Admin/ShopProductController.php
@@ -156,16 +156,16 @@ public function dataTable(Request $request)
         return datatables($query)
             ->addColumn('actions', function (ShopProduct $shopProduct) {
                 return '
-                            <a data-content="' . __('Edit') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.store.edit', $shopProduct->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                            <a data-content="' . __('Edit') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.store.edit', $shopProduct->id) . '" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
 
                            <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.store.destroy', $shopProduct->id) . '">
                             ' . csrf_field() . '
                             ' . method_field('DELETE') . '
-                           <button data-content="' . __('Delete') . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                           <button data-content="' . __('Delete') . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                        </form>
                 ';
             })
-            ->addColumn('disabled', function (ShopProduct $shopProduct) {
+            ->editColumn('disabled', function (ShopProduct $shopProduct) {
                 $checked = $shopProduct->disabled == false ? 'checked' : '';
 
                 return '
diff --git a/app/Http/Controllers/Admin/TicketsController.php b/app/Http/Controllers/Admin/TicketsController.php
index 3622c22ae..025c58de3 100644
--- a/app/Http/Controllers/Admin/TicketsController.php
+++ b/app/Http/Controllers/Admin/TicketsController.php
@@ -121,11 +121,12 @@ public function reply(Request $request)
 
     public function dataTable()
     {
-        $query = Ticket::query();
+        $query = Ticket::leftJoin('ticket_categories', 'tickets.ticketcategory_id', '=', 'ticket_categories.id')
+            ->select(['tickets.*', 'ticket_categories.name as category_name']);
 
         return datatables($query)
-            ->addColumn('category', function (Ticket $tickets) {
-                return $tickets->ticketcategory->name;
+            ->addColumn('category', function (Ticket $ticket) {
+                return $ticket->category_name;
             })
             ->editColumn('title', function (Ticket $tickets) {
                 return '<a class="text-info"  href="'.route('admin.ticket.show', ['ticket_id' => $tickets->ticket_id]).'">'.'#'.$tickets->ticket_id.' - '.htmlspecialchars($tickets->title).'</a>';
@@ -139,16 +140,16 @@ public function dataTable()
                 $statusButtonText = ($tickets->status == "Closed") ? __('Reopen') : __('Close');
 
                 return '
-                            <a data-content="'.__('View').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.ticket.show', ['ticket_id' => $tickets->ticket_id]).'" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-eye"></i></a>
+                            <a data-content="'.__('View').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.ticket.show', ['ticket_id' => $tickets->ticket_id]).'" class="mr-1 text-white btn btn-sm btn-info"><i class="fas fa-eye"></i></a>
                             <form class="d-inline"  method="post" action="'.route('admin.ticket.changeStatus', ['ticket_id' => $tickets->ticket_id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
-                            <button data-content="'.__($statusButtonText).'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white '.$statusButtonColor.'  mr-1"><i class="fas '.$statusButtonIcon.'"></i></button>
+                            <button data-content="'.__($statusButtonText).'" data-toggle="popover" data-trigger="hover" data-placement="top" class="text-white btn btn-sm '.$statusButtonColor.'  mr-1"><i class="fas '.$statusButtonIcon.'"></i></button>
                             </form>
                             <form class="d-inline"  method="post" action="'.route('admin.ticket.delete', ['ticket_id' => $tickets->ticket_id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
-                            <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                            <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 text-white btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                             </form>
                 ';
             })
@@ -178,7 +179,8 @@ public function dataTable()
                 return ['display' => $tickets->updated_at ? $tickets->updated_at->diffForHumans() : '',
                         'raw' => $tickets->updated_at ? strtotime($tickets->updated_at) : ''];
             })
-            ->rawColumns(['category', 'title', 'user_id', 'status', 'priority', 'updated_at', 'actions'])
+            ->orderColumn('category', 'category_name $1')
+            ->rawColumns(['title', 'user_id', 'status', 'priority', 'updated_at', 'actions'])
             ->make(true);
     }
 
@@ -279,12 +281,12 @@ public function dataTableBlacklist()
                             <form class="d-inline"  method="post" action="'.route('admin.ticket.blacklist.change', ['id' => $blacklist->id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
-                            <button data-content="'.__('Change Status').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-sync-alt"></i></button>
+                            <button data-content="'.__('Change Status').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 text-white btn btn-sm btn-warning"><i class="fas fa-sync-alt"></i></button>
                             </form>
                             <form class="d-inline"  method="post" action="'.route('admin.ticket.blacklist.delete', ['id' => $blacklist->id]).'">
                                 '.csrf_field().'
                                 '.method_field('POST').'
-                            <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                            <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 text-white btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                             </form>
                 ';
             })
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index b2c7b075a..60a1120fb 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -148,7 +148,7 @@ public function edit(User $user, GeneralSettings $general_settings)
      */
     public function update(Request $request, User $user)
     {
-        $request->validate([
+        $data = $request->validate([
             'name' => 'required|string|min:4|max:30',
             'pterodactyl_id' => "required|numeric|unique:users,pterodactyl_id,{$user->id}",
             'email' => 'required|string|email',
@@ -179,23 +179,23 @@ public function update(Request $request, User $user)
             ]);
         }
 
-        if($this->can(self::CHANGE_USERNAME_PERMISSION)){
-           $user->name = $request->name;
-        }
-        if($this->can(self::CHANGE_CREDITS_PERMISSION)){
-            $user->credits = $request->credits;
-        }
-        if($this->can(self::CHANGE_PTERO_PERMISSION)){
-            $user->pterodactyl_id = $request->pterodactyl_id;
-        }
-        if($this->can(self::CHANGE_REFERAL_PERMISSION)){
-            $user->referral_code = $request->referral_code;
-        }
-        if($this->can(self::CHANGE_EMAIL_PERMISSION)){
-            $user->email = $request->email;
-        }
-
-        $user->save();
+        // if($this->can(self::CHANGE_USERNAME_PERMISSION)){
+        //    $user->name = $request->name;
+        // }
+        // if($this->can(self::CHANGE_CREDITS_PERMISSION)){
+        //     $user->credits = $request->credits;
+        // }
+        // if($this->can(self::CHANGE_PTERO_PERMISSION)){
+        //     $user->pterodactyl_id = $request->pterodactyl_id;
+        // }
+        // if($this->can(self::CHANGE_REFERAL_PERMISSION)){
+        //     $user->referral_code = $request->referral_code;
+        // }
+        // if($this->can(self::CHANGE_EMAIL_PERMISSION)){
+        //     $user->email = $request->email;
+        // }
+
+        $user->update($data);
 
         event(new UserUpdateCreditsEvent($user));
 
@@ -358,10 +358,12 @@ public function toggleSuspended(User $user)
      */
     public function dataTable(Request $request)
     {
-        $query =  User::with('discordUser')->withCount('servers');
-        // manually count referrals in user_referrals table
-        $query->selectRaw('users.*, (SELECT COUNT(*) FROM user_referrals WHERE user_referrals.referral_id = users.id) as referrals_count');
-
+        $query = User::query()
+            ->withCount('servers')
+            ->leftJoin('model_has_roles', 'users.id', '=', 'model_has_roles.model_id')
+            ->leftJoin('roles', 'model_has_roles.role_id', '=', 'roles.id')
+            ->selectRaw('users.*, roles.name as role_name, (SELECT COUNT(*) FROM user_referrals WHERE user_referrals.referral_id = users.id) as referrals_count')
+            ->where('model_has_roles.model_type', User::class);
 
         return datatables($query)
             ->addColumn('avatar', function (User $user) {
@@ -412,6 +414,7 @@ public function dataTable(Request $request)
             ->editColumn('name', function (User $user, PterodactylSettings $ptero_settings) {
                 return '<a class="text-info" target="_blank" href="' . $ptero_settings->panel_url . '/admin/users/view/' . $user->pterodactyl_id . '">' . strip_tags($user->name) . '</a>';
             })
+            ->orderColumn('role', 'role_name $1')
             ->rawColumns(['avatar', 'name', 'credits', 'role', 'usage',  'actions'])
             ->make();
     }
diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php
index ec6c5232f..b42d5094c 100644
--- a/app/Http/Controllers/Admin/VoucherController.php
+++ b/app/Http/Controllers/Admin/VoucherController.php
@@ -203,7 +203,7 @@ public function usersDataTable(Voucher $voucher)
                 return '<a class="text-info" target="_blank" href="'.route('admin.users.show', $user->id).'">'.$user->name.'</a>';
             })
             ->addColumn('credits', function (User $user) {
-                return '<i class="fas fa-coins mr-2"></i> '.$user->credits();
+                return '<i class="mr-2 fas fa-coins"></i> '.$user->credits();
             })
             ->addColumn('last_seen', function (User $user) {
                 return $user->last_seen ? $user->last_seen->diffForHumans() : '';
@@ -214,28 +214,33 @@ public function usersDataTable(Voucher $voucher)
 
     public function dataTable()
     {
-        $query = Voucher::query();
+        $query = Voucher::selectRaw('
+            vouchers.*,
+            CASE
+                WHEN (SELECT COUNT(*) FROM user_voucher WHERE user_voucher.voucher_id = vouchers.id) >= vouchers.uses THEN "USES_LIMIT_REACHED"
+                WHEN vouchers.expires_at IS NOT NULL AND vouchers.expires_at < NOW() THEN "EXPIRED"
+                ELSE "VALID"
+            END as derived_status
+        ');
 
         return datatables($query)
             ->addColumn('actions', function (Voucher $voucher) {
                 return '
-                            <a data-content="'.__('Users').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.vouchers.users', $voucher->id).'" class="btn btn-sm btn-primary mr-1"><i class="fas fa-users"></i></a>
-                            <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.vouchers.edit', $voucher->id).'" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+                            <a data-content="'.__('Users').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.vouchers.users', $voucher->id).'" class="mr-1 btn btn-sm btn-primary"><i class="fas fa-users"></i></a>
+                            <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.vouchers.edit', $voucher->id).'" class="mr-1 btn btn-sm btn-info"><i class="fas fa-pen"></i></a>
 
                            <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.vouchers.destroy', $voucher->id).'">
                             '.csrf_field().'
                             '.method_field('DELETE').'
-                           <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                           <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="mr-1 btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
                        </form>
                 ';
             })
             ->addColumn('status', function (Voucher $voucher) {
-                $color = 'success';
-                if ($voucher->getStatus() != __('VALID')) {
-                    $color = 'danger';
-                }
+                $color = ($voucher->derived_status == 'VALID') ? 'success' : 'danger';
+                $status = str_replace('_', ' ', $voucher->derived_status);
 
-                return '<span class="badge badge-'.$color.'">'.$voucher->getStatus().'</span>';
+                return '<span class="badge badge-'.$color.'">'.$status.'</span>';
             })
             ->editColumn('uses', function (Voucher $voucher) {
                 return "{$voucher->used} / {$voucher->uses}";
@@ -253,6 +258,7 @@ public function dataTable()
             ->editColumn('code', function (Voucher $voucher) {
                 return "<code>{$voucher->code}</code>";
             })
+            ->orderColumn('status', 'derived_status $1')
             ->rawColumns(['actions', 'code', 'status'])
             ->make();
     }
diff --git a/themes/default/views/admin/coupons/index.blade.php b/themes/default/views/admin/coupons/index.blade.php
index d89135cff..cad2aa4e4 100644
--- a/themes/default/views/admin/coupons/index.blade.php
+++ b/themes/default/views/admin/coupons/index.blade.php
@@ -4,7 +4,7 @@
   <!-- CONTENT HEADER -->
   <section class="content-header">
     <div class="container-fluid">
-        <div class="row mb-2">
+        <div class="mb-2 row">
             <div class="col-sm-6">
                 <h1>{{__('Coupons')}}</h1>
             </div>
@@ -31,7 +31,7 @@
                       {{__('Coupons')}}
                     </h5>
                     <a href="{{route('admin.coupons.create')}}" class="btn btn-sm btn-primary">
-                      <i class="fas fa-plus mr-1"></i>
+                      <i class="mr-1 fas fa-plus"></i>
                       {{__('Create new')}}
                     </a>
                 </div>
@@ -82,7 +82,7 @@ function submitResult() {
         {data: 'status'},
         {data: 'code'},
         {data: 'value'},
-        {data: 'uses'},
+        {data: 'uses', sortable: false},
         {data: 'expires_at'},
         {data: 'created_at'},
         {data: 'actions', sortable: false},
diff --git a/themes/default/views/admin/products/index.blade.php b/themes/default/views/admin/products/index.blade.php
index a951a46f6..226598041 100644
--- a/themes/default/views/admin/products/index.blade.php
+++ b/themes/default/views/admin/products/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{__('Products')}}</h1>
                 </div>
@@ -30,9 +30,9 @@
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
 
-                        <h5 class="card-title"><i class="fas fa-sliders-h mr-2"></i>{{__('Products')}}</h5>
+                        <h5 class="card-title"><i class="mr-2 fas fa-sliders-h"></i>{{__('Products')}}</h5>
                         <a href="{{route('admin.products.create')}}" class="btn btn-sm btn-primary"><i
-                                class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
+                                class="mr-1 fas fa-plus"></i>{{__('Create new')}}</a>
                     </div>
                 </div>
 
diff --git a/themes/default/views/admin/servers/index.blade.php b/themes/default/views/admin/servers/index.blade.php
index 3cfec1641..2a0f8791e 100644
--- a/themes/default/views/admin/servers/index.blade.php
+++ b/themes/default/views/admin/servers/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{ __('Servers') }}</h1>
                 </div>
@@ -28,10 +28,10 @@
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
                         <div class="card-title ">
-                            <span><i class="fas fa-server mr-2"></i>{{ __('Servers') }}</span>
+                            <span><i class="mr-2 fas fa-server"></i>{{ __('Servers') }}</span>
                         </div>
                         <a href="{{ route('admin.servers.sync') }}" class="btn btn-primary btn-sm"><i
-                                class="fas fa-sync mr-2"></i>{{ __('Sync') }}</a>
+                                class="mr-2 fas fa-sync"></i>{{ __('Sync') }}</a>
                     </div>
                 </div>
                 <div class="card-body table-responsive">
@@ -93,7 +93,6 @@ function submitResult() {
                 },
                 {
                     data: 'product.name',
-                    sortable: false
                 },
                 {
                     data: 'suspended'
diff --git a/themes/default/views/admin/ticket/blacklist.blade.php b/themes/default/views/admin/ticket/blacklist.blade.php
index e26304a16..f501d3995 100644
--- a/themes/default/views/admin/ticket/blacklist.blade.php
+++ b/themes/default/views/admin/ticket/blacklist.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{ __('Ticket Blacklist') }}</h1>
                 </div>
@@ -29,7 +29,7 @@
                     <div class="card">
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
-                                <h5 class="card-title"><i class="fas fas fa-users mr-2"></i>{{__('Blacklist List')}}</h5>
+                                <h5 class="card-title"><i class="mr-2 fas fa-users"></i>{{__('Blacklist List')}}</h5>
                             </div>
                         </div>
                         <div class="card-body table-responsive">
@@ -62,7 +62,7 @@ class="fas fa-info-circle"></i></h5>
                         <div class="card-body">
                             <form action="{{route('admin.ticket.blacklist.add')}}" method="POST" class="ticket-form">
                             @csrf
-                                <div class="custom-control mb-3 p-0">
+                                <div class="p-0 mb-3 custom-control">
                                     <label for="user_id">{{ __('User') }}:
                                         <i data-toggle="popover" data-trigger="hover"
                                         data-content="{{ __('Please note, the blacklist will make the user unable to make a ticket/reply again') }}" class="fas fa-info-circle"></i>
@@ -100,7 +100,7 @@ class="fas fa-info-circle"></i></h5>
                     {data: 'user' , name : 'user.name'},
                     {data: 'status'},
                     {data: 'reason'},
-                    {data: 'created_at', sortable: false},
+                    {data: 'created_at'},
                     {data: 'actions', sortable: false},
                 ],
                 fnDrawCallback: function( oSettings ) {
diff --git a/themes/default/views/admin/ticket/index.blade.php b/themes/default/views/admin/ticket/index.blade.php
index 5dc0bb936..17557a5f5 100644
--- a/themes/default/views/admin/ticket/index.blade.php
+++ b/themes/default/views/admin/ticket/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{__('Ticket')}}</h1>
                 </div>
@@ -28,9 +28,9 @@
 
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
-                        <h5 class="card-title"><i class="fas fa-ticket-alt mr-2"></i>{{__('Ticket List')}}</h5>
+                        <h5 class="card-title"><i class="mr-2 fas fa-ticket-alt"></i>{{__('Ticket List')}}</h5>
                     </div>
-                    <a href="{{route("admin.ticket.category.index")}}"><button class="btn btn-primary float-right">+ {{__("Add Category")}}</button></a>
+                    <a href="{{route("admin.ticket.category.index")}}"><button class="float-right btn btn-primary">+ {{__("Add Category")}}</button></a>
                 </div>
 
 
diff --git a/themes/default/views/admin/vouchers/index.blade.php b/themes/default/views/admin/vouchers/index.blade.php
index aa8e679ed..5411d48e7 100644
--- a/themes/default/views/admin/vouchers/index.blade.php
+++ b/themes/default/views/admin/vouchers/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{__('Vouchers')}}</h1>
                 </div>
@@ -28,9 +28,9 @@
 
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
-                        <h5 class="card-title"><i class="fas fa-money-check-alt mr-2"></i>{{__('Vouchers')}}</h5>
+                        <h5 class="card-title"><i class="mr-2 fas fa-money-check-alt"></i>{{__('Vouchers')}}</h5>
                         <a href="{{route('admin.vouchers.create')}}" class="btn btn-sm btn-primary"><i
-                                class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
+                                class="mr-1 fas fa-plus"></i>{{__('Create new')}}</a>
                     </div>
                 </div>
 
@@ -81,7 +81,7 @@ function submitResult() {
                     {data: 'code'},
                     {data: 'memo'},
                     {data: 'credits'},
-                    {data: 'uses'},
+                    {data: 'uses', sortable: false},
                     {data: 'expires_at'},
                     {data: 'actions', sortable: false},
                 ],
diff --git a/transferusers.php b/transferusers.php
new file mode 100644
index 000000000..89496b3d3
--- /dev/null
+++ b/transferusers.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * ---------CONFIG----------
+ *
+ * FILL IN THE DATABASE INFORMATION
+ */
+
+function generateRandomString($length = 8) {
+    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+    $charactersLength = strlen($characters);
+    $randomString = '';
+    for ($i = 0; $i < $length; $i++) {
+        $randomString .= $characters[rand(0, $charactersLength - 1)];
+    }
+    return $randomString;
+}
+
+
+echo "ENTER YOUR PTERODACTYL DATABASE HOST: ";
+$PTERODACTYL_HOST = trim(fgets(STDIN));
+echo "ENTER YOUR PTERODACTYL DATABASE USER: ";
+$PTERODACTYL_USER = trim(fgets(STDIN));
+echo "ENTER YOUR PTERODACTYL DATABASE PASSWORD: ";
+$PTERODACTYL_PASSWORD = trim(fgets(STDIN));
+echo "ENTER YOUR PTERODACTYL DATABASE DATABASE NAME: ";
+$PTERODACTYL_DATABASE = trim(fgets(STDIN));
+$pterodb = new mysqli($PTERODACTYL_HOST, $PTERODACTYL_USER, $PTERODACTYL_PASSWORD, $PTERODACTYL_DATABASE);
+if (!$pterodb) {
+    die('Connect Error (' . mysqli_connect_errno() . ') '
+        . mysqli_connect_error());
+}
+echo "ENTER YOUR CPGG DATABASE HOST: ";
+$CPGG_HOST = trim(fgets(STDIN));
+echo "ENTER YOUR CPGG DATABASE USER: ";
+$CPGG_USER = trim(fgets(STDIN));
+echo "ENTER YOUR CPGG DATABASE PASSWORD: ";
+$CPPPG_PASSWORD = trim(fgets(STDIN));
+echo "ENTER YOUR CPGG DATABASE DATABASE NAME: ";
+$CPGG_DATABASE = trim(fgets(STDIN));
+
+$cpggdb = new mysqli($CPGG_HOST, $CPGG_USER, $CPPPG_PASSWORD, $CPGG_DATABASE);
+if (!$cpggdb) {
+    die('Connect Error (' . mysqli_connect_errno() . ') '
+        . mysqli_connect_error());
+}
+
+
+
+echo "ENTER THE AMOUNT OF CREDITS A USER SHOULD START WITH (default: 250)";
+$init_credits = trim(fgets(STDIN));
+if (empty($init_credits)) {
+    $init_credits = 250;
+}
+echo "ENTER THE AMOUNT OF SERVERS A USER SHOULD START WITH (default: 2)";
+$serverlimit = trim(fgets(STDIN));
+if (empty($serverlimit)) {
+    $serverlimit = 2;
+}
+
+
+$userSQL = "SELECT * FROM `users`";
+$pteroUserResult = mysqli_query($pterodb, $userSQL);
+$cpggUserResult = mysqli_query($cpggdb, $userSQL);
+
+while ($pterouser = $pteroUserResult->fetch_assoc()) {
+    $id = $pterouser["id"];
+    $username = $pterouser["username"];
+    $email = $pterouser['email'];
+    $password = $pterouser['password'];
+    $now = date("Y-m-d H:i:s");
+    $role = "member";
+    $referral_code = generateRandomString();
+    try {
+        if ($pterouser["root_admin"]) {
+            $role = "admin";
+        }
+        $checkusersql = mysqli_query($cpggdb, "SELECT * FROM `users` WHERE `email` = '$email'");
+        if (mysqli_num_rows($checkusersql) > 0) {
+            echo "User ".$email." exists. Skipping! \n";
+        } else {
+
+
+            $sql = "INSERT INTO `users` (`id`, `name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `avatar`, `email`, `email_verified_at`, `password`, `remember_token`, `created_at`, `updated_at`, `ip`, `last_seen`, `discord_verified_at`, `suspended`, `referral_code`) VALUES (NULL, '$username', '$role', '$init_credits', '$serverlimit', '$id', NULL, '$email', NULL, '$password', NULL, '$now', NULL, NULL, NULL, NULL, '0', '$referral_code')";
+            $res = mysqli_query($cpggdb, $sql);
+            echo "User ".$email."  created \n";
+        }
+
+    } catch (Exception $e) {
+        echo "Fail: " . $e;
+    }
+}
+
+
+?>
\ No newline at end of file

From f3a341fa1bac3d4321f870791fbe4b89995a93b3 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sat, 28 Oct 2023 11:59:00 -0400
Subject: [PATCH 244/514] Fix role search

---
 app/Http/Controllers/Admin/RoleController.php    |  9 +++------
 themes/default/views/admin/roles/index.blade.php | 10 +++++-----
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index d3553ae20..cc75f1788 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -182,8 +182,7 @@ public function destroy(Role $role)
      */
     public function dataTable()
     {
-        $query = Role::query()->withCount(['users', 'permissions']);
-
+        $query = Role::query()->withCount(['users', 'permissions'])->get();
 
         return datatables($query)
             ->editColumn('id', function (Role $role) {
@@ -205,17 +204,15 @@ class="fa fas fa-trash"></i></button>
             ->editColumn('name', function (Role $role) {
                 return "<span style='background-color: $role->color' class='badge'>$role->name</span>";
             })
-            ->editColumn('usercount', function ($query) {
+            ->editColumn('users_count', function ($query) {
                 return $query->users_count;
             })
-            ->editColumn('permissionscount', function ($query){
+            ->editColumn('permissions_count', function ($query){
                 return $query->permissions_count;
             })
             ->editColumn('power', function (Role $role){
                 return $role->power;
             })
-            ->orderColumn('usercount', 'users_count $1')
-            ->orderColumn('permissionscount', 'permissions_count $1')
             ->rawColumns(['actions', 'name'])
             ->make(true);
     }
diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
index 213a7724d..b327fce9b 100644
--- a/themes/default/views/admin/roles/index.blade.php
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -1,16 +1,16 @@
 @extends('layouts.main')
 
 @section('content')
-    <div class="main py-4">
+    <div class="py-4 main">
 
         @can('admin.roles.write')
-            <div class="d-flex justify-content-end my-3">
+            <div class="my-3 d-flex justify-content-end">
                 <a href="{{route('admin.roles.create')}}" class="btn btn-primary"><i
                         class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
             </div>
         @endcan
 
-        <div class="card card-body border-0 shadow table-wrapper table-responsive">
+        <div class="border-0 shadow card card-body table-wrapper table-responsive">
             <h2 class="mb-4 h5">{{ __('Roles') }}</h2>
 
             <div class="card-body table-responsive">
@@ -48,8 +48,8 @@ class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
             columns: [
                 {data: 'id'},
                 {data: 'name'},
-                {data: 'usercount'},
-                {data: 'permissionscount'},
+                {data: 'users_count'},
+                {data: 'permissions_count'},
                 {data: 'power'},
                 {data: 'actions' , sortable : false},
             ],

From 3b99ae527f8078eff5579f8557aa6ae1b6f60e44 Mon Sep 17 00:00:00 2001
From: Ferks-FK <fernandokaiquecnp2014@gmail.com>
Date: Sat, 28 Oct 2023 13:03:23 -0400
Subject: [PATCH 245/514] closes #684

---
 .../views/admin/overview/index.blade.php      | 290 +++++++++---------
 1 file changed, 150 insertions(+), 140 deletions(-)

diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index 5a6fc1d53..e9c4debfe 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -4,7 +4,7 @@
     <!-- CONTENT HEADER -->
     <section class="content-header">
         <div class="container-fluid">
-            <div class="row mb-2">
+            <div class="mb-2 row">
                 <div class="col-sm-6">
                     <h1>{{__('Admin Overview')}}</h1>
                 </div>
@@ -33,22 +33,22 @@
     <section class="content">
         <div class="container-fluid">
 
-            <div class="row mb-3">
+            <div class="mb-3 row">
                 <div class="col-md-3">
-                    <a href="https://discord.gg/4Y6HjD2uyU" class="btn btn-dark btn-block px-3"><i
-                            class="fab fa-discord mr-2"></i> {{__('Support server')}}</a>
+                    <a href="https://discord.gg/4Y6HjD2uyU" class="px-3 btn btn-dark btn-block"><i
+                            class="mr-2 fab fa-discord"></i> {{__('Support server')}}</a>
                 </div>
                 <div class="col-md-3">
-                    <a href="https://CtrlPanel.gg/docs/intro" class="btn btn-dark btn-block px-3"><i
-                            class="fas fa-link mr-2"></i> {{__('Documentation')}}</a>
+                    <a href="https://CtrlPanel.gg/docs/intro" class="px-3 btn btn-dark btn-block"><i
+                            class="mr-2 fas fa-link"></i> {{__('Documentation')}}</a>
                 </div>
                 <div class="col-md-3">
-                    <a href="https://github.com/ControlPanel-gg/dashboard" class="btn btn-dark btn-block px-3"><i
-                            class="fab fa-github mr-2"></i> {{__('Github')}}</a>
+                    <a href="https://github.com/ControlPanel-gg/dashboard" class="px-3 btn btn-dark btn-block"><i
+                            class="mr-2 fab fa-github"></i> {{__('Github')}}</a>
                 </div>
                 <div class="col-md-3">
-                    <a href="https://CtrlPanel.gg/docs/Contributing/donating" class="btn btn-dark btn-block px-3"><i
-                            class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
+                    <a href="https://CtrlPanel.gg/docs/Contributing/donating" class="px-3 btn btn-dark btn-block"><i
+                            class="mr-2 fas fa-money-bill"></i> {{__('Support CtrlPanel')}}</a>
                 </div>
             </div>
 
@@ -59,7 +59,7 @@ class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
 
                         <div class="info-box-content">
                             <span class="info-box-text">{{__('Servers')}}
-                          <i class="fas fa-info-circle mr-4" data-toggle="popover"
+                          <i class="mr-4 fas fa-info-circle" data-toggle="popover"
                              data-trigger="hover" data-placement="top"
                              data-html="true"
                              data-content="{{ __("This shows the total active servers and the total servers. Total active servers are all servers which are not suspended") }}"></i>
@@ -77,7 +77,7 @@ class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
 
                         <div class="info-box-content">
                             <span class="info-box-text">{{__('Users')}}
-                              <i class="fas fa-info-circle mr-4" data-toggle="popover"
+                              <i class="mr-4 fas fa-info-circle" data-toggle="popover"
                                   data-trigger="hover" data-placement="top"
                                   data-html="true"
                                   data-content="{{ __("This shows the total active Users and the total Users. Total active Users are all Users which are not suspended") }}"></i>
@@ -92,7 +92,7 @@ class="fas fa-money-bill mr-2"></i> {{__('Support CtrlPanel')}}</a>
                 <div class="col-12 col-sm-6 col-md-3">
                     <div class="info-box">
                         <span class="info-box-icon bg-warning elevation-1"><i
-                                class="fas fa-coins text-white"></i></span>
+                                class="text-white fas fa-coins"></i></span>
 
                         <div class="info-box-content">
                             <span class="info-box-text">{{__('Total')}} {{ $credits_display_name }}</span>
@@ -123,15 +123,15 @@ class="fas fa-coins text-white"></i></span>
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-kiwi-bird mr-2"></i>{{__('Pterodactyl')}}</span>
+                                    <span><i class="mr-2 fas fa-kiwi-bird"></i>{{__('Pterodactyl')}}</span>
                                 </div>
                                 <a href="{{route('admin.overview.sync')}}" class="btn btn-primary btn-sm"><i
-                                        class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
+                                        class="mr-2 fas fa-sync"></i>{{__('Sync')}}</a>
                             </div>
                         </div>
-                        <div class="card-body py-1">
+                        <div class="py-1 card-body">
                             @if ($deletedNodesPresent)
-                                <div class="alert alert-danger m-2">
+                                <div class="m-2 alert alert-danger">
                                     <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Warning!') }}</h5>
                                     <p class="mb-2">
                                         {{ __('Some nodes got deleted on pterodactyl only. Please click the sync button above.') }}
@@ -166,42 +166,44 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
                             </table>
                         </div>
                         <div class="card-footer">
-                            <span><i class="fas fa-sync mr-2"></i>{{__('Last updated :date', ['date' => $syncLastUpdate])}}</span>
+                            <span><i class="mr-2 fas fa-sync"></i>{{__('Last updated :date', ['date' => $syncLastUpdate])}}</span>
                         </div>
                     </div>
                     <div class="card">
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-ticket-alt mr-2"></i>{{__('Latest tickets')}}</span>
+                                    <span><i class="mr-2 fas fa-ticket-alt"></i>{{__('Latest tickets')}}</span>
                                 </div>
                             </div>
                         </div>
-                        <div class="card-body py-1">
+                        <div class="py-1 card-body">
                             @if(!$tickets->count())<span style="font-size: 16px; font-weight:700">{{__('There are no tickets')}}.</span>
                             @else
-                                <table class="table">
-                                    <thead>
-                                    <tr>
-                                        <th>{{__('Title')}}</th>
-                                        <th>{{__('User')}}</th>
-                                        <th>{{__('Status')}}</th>
-                                        <th>{{__('Last updated')}}</th>
-                                    </tr>
-                                    </thead>
-                                    <tbody>
+                                <div class="overflow-auto">
+                                    <table class="table">
+                                        <thead>
+                                        <tr class="text-nowrap">
+                                            <th>{{__('Title')}}</th>
+                                            <th>{{__('User')}}</th>
+                                            <th>{{__('Status')}}</th>
+                                            <th>{{__('Last updated')}}</th>
+                                        </tr>
+                                        </thead>
+                                        <tbody>
 
-                                        @foreach($tickets as $ticket_id => $ticket)
-                                            <tr>
-                                                <td><a class="text-info"  href="{{route('admin.ticket.show', ['ticket_id' => $ticket_id])}}">#{{$ticket_id}} - {{$ticket->title}}</td>
-                                                <td><a href="{{route('admin.users.show', $ticket->user_id)}}">{{$ticket->user}}</a></td>
-                                                <td><span class="badge {{$ticket->statusBadgeColor}}">{{$ticket->status}}</span></td>
-                                                <td>{{$ticket->last_updated}}</td>
-                                            </tr>
-                                        @endforeach
+                                            @foreach($tickets as $ticket_id => $ticket)
+                                                <tr class="text-nowrap">
+                                                    <td><a class="text-info"  href="{{route('admin.ticket.show', ['ticket_id' => $ticket_id])}}">#{{$ticket_id}} - {{$ticket->title}}</td>
+                                                    <td><a href="{{route('admin.users.show', $ticket->user_id)}}">{{$ticket->user}}</a></td>
+                                                    <td><span class="badge {{$ticket->statusBadgeColor}}">{{$ticket->status}}</span></td>
+                                                    <td>{{$ticket->last_updated}}</td>
+                                                </tr>
+                                            @endforeach
 
-                                    </tbody>
-                                </table>
+                                        </tbody>
+                                    </table>
+                                </div>
                             @endif
                         </div>
                     </div>
@@ -209,14 +211,14 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-server mr-2"></i>{{__('CtrlPanel.gg')}}</span>
+                                    <span><i class="mr-2 fas fa-server"></i>{{__('CtrlPanel.gg')}}</span>
                                 </div>
                             </div>
-                            <div class="card-body py-1">
+                            <div class="py-1 card-body">
 
                             </div>
                             <div class="card-footer">
-                                <span><i class="fas fa-info mr-2"></i>{{__("Version")}} {{config("app.version")}} - {{config("BRANCHNAME")}}</span>
+                                <span><i class="mr-2 fas fa-info"></i>{{__("Version")}} {{config("app.version")}} - {{config("BRANCHNAME")}}</span>
                             </div>
                         </div>
                     </div>
@@ -226,13 +228,13 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-server mr-2"></i>{{__('Individual nodes')}}</span>
+                                    <span><i class="mr-2 fas fa-server"></i>{{__('Individual nodes')}}</span>
                                 </div>
                             </div>
                         </div>
-                        <div class="card-body py-1">
+                        <div class="py-1 card-body">
                             @if ($perPageLimit)
-                                <div class="alert alert-danger m-2">
+                                <div class="m-2 alert alert-danger">
                                     <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Error!') }}</h5>
                                     <p class="mb-2">
                                         {{ __('You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.') }}<br>
@@ -240,39 +242,41 @@ class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
                                         {{ __('Note') }}: {{ __('If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on CtrlPanel. Try clicking the button below.') }}
                                     </p>
                                     <a href="{{route('admin.servers.sync')}}" class="btn btn-primary btn-md"><i
-                                        class="fas fa-sync mr-2"></i>{{__('Sync servers')}}</a>
+                                        class="mr-2 fas fa-sync"></i>{{__('Sync servers')}}</a>
                                 </div>
                             @endif
-                            <table class="table">
-                                <thead>
-                                <tr>
-                                    <th>{{__('ID')}}</th>
-                                    <th>{{__('Node')}}</th>
-                                    <th>{{__('Server count')}}</th>
-                                    <th>{{__('Resource usage')}}</th>
-                                    <th>{{ $credits_display_name . ' ' . __('Usage') ." (".__('per month').")"}}</th>
-                                </tr>
-                                </thead>
-                                <tbody>
-                                    @foreach($nodes as $nodeID => $node)
+                            <div class="overflow-auto">
+                                <table class="table">
+                                    <thead>
+                                    <tr class="text-nowrap">
+                                        <th>{{__('ID')}}</th>
+                                        <th>{{__('Node')}}</th>
+                                        <th>{{__('Server count')}}</th>
+                                        <th>{{__('Resource usage')}}</th>
+                                        <th>{{ $credits_display_name . ' ' . __('Usage') ." (".__('per month').")"}}</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody>
+                                        @foreach($nodes as $nodeID => $node)
+                                            <tr>
+                                                <td>{{$nodeID}}</td>
+                                                <td>{{$node->name}}</td>
+                                                <td>{{$node->activeServers}}/{{$node->totalServers}}</td>
+                                                <td>{{$node->usagePercent}}%</td>
+                                                <td>{{$node->activeEarnings}}/{{$node->totalEarnings}}</td>
+                                            </tr>
+                                        @endforeach
+                                    </tbody>
+                                    <tfoot>
                                         <tr>
-                                            <td>{{$nodeID}}</td>
-                                            <td>{{$node->name}}</td>
-                                            <td>{{$node->activeServers}}/{{$node->totalServers}}</td>
-                                            <td>{{$node->usagePercent}}%</td>
-                                            <td>{{$node->activeEarnings}}/{{$node->totalEarnings}}</td>
+                                            <td class="text-nowrap" colspan="2"><span style="float: right; font-weight: 700">{{__('Total')}} ({{__('active')}}/{{__('total')}}):</span></td>
+                                            <td>{{$counters['servers']->active}}/{{$counters['servers']->total}}</td>
+                                            <td>{{$counters['totalUsagePercent']}}%</td>
+                                            <td>{{$counters['earnings']->active}}/{{$counters['earnings']->total}}</td>
                                         </tr>
-                                    @endforeach
-                                </tbody>
-                                <tfoot>
-                                    <tr>
-                                        <td colspan="2"><span style="float: right; font-weight: 700">{{__('Total')}} ({{__('active')}}/{{__('total')}}):</span></td>
-                                        <td>{{$counters['servers']->active}}/{{$counters['servers']->total}}</td>
-                                        <td>{{$counters['totalUsagePercent']}}%</td>
-                                        <td>{{$counters['earnings']->active}}/{{$counters['earnings']->total}}</td>
-                                    </tr>
-                                </tfoot>
-                            </table>
+                                    </tfoot>
+                                </table>
+                            </div>
                             <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px;">
                         </div>
                     </div>
@@ -280,11 +284,11 @@ class="fas fa-sync mr-2"></i>{{__('Sync servers')}}</a>
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-file-invoice-dollar mr-2"></i>{{__('Latest payments')}}</span>
+                                    <span><i class="mr-2 fas fa-file-invoice-dollar"></i>{{__('Latest payments')}}</span>
                                 </div>
                             </div>
                         </div>
-                        <div class="card-body py-1">
+                        <div class="py-1 card-body">
                             <div class="row">
                                 @if($counters['payments']['lastMonth']->count())
                                     <div class="col-md-6" style="border-right:1px solid #6c757d">
@@ -293,16 +297,46 @@ class="fas fa-sync mr-2"></i>{{__('Sync servers')}}</a>
                                             data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['lastMonth']->timeStart}} - {{$counters['payments']['lastMonth']->timeEnd}}"
                                             class="fas fa-info-circle"></i>
                                         </span>
+                                        <div class="overflow-auto">
+                                            <table class="table">
+                                                <thead>
+                                                <tr class="text-nowrap">
+                                                    <th><b>{{__('Currency')}}</b></th>
+                                                    <th>{{__('Number of payments')}}</th>
+                                                    <th>{{__('Total amount')}}</th>
+                                                </tr>
+                                                </thead>
+                                                <tbody>
+                                                    @foreach($counters['payments']['lastMonth'] as $currency => $income)
+                                                        <tr>
+                                                            <td>{{$currency}}</td>
+                                                            <td>{{$income->count}}</td>
+                                                            <td>{{$income->total}}</td>
+                                                        </tr>
+                                                    @endforeach
+                                                </tbody>
+                                            </table>
+                                        </div>
+                                    </div>
+                                @endif
+                                @if($counters['payments']['lastMonth']->count()) <div class="col-md-6">
+                                @else <div class="col-md-12"> @endif
+                                    <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This month')}}:
+                                        <i data-toggle="popover" data-trigger="hover" data-html="true"
+                                        data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['thisMonth']->timeStart}} - {{$counters['payments']['thisMonth']->timeEnd}}"
+                                        class="fas fa-info-circle"></i>
+                                    </span>
+                                    <div class="overflow-auto">
                                         <table class="table">
                                             <thead>
-                                            <tr>
+                                            <tr class="text-nowrap">
                                                 <th><b>{{__('Currency')}}</b></th>
                                                 <th>{{__('Number of payments')}}</th>
                                                 <th>{{__('Total amount')}}</th>
                                             </tr>
                                             </thead>
                                             <tbody>
-                                                @foreach($counters['payments']['lastMonth'] as $currency => $income)
+                                                @foreach($counters['payments']['thisMonth'] as $currency => $income)
                                                     <tr>
                                                         <td>{{$currency}}</td>
                                                         <td>{{$income->count}}</td>
@@ -311,35 +345,7 @@ class="fas fa-info-circle"></i>
                                                 @endforeach
                                             </tbody>
                                         </table>
-                                        <hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: -16px">
                                     </div>
-                                @endif
-                                @if($counters['payments']['lastMonth']->count()) <div class="col-md-6">
-                                @else <div class="col-md-12"> @endif
-                                    <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This month')}}:
-                                        <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                        data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['thisMonth']->timeStart}} - {{$counters['payments']['thisMonth']->timeEnd}}"
-                                        class="fas fa-info-circle"></i>
-                                    </span>
-                                    <table class="table">
-                                        <thead>
-                                        <tr>
-                                            <th><b>{{__('Currency')}}</b></th>
-                                            <th>{{__('Number of payments')}}</th>
-                                            <th>{{__('Total amount')}}</th>
-                                        </tr>
-                                        </thead>
-                                        <tbody>
-                                            @foreach($counters['payments']['thisMonth'] as $currency => $income)
-                                                <tr>
-                                                    <td>{{$currency}}</td>
-                                                    <td>{{$income->count}}</td>
-                                                    <td>{{$income->total}}</td>
-                                                </tr>
-                                            @endforeach
-                                        </tbody>
-                                    </table>
-                                    <hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: -16px">
                                 </div>
                             </div>
 
@@ -349,20 +355,52 @@ class="fas fa-info-circle"></i>
                         <div class="card-header">
                             <div class="d-flex justify-content-between">
                                 <div class="card-title ">
-                                    <span><i class="fas fa-hand-holding-usd mr-2"></i>{{__('Tax overview')}}</span>
+                                    <span><i class="mr-2 fas fa-hand-holding-usd"></i>{{__('Tax overview')}}</span>
                                 </div>
                             </div>
                         </div>
-                        <div class="card-body py-1">
+                        <div class="py-1 card-body">
                             @if($counters['taxPayments']['lastYear']->count())
                                 <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('Last year')}}:
                                     <i data-toggle="popover" data-trigger="hover" data-html="true"
                                     data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['lastYear']->timeStart}} - {{$counters['taxPayments']['lastYear']->timeEnd}}"
                                     class="fas fa-info-circle"></i>
                                 </span>
+                                <div class="overflow-auto">
+                                    <table class="table">
+                                        <thead>
+                                        <tr class="text-nowrap">
+                                            <th><b>{{__('Currency')}}</b></th>
+                                            <th>{{__('Number of payments')}}</th>
+                                            <th><b>{{__('Base amount')}}</b></th>
+                                            <th><b>{{__('Total taxes')}}</b></th>
+                                            <th>{{__('Total amount')}}</th>
+                                        </tr>
+                                        </thead>
+                                        <tbody>
+                                            @foreach($counters['taxPayments']['lastYear'] as $currency => $income)
+                                                <tr>
+                                                    <td>{{$currency}}</td>
+                                                    <td>{{$income->count}}</td>
+                                                    <td>{{$income->price}}</td>
+                                                    <td>{{$income->taxes}}</td>
+                                                    <td>{{$income->total}}</td>
+                                                </tr>
+                                            @endforeach
+                                        </tbody>
+                                    </table>
+                                </div>
+                                <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px; margin-bottom: 8px">
+                            @endif
+                            <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This year')}}:
+                                <i data-toggle="popover" data-trigger="hover" data-html="true"
+                                data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['thisYear']->timeStart}} - {{$counters['taxPayments']['thisYear']->timeEnd}}"
+                                class="fas fa-info-circle"></i>
+                            </span>
+                            <div class="overflow-auto">
                                 <table class="table">
                                     <thead>
-                                    <tr>
+                                    <tr class="text-nowrap">
                                         <th><b>{{__('Currency')}}</b></th>
                                         <th>{{__('Number of payments')}}</th>
                                         <th><b>{{__('Base amount')}}</b></th>
@@ -371,7 +409,7 @@ class="fas fa-info-circle"></i>
                                     </tr>
                                     </thead>
                                     <tbody>
-                                        @foreach($counters['taxPayments']['lastYear'] as $currency => $income)
+                                        @foreach($counters['taxPayments']['thisYear'] as $currency => $income)
                                             <tr>
                                                 <td>{{$currency}}</td>
                                                 <td>{{$income->count}}</td>
@@ -382,35 +420,7 @@ class="fas fa-info-circle"></i>
                                         @endforeach
                                     </tbody>
                                 </table>
-                                <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px; margin-bottom: 8px">
-                            @endif
-                            <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This year')}}:
-                                <i data-toggle="popover" data-trigger="hover" data-html="true"
-                                data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['thisYear']->timeStart}} - {{$counters['taxPayments']['thisYear']->timeEnd}}"
-                                class="fas fa-info-circle"></i>
-                            </span>
-                            <table class="table">
-                                <thead>
-                                <tr>
-                                    <th><b>{{__('Currency')}}</b></th>
-                                    <th>{{__('Number of payments')}}</th>
-                                    <th><b>{{__('Base amount')}}</b></th>
-                                    <th><b>{{__('Total taxes')}}</b></th>
-                                    <th>{{__('Total amount')}}</th>
-                                </tr>
-                                </thead>
-                                <tbody>
-                                    @foreach($counters['taxPayments']['thisYear'] as $currency => $income)
-                                        <tr>
-                                            <td>{{$currency}}</td>
-                                            <td>{{$income->count}}</td>
-                                            <td>{{$income->price}}</td>
-                                            <td>{{$income->taxes}}</td>
-                                            <td>{{$income->total}}</td>
-                                        </tr>
-                                    @endforeach
-                                </tbody>
-                            </table>
+                            </div>
                             <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px;">
                         </div>
                     </div>

From 62149da1f5e71afc8736b6a15c5435d3bb25d2a3 Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Wed, 24 Jan 2024 14:48:15 -0300
Subject: [PATCH 246/514] mercadopago payment add init

---
 .../MercadoPago/MercadoPagoExtension.php      | 225 ++++++++++++++++++
 .../MercadoPago/MercadoPagoSettings.php       |  34 +++
 ..._24_120635_create_mercadopago_settings.php |  18 ++
 .../MercadoPago/web_routes.php                |  18 ++
 config/permissions_web.php                    |   3 +
 .../BlueInfinity/views/layouts/main.blade.php |   6 +-
 themes/default/views/layouts/main.blade.php   |   6 +-
 7 files changed, 306 insertions(+), 4 deletions(-)
 create mode 100644 app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
 create mode 100644 app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php
 create mode 100644 app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php
 create mode 100644 app/Extensions/PaymentGateways/MercadoPago/web_routes.php

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
new file mode 100644
index 000000000..7f12d17b5
--- /dev/null
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -0,0 +1,225 @@
+<?php
+
+namespace App\Extensions\PaymentGateways\MercadoPago;
+
+use App\Classes\AbstractExtension;
+use App\Enums\PaymentStatus;
+use App\Events\PaymentEvent;
+use App\Events\UserUpdateCreditsEvent;
+use App\Models\Payment;
+use App\Models\ShopProduct;
+use App\Models\User;
+use App\Traits\Coupon as CouponTrait;
+use Exception;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Redirect;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Http;
+use App\Notifications\ConfirmPaymentNotification;
+
+/**
+ * Summary of MercadoPagoExtension
+ */
+class MercadoPagoExtension extends AbstractExtension
+{
+    use CouponTrait;
+
+    public static function getConfig(): array
+    {
+        return [
+            "name" => "MercadoPago",
+            "RoutesIgnoreCsrf" => [
+                "payment/MercadoPagoWebhook"
+            ],
+        ];
+    }
+
+    public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
+    {
+        $user = Auth::user();
+        $user = User::findOrFail($user->id);
+        $url = 'https://api.mercadopago.com/checkout/preferences';
+        $settings = new MercadoPagoSettings();
+        try {
+            $response =  Http::withHeaders([
+                'Content-Type' => 'application/json',
+                'Authorization' => 'Bearer ' . $settings->access_token,
+            ])->post($url, [
+                'back_urls' => [
+                    'success' => route('payment.MercadoPagoChecker'),
+                    'failure' => route('payment.Cancel'),
+                    'pending' => route('payment.MercadoPagoChecker'),
+                ],
+                'notification_url' => route('payment.MercadoPagoWebhook'),
+                'payer' => [
+                    'email' => $user->email,
+                ],
+                'items' => [
+                    [
+                        'title' => "Order #{$payment->id} - " . $shopProduct->name,
+                        'quantity' => 1,
+                        'unit_price' => $totalPriceString,
+                        'currency_id' => $shopProduct->currency_code,
+                    ],
+                ],
+                'metadata' => [
+                    'credit_amount' => $shopProduct->quantity,
+                    'user_id' => $user->id,
+                    'crtl_panel_payment_id' => $payment->id,
+                ],
+            ]);
+
+            if ($response->successful()) {
+                // preferenceID
+                $preferenceId = $response->json()['id'];
+
+                // Redirect link
+                return ("https://www.mercadopago.com/checkout/v1/redirect?preference-id=" . $preferenceId);
+            } else {
+                Log::error('MercadoPago Payment: ' . $response->body());
+                throw new Exception('Payment failed');
+            }
+        } catch (Exception $ex) {
+            Log::error('MercadoPago Payment: ' . $ex->getMessage());
+            throw new Exception('Payment failed');
+        }
+    }
+
+    static function Checker(Request $request): void
+    {
+        // paymentID (not is preferenceID or paymentID for store)
+        $paymentId = $request->input('payment_id');
+
+        $MpPayment = self::MpPayment($paymentId, false);
+
+        switch ($MpPayment) {
+            case "paid":
+                Redirect::route('home')->with('success', 'Payment successful')->send();
+                break;
+            case "cancelled":
+                Redirect::route('home')->with('info', 'Your canceled the payment')->send();
+                break;
+            case "processing":
+                Redirect::route('home')->with('info', 'Your payment is being processed')->send();
+                break;
+            default:
+                Redirect::route('home')->with('error', 'Your payment is unknown')->send();
+                break;
+        }
+    }
+
+    static function Webhook(Request $request): JsonResponse
+    {
+        $topic = $request->input('topic');
+        $msg = 'unset';
+        $status = 400;
+        if ($topic === 'merchant_order') {
+            $msg = 'ignored';
+            $status = 200;
+        } else if ($topic === 'payment') {
+            $msg = 'ignored';
+            $status = 200;
+        } else {
+            try {
+                $notificationId = $request->input('data.id') ?? $request->input('id') ?? $request->input('payment_id') ?? 'unknown';
+                if ($notificationId == 'unknown') {
+                    $msg = 'unknown payment.';
+                    $status = 400;
+                } else if ($notificationId == '123456') {
+                    $msg = 'MercadoPago api test';
+                    $status = 200;
+                } else {
+                    $MpPayment = self::MpPayment($notificationId, true);
+                    switch ($MpPayment) {
+                        case "paid":
+                            $msg = $MpPayment;
+                            $status = 200;
+                            break;
+
+                        case "cancelled":
+                            $msg = $MpPayment;
+                            $status = 200;
+                            break;
+
+                        case "processing":
+                            $msg = $MpPayment;
+                            $status = 200;
+                            break;
+                        default:
+                            $msg = 'unknown';
+                            $status = 400;
+                            break;
+                    }
+                }
+            } catch (Exception $ex) {
+                Log::error('MercadoPago Webhook(IPN) Payment: ' . $ex->getMessage());
+                $msg = 'error';
+                $status = 500;
+            }
+        }
+        $response = new JsonResponse($msg, $status);
+        return $response;
+    }
+    /**
+     * Mercado Pago Payment checker 
+     */
+    private function MpPayment(string $paymentID, bool $notification): string
+    {
+        $MpResponse = "unknown";
+        $payment = "unknown";
+        $url = "https://api.mercadopago.com/v1/payments/" . $paymentID;
+        $settings = new MercadoPagoSettings();
+        $response = Http::withHeaders([
+            'Content-Type' => 'application/json',
+            'Authorization' => 'Bearer ' . $settings->access_token,
+        ])->get($url);
+
+        if ($response->successful()) {
+            $mercado = $response->json();
+            $status = $mercado->status;
+            $payment = Payment::findOrFail($mercado->metadata->crtl_panel_payment_id);
+            $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
+
+            if ($status == "approved") {
+                // avoids double additions, if the user enters after the webhook has already added the credits
+                if ($payment->status !== PaymentStatus::PAID) {
+                    $user = User::findOrFail($payment->user_id);
+                    $payment->update([
+                        'status' => PaymentStatus::PAID,
+                        'payment_id' => $paymentID,
+                    ]);
+                    $payment->save();
+                    if ($notification) {
+                        $user->notify(new ConfirmPaymentNotification($payment));
+                    }
+                    event(new PaymentEvent($user, $payment, $shopProduct));
+                    event(new UserUpdateCreditsEvent($user));
+                }
+                $MpResponse = "paid";
+            } else {
+                if ($status == "cancelled") {
+                    $user = User::findOrFail($payment->user_id);
+                    $payment->update([
+                        'status' => PaymentStatus::CANCELED,
+                        'payment_id' => $paymentID,
+                    ]);
+                    $payment->save();
+                    event(new PaymentEvent($user, $payment, $shopProduct));
+                    $MpResponse = "cancelled";
+                } else {
+                    $user = User::findOrFail($payment->user_id);
+                    $payment->update([
+                        'status' => PaymentStatus::PROCESSING,
+                        'payment_id' => $paymentID,
+                    ]);
+                    $payment->save();
+                    event(new PaymentEvent($user, $payment, $shopProduct));
+                    $MpResponse = "processing";
+                }
+            }
+        }
+        return $MpResponse;
+    }
+}
diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php
new file mode 100644
index 000000000..f9b2059f7
--- /dev/null
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Extensions\PaymentGateways\MercadoPago;
+
+use Spatie\LaravelSettings\Settings;
+
+class MercadoPagoSettings extends Settings
+{
+
+    public bool $enabled = false;
+    public ?string $access_token;
+
+    public static function group(): string
+    {
+        return 'mercadopago';
+    }
+
+    public static function getOptionInputData()
+    {
+        return [
+            'category_icon' => 'fas fa-dollar-sign',
+            'access_token' => [
+                'type' => 'string',
+                'label' => 'Access Token Key',
+                'description' => 'The Access Token of your Mercado Pago App',
+            ],
+            'enabled' => [
+                'type' => 'boolean',
+                'label' => 'Enabled',
+                'description' => 'Enable or disable this payment gateway',
+            ],
+        ];
+    }
+}
diff --git a/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php b/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php
new file mode 100644
index 000000000..f27411c30
--- /dev/null
+++ b/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php
@@ -0,0 +1,18 @@
+<?php
+
+use Spatie\LaravelSettings\Migrations\SettingsMigration;
+
+class CreateMercadoPagoSettings extends SettingsMigration
+{
+    public function up(): void
+    {
+        $this->migrator->addEncrypted('mpago.access_token', null);
+        $this->migrator->add('mpago.enabled', false);
+    }
+
+    public function down(): void
+    {
+        $this->migrator->delete('mpago.access_token');
+        $this->migrator->delete('mpago.enabled');
+    }
+}
diff --git a/app/Extensions/PaymentGateways/MercadoPago/web_routes.php b/app/Extensions/PaymentGateways/MercadoPago/web_routes.php
new file mode 100644
index 000000000..a43179a64
--- /dev/null
+++ b/app/Extensions/PaymentGateways/MercadoPago/web_routes.php
@@ -0,0 +1,18 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Extensions\PaymentGateways\MercadoPago\MercadoPagoExtension;
+
+Route::middleware(['web', 'auth'])->group(function () {
+    Route::get(
+        'payment/MercadoPagoChecker',
+        function () {
+            MercadoPagoExtension::Checker(request());
+        }
+    )->name('payment.MercadoPagoChecker');
+});
+
+
+Route::post('payment/MercadoPagoWebhook', function () {
+    MercadoPagoExtension::Webhook(request());
+})->name('payment.MercadoPagoWebhook');
diff --git a/config/permissions_web.php b/config/permissions_web.php
index f0918375b..4c74caa18 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -118,6 +118,9 @@
     'settings.paypal.read',
     'settings.paypal.write',
 
+    'settings.mercadopago.read',
+    'settings.mercadopago.write',
+
     'settings.stripe.read',
     'settings.stripe.write',
 
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index b6549a7a0..3f1e07534 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -258,7 +258,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                     @endif
 
                     <!-- lol how do i make this shorter? -->
-                    @canany(['settings.discord.read','settings.discord.write','settings.general.read','settings.general.write','settings.invoice.read','settings.invoice.write','settings.locale.read','settings.locale.write','settings.mail.read','settings.mail.write','settings.pterodactyl.read','settings.pterodactyl.write','settings.referral.read','settings.referral.write','settings.server.read','settings.server.write','settings.ticket.read','settings.ticket.write','settings.user.read','settings.user.write','settings.website.read','settings.website.write','settings.paypal.read','settings.paypal.write','settings.stripe.read','settings.stripe.write','settings.mollie.read','settings.mollie.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
+                    @canany(['settings.discord.read','settings.discord.write','settings.general.read','settings.general.write','settings.invoice.read','settings.invoice.write','settings.locale.read','settings.locale.write','settings.mail.read','settings.mail.write','settings.pterodactyl.read','settings.pterodactyl.write','settings.referral.read','settings.referral.write','settings.server.read','settings.server.write','settings.ticket.read','settings.ticket.write','settings.user.read','settings.user.write','settings.website.read','settings.website.write','settings.paypal.read','settings.paypal.write','settings.stripe.read','settings.stripe.write','settings.mollie.read','settings.mollie.write','settings.mercadopago.read','settings.mercadopago.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
                         <li class="nav-header">{{ __('Administration') }}</li>
                     @endcanany
 
@@ -329,7 +329,9 @@ class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
                             'settings.stripe.read',
                             'settings.stripe.write',
                             'settings.mollie.read',
-                            'settings.mollie.write',])
+                            'settings.mollie.write',
+                            'settings.mercadopago.read',
+                            'settings.mercadopago.write',])
                         <li class="nav-item">
                             <a href="{{ route('admin.settings.index') }}"
                                class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 9631ef64d..5b44b85a9 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -258,7 +258,7 @@ class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
                         @endif
 
                     <!-- lol how do i make this shorter? -->
-                        @canany(['settings.discord.read','settings.discord.write','settings.general.read','settings.general.write','settings.invoice.read','settings.invoice.write','settings.locale.read','settings.locale.write','settings.mail.read','settings.mail.write','settings.pterodactyl.read','settings.pterodactyl.write','settings.referral.read','settings.referral.write','settings.server.read','settings.server.write','settings.ticket.read','settings.ticket.write','settings.user.read','settings.user.write','settings.website.read','settings.website.write','settings.paypal.read','settings.paypal.write','settings.stripe.read','settings.stripe.write','settings.mollie.read','settings.mollie.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
+                        @canany(['settings.discord.read','settings.discord.write','settings.general.read','settings.general.write','settings.invoice.read','settings.invoice.write','settings.locale.read','settings.locale.write','settings.mail.read','settings.mail.write','settings.pterodactyl.read','settings.pterodactyl.write','settings.referral.read','settings.referral.write','settings.server.read','settings.server.write','settings.ticket.read','settings.ticket.write','settings.user.read','settings.user.write','settings.website.read','settings.website.write','settings.paypal.read','settings.paypal.write','settings.stripe.read','settings.stripe.write','settings.mollie.read','settings.mollie.write','settings.mercadopago.read','settings.mercadopago.write','admin.overview.read','admin.overview.sync','admin.ticket.read','admin.tickets.write','admin.ticket_blacklist.read','admin.ticket_blacklist.write','admin.roles.read','admin.roles.write','admin.api.read','admin.api.write'])
                             <li class="nav-header">{{ __('Administration') }}</li>
                         @endcanany
 
@@ -329,7 +329,9 @@ class="nav-link @if (Request::routeIs('admin.roles.*')) active @endif">
                                 'settings.stripe.read',
                                 'settings.stripe.write',
                                 'settings.mollie.read',
-                                'settings.mollie.write',])
+                                'settings.mollie.write',
+                                'settings.mercadopago.read',
+                                'settings.mercadopago.write',])
                             <li class="nav-item">
                                 <a href="{{ route('admin.settings.index') }}"
                                     class="nav-link @if (Request::routeIs('admin.settings.*')) active @endif">

From 361fbe0af03092bb09edfa787737ad1d466b9edd Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Wed, 24 Jan 2024 13:57:52 -0400
Subject: [PATCH 247/514] add mercadopago img

---
 .../PaymentGateways/mercadopago_logo.png       | Bin 0 -> 344082 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 public/images/Extensions/PaymentGateways/mercadopago_logo.png

diff --git a/public/images/Extensions/PaymentGateways/mercadopago_logo.png b/public/images/Extensions/PaymentGateways/mercadopago_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c896983a0fc7c3c6a5e3e6d7cb257505e50c0e3
GIT binary patch
literal 344082
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%0Dwe;on;WP5XLGk0L^6-%tWtuGld#|G+`xM@jR
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
MU;bX^T|J-w2ax+H9{>OV

literal 0
HcmV?d00001


From 02b77670e20080e006fe00a0e62abe0d50b21a88 Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Thu, 25 Jan 2024 21:20:54 -0300
Subject: [PATCH 248/514] tested mercadopago routes

---
 .../MercadoPago/MercadoPagoExtension.php             | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index 7f12d17b5..42540e693 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -60,7 +60,8 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                     [
                         'title' => "Order #{$payment->id} - " . $shopProduct->name,
                         'quantity' => 1,
-                        'unit_price' => $totalPriceString,
+                        // convert shopProduct to float(this is string) 
+                        'unit_price' => floatval($shopProduct->getTotalPrice()),
                         'currency_id' => $shopProduct->currency_code,
                     ],
                 ],
@@ -72,11 +73,8 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
             ]);
 
             if ($response->successful()) {
-                // preferenceID
-                $preferenceId = $response->json()['id'];
-
                 // Redirect link
-                return ("https://www.mercadopago.com/checkout/v1/redirect?preference-id=" . $preferenceId);
+                Redirect::to($response->json()['init_point'])->send();
             } else {
                 Log::error('MercadoPago Payment: ' . $response->body());
                 throw new Exception('Payment failed');
@@ -178,8 +176,8 @@ private function MpPayment(string $paymentID, bool $notification): string
 
         if ($response->successful()) {
             $mercado = $response->json();
-            $status = $mercado->status;
-            $payment = Payment::findOrFail($mercado->metadata->crtl_panel_payment_id);
+            $status = $mercado['status'];
+            $payment = Payment::findOrFail($mercado['metadata']['crtl_panel_payment_id']);
             $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
 
             if ($status == "approved") {

From 7012a68265e47092e727358d1e049f386c08b0f2 Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Thu, 25 Jan 2024 21:42:23 -0300
Subject: [PATCH 249/514] mercado pago end

---
 README.md                                     |  2 +-
 .../MercadoPago/MercadoPagoExtension.php      | 50 +++++--------------
 ..._24_120635_create_mercadopago_settings.php |  8 +--
 3 files changed, 17 insertions(+), 43 deletions(-)

diff --git a/README.md b/README.md
index c121ff78a..35c7ab7e4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 ### Features
 
--   PayPal, Stripe and Mollie Integration
+-   PayPal, Stripe, Mollie and MercadoPago Integration
 -   Hourly, Weekely, Monthly, Quarterly and Annual billing Cycles
 -   Referral System
 -   Partner System
diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index 42540e693..c37d640e6 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -60,8 +60,8 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                     [
                         'title' => "Order #{$payment->id} - " . $shopProduct->name,
                         'quantity' => 1,
-                        // convert shopProduct to float(this is string) 
-                        'unit_price' => floatval($shopProduct->getTotalPrice()),
+                        // convert to float
+                        'unit_price' => floatval($totalPriceString),
                         'currency_id' => $shopProduct->currency_code,
                     ],
                 ],
@@ -111,54 +111,29 @@ static function Checker(Request $request): void
     static function Webhook(Request $request): JsonResponse
     {
         $topic = $request->input('topic');
-        $msg = 'unset';
-        $status = 400;
         if ($topic === 'merchant_order') {
-            $msg = 'ignored';
-            $status = 200;
+            // ignore other types IPN 
+            return response()->json(['success' => true]);
         } else if ($topic === 'payment') {
-            $msg = 'ignored';
-            $status = 200;
+            // ignore other types IPN 
+            return response()->json(['success' => true]);
         } else {
             try {
                 $notificationId = $request->input('data.id') ?? $request->input('id') ?? $request->input('payment_id') ?? 'unknown';
                 if ($notificationId == 'unknown') {
-                    $msg = 'unknown payment.';
-                    $status = 400;
+                    return response()->json(['success' => false]);
                 } else if ($notificationId == '123456') {
-                    $msg = 'MercadoPago api test';
-                    $status = 200;
+                    // mercado pago api test
+                    return response()->json(['success' => true]);
                 } else {
-                    $MpPayment = self::MpPayment($notificationId, true);
-                    switch ($MpPayment) {
-                        case "paid":
-                            $msg = $MpPayment;
-                            $status = 200;
-                            break;
-
-                        case "cancelled":
-                            $msg = $MpPayment;
-                            $status = 200;
-                            break;
-
-                        case "processing":
-                            $msg = $MpPayment;
-                            $status = 200;
-                            break;
-                        default:
-                            $msg = 'unknown';
-                            $status = 400;
-                            break;
-                    }
+                    self::MpPayment($notificationId, true);
                 }
             } catch (Exception $ex) {
                 Log::error('MercadoPago Webhook(IPN) Payment: ' . $ex->getMessage());
-                $msg = 'error';
-                $status = 500;
+                return response()->json(['success' => false]);
             }
         }
-        $response = new JsonResponse($msg, $status);
-        return $response;
+        return response()->json(['success' => true]);
     }
     /**
      * Mercado Pago Payment checker 
@@ -166,7 +141,6 @@ static function Webhook(Request $request): JsonResponse
     private function MpPayment(string $paymentID, bool $notification): string
     {
         $MpResponse = "unknown";
-        $payment = "unknown";
         $url = "https://api.mercadopago.com/v1/payments/" . $paymentID;
         $settings = new MercadoPagoSettings();
         $response = Http::withHeaders([
diff --git a/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php b/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php
index f27411c30..5d4cf411c 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/migrations/2024_01_24_120635_create_mercadopago_settings.php
@@ -6,13 +6,13 @@ class CreateMercadoPagoSettings extends SettingsMigration
 {
     public function up(): void
     {
-        $this->migrator->addEncrypted('mpago.access_token', null);
-        $this->migrator->add('mpago.enabled', false);
+        $this->migrator->addEncrypted('mercadopago.access_token', null);
+        $this->migrator->add('mercadopago.enabled', false);
     }
 
     public function down(): void
     {
-        $this->migrator->delete('mpago.access_token');
-        $this->migrator->delete('mpago.enabled');
+        $this->migrator->delete('mercadopago.access_token');
+        $this->migrator->delete('mercadopago.enabled');
     }
 }

From 6d61ca5ceff04119452b138b5d6ae5b3bead34e0 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 5 Feb 2024 09:27:24 +0100
Subject: [PATCH 250/514] fix installer

---
 ..._01_181334_create_pterodactyl_settings.php |   6 ++++--
 storage/app/public/logo.png                   | Bin 95961 -> 96827 bytes
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index f3b5b37d2..9ab9d72f6 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -10,8 +10,10 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
-        $this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
+        //$this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
+        //$this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
+        $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
+        $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
         $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL') : env('PTERODACTYL_URL', ''));
         $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT') : 200);
     }
diff --git a/storage/app/public/logo.png b/storage/app/public/logo.png
index 1dda9e7c6c5aa69f3b2d512e6a0521aee51f7b3c..8a68b5fbd7c9eb5949713891ee898d7bda8a8eaf 100644
GIT binary patch
literal 96827
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

literal 95961
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
Ef&*k|!vFvP


From 9cc6e83819ae7ae7b8ec3b5276a197592d9747f8 Mon Sep 17 00:00:00 2001
From: Vikas Dongre <zvikasdongre@gmail.com>
Date: Sat, 17 Feb 2024 23:38:30 +0530
Subject: [PATCH 251/514] fix: installer showing feeding failed, as well as
 adding proper error handling.

---
 public/install/forms.php     | 35 +++++++++++++++++------------------
 public/install/functions.php | 22 +++++++++++++++-------
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 98f05657d..96f1dfa17 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -29,8 +29,7 @@
 
     try {
         $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
-    }
-    catch (mysqli_sql_exception $e) {
+    } catch (mysqli_sql_exception $e) {
         wh_log($e->getMessage(), 'error');
         header('LOCATION: index.php?step=2&message=' . $e->getMessage());
         exit();
@@ -69,26 +68,26 @@
     wh_log('Feeding the Database', 'debug');
     $logs = '';
 
-    //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
-    //$logs .= run_console('composer install --no-dev --optimize-autoloader');
-    if (!str_contains(getenv('APP_KEY'), 'base64')) {
-        $logs .= run_console('php artisan key:generate --force');
-    } else {
-        $logs .= "Key already exists. Skipping\n";
-    }
-    $logs .= run_console('php artisan storage:link');
-    $logs .= run_console('php artisan migrate --seed --force');
-    $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
-    $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
+    try {
+        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
+        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
+        if (!str_contains(getenv('APP_KEY'), 'base64')) {
+            $logs .= run_console('php artisan key:generate --force');
+        } else {
+            $logs .= "Key already exists. Skipping\n";
+        }
+        $logs .= run_console('php artisan storage:link');
+        $logs .= run_console('php artisan migrate --seed --force');
+        $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
+        $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
 
-    wh_log($logs, 'debug');
+        wh_log($logs, 'debug');
 
-    if (str_contains(getenv('APP_KEY'), 'base64')) {
         wh_log('Feeding the Database successful', 'debug');
         header('LOCATION: index.php?step=3');
-    } else {
-        wh_log('Feeding the Database failed', 'debug');
-        header('LOCATION: index.php?step=2.5&message=There was an error. Please check the installer.log file in /var/www/controlpanel/storage/logs !');
+    } catch (\Throwable $th) {
+        wh_log('Feeding the Database failed', 'error');
+        header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
     }
 }
 
diff --git a/public/install/functions.php b/public/install/functions.php
index 8eb1318cb..451d8b956 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -10,7 +10,7 @@
 use Monolog\Logger;
 
 if (!file_exists('../../.env')) {
-        echo run_console('cp .env.example .env');
+    echo run_console('cp .env.example .env');
 }
 
 (new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
@@ -150,7 +150,8 @@ function checkExtensions(): array
     return $not_ok;
 }
 
-function removeQuotes($string){
+function removeQuotes($string)
+{
     return str_replace('"', "", $string);
 }
 
@@ -162,7 +163,7 @@ function removeQuotes($string){
  */
 function setenv($envKey, $envValue)
 {
-    $envFile = dirname(__FILE__, 3).'/.env';
+    $envFile = dirname(__FILE__, 3) . '/.env';
     $str = file_get_contents($envFile);
 
     $str .= "\n"; // In case the searched variable is in the last line without \n
@@ -236,9 +237,16 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
     $path = dirname(__FILE__, 3);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
     $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
-
-    wh_log('command result: ' . stream_get_contents($pipes[1]), 'debug');
-    return stream_get_contents($pipes[1]);
+    $output = stream_get_contents($pipes[1]);
+    $exit_code = proc_close($handle);
+
+    if ($exit_code > 0) {
+        wh_log('command result: ' . $output, 'error');
+        throw new Exception("There was an error after running command `$command`", $exit_code);
+        return $output;
+    } else {
+        return $output;
+    }
 }
 
 /**
@@ -259,7 +267,7 @@ function wh_log(string $message, string $level = 'info', array $context = []): v
 
     switch (strtolower($level)) {
         case 'debug': // Only log debug messages if APP_DEBUG is true
-            if(getenv('APP_DEBUG') === false) return;
+            if (getenv('APP_DEBUG') === false) return;
             $log->debug($message, $context);
             break;
         case 'info':

From bfb169e1917f4249ea55aa57c86342aa4a320a91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=A2=C2=80MrWeez?= <arsenyplis2018@gmail.com>
Date: Thu, 29 Feb 2024 01:29:31 +0300
Subject: [PATCH 252/514] Added support for php8.3

---
 public/install/functions.php |   2 +-
 storage/app/public/logo.png  | Bin
 2 files changed, 1 insertion(+), 1 deletion(-)
 mode change 100644 => 100755 storage/app/public/logo.png

diff --git a/public/install/functions.php b/public/install/functions.php
index 451d8b956..a5f2b0454 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -19,7 +19,7 @@
 
 $requirements = [
     'minPhp' => '8.1',
-    'maxPhp' => '8.3', // This version is not supported
+    'maxPhp' => '8.4', // This version is not supported
     'mysql' => '5.7.22',
 ];
 
diff --git a/storage/app/public/logo.png b/storage/app/public/logo.png
old mode 100644
new mode 100755

From afe3fd23c5d0156fd1a14325daf8238e2357b46f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=A2=C2=80MrWeez?= <arsenyplis2018@gmail.com>
Date: Thu, 29 Feb 2024 13:42:15 +0300
Subject: [PATCH 253/514] Repair docker image for PHP-FPM by Hyd3r1

---
 docker/docker-compose.yml | 20 +++-----------------
 docker/php/Dockerfile     | 13 +++++--------
 2 files changed, 8 insertions(+), 25 deletions(-)

diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 98eded4ac..56c9e24de 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -12,7 +12,7 @@ services:
     ports:
       - 80:80
     volumes:
-      - "../:/var/www/html:delegated"
+      - "../:/var/www/html"
     depends_on:
       - php
       - mysql
@@ -42,7 +42,7 @@ services:
       dockerfile: docker/php/Dockerfile
     container_name: controlpanel_php
     volumes:
-      - "../:/var/www/html:delegated"
+      - "../:/var/www/html"
     networks:
       - laravel
 
@@ -61,19 +61,5 @@ services:
     networks:
       - laravel
 
-  redis:
-    image: "redis:alpine"
-    command: redis-server --requirepass sOmE_sEcUrE_pAsS
-    ports:
-      - "6379:6379"
-    volumes:
-      - $PWD/redis-data:/var/lib/redis
-      - $PWD/redis.conf:/usr/local/etc/redis/redis.conf
-    environment:
-      - REDIS_REPLICATION_MODE=master
-    networks:
-      - laravel
-
-
 volumes:
-  mysql:
+  mysql:
\ No newline at end of file
diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile
index 65dfab874..4b8d91dd9 100644
--- a/docker/php/Dockerfile
+++ b/docker/php/Dockerfile
@@ -1,16 +1,14 @@
-FROM php:8.0-fpm-alpine3.13
+FROM php:8.1-fpm-buster
+RUN apt-get update \
+  && apt-get install -y build-essential zlib1g-dev default-mysql-client curl gnupg procps vim git unzip libzip-dev libpq-dev libicu-dev libonig-dev libpng-dev libjpeg-dev libfreetype6-dev
 
-RUN apk update && apk upgrade
-RUN apk add --no-cache --repository https://alpine.global.ssl.fastly.net/alpine/edge/community/
-
-RUN apk add --no-cache curl-dev icu-dev libzip-dev
-RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip
+RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
 
 ADD ./docker/php/www.conf /usr/local/etc/php-fpm.d/
 
 RUN mkdir -p /var/www/html
 
-RUN addgroup -g 1000 laravel && adduser -G laravel -g laravel -s /bin/sh -D laravel
+RUN addgroup --gid 1000 laravel && adduser --ingroup laravel --uid 1000 --shell /bin/sh --disabled-password --gecos "" laravel
 RUN chown laravel:laravel /var/www/html
 
 WORKDIR /var/www/html
@@ -18,4 +16,3 @@ WORKDIR /var/www/html
 USER laravel
 
 COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
-

From 6f6517033e0a3a23e6e3b15e0138d57422e56743 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=A2=C2=80MrWeez?= <arsenyplis2018@gmail.com>
Date: Thu, 29 Feb 2024 14:15:58 +0300
Subject: [PATCH 254/514] Fixed old link and name

---
 themes/default/views/admin/overview/index.blade.php        | 2 +-
 themes/default/views/information/privacy-content.blade.php | 4 ++--
 themes/default/views/information/tos-content.blade.php     | 4 ++++
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index e9c4debfe..09f07e93b 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -43,7 +43,7 @@ class="mr-2 fab fa-discord"></i> {{__('Support server')}}</a>
                             class="mr-2 fas fa-link"></i> {{__('Documentation')}}</a>
                 </div>
                 <div class="col-md-3">
-                    <a href="https://github.com/ControlPanel-gg/dashboard" class="px-3 btn btn-dark btn-block"><i
+                    <a href="https://github.com/Ctrlpanel-gg/panel" class="px-3 btn btn-dark btn-block"><i
                             class="mr-2 fab fa-github"></i> {{__('Github')}}</a>
                 </div>
                 <div class="col-md-3">
diff --git a/themes/default/views/information/privacy-content.blade.php b/themes/default/views/information/privacy-content.blade.php
index 5f465e829..9b1db4995 100644
--- a/themes/default/views/information/privacy-content.blade.php
+++ b/themes/default/views/information/privacy-content.blade.php
@@ -49,8 +49,8 @@
             Service or from the Service infrastructure itself (for example, the duration of a page visit).</p>
     </li>
     <li>
-        <p><strong>Website</strong> refers to CtrlPanel, accessible from <a href="controlpanel"
-                rel="external nofollow noopener" target="_blank">controlpanel</a></p>
+        <p><strong>Website</strong> refers to CtrlPanel, accessible from <a href="ctrlpanel"
+                rel="external nofollow noopener" target="_blank">ctrlpanel</a></p>
     </li>
     <li>
         <p><strong>You</strong> means the individual accessing or using the Service, or the company, or other legal
diff --git a/themes/default/views/information/tos-content.blade.php b/themes/default/views/information/tos-content.blade.php
index 6dd7c1293..e9a42927f 100644
--- a/themes/default/views/information/tos-content.blade.php
+++ b/themes/default/views/information/tos-content.blade.php
@@ -146,6 +146,10 @@
 
 <p>- PayPal</p>
 
+<p>- Stripe</p>
+
+<p>- Mollie</p>
+
 <p></p>
 
 <p>You agree to provide current, complete, and accurate purchase and account information for all purchases made via the Site. You further agree to promptly update account and payment information, including email address, payment method, and payment card expiration date, so that we can complete your transactions and contact you as needed. Sales tax will be added to the price of purchases as deemed required by us. We may change prices at any time. All payments shall beinU.S. dollars.</p>

From 6a11341c0a4256a5e59d8280a756d80eda36fea0 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 14 Mar 2024 14:40:08 +0100
Subject: [PATCH 255/514] Fix roles notification

---
 app/Http/Controllers/Admin/UserController.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 60a1120fb..b023d2328 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -316,7 +316,8 @@ public function notify(Request $request)
                 ->line(new HtmlString($data['content']));
         }
         $all = $data['all'] ?? false;
-        if(!$data["roles"]){
+        $roles = $data['roles'] ?? false;
+        if(!$roles){
             $users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
         } else{
             $users = User::role($data["roles"])->get();

From 7f0d934ed5afe30de58e46e2397473a7efd87e71 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 12 Apr 2024 14:03:11 +0200
Subject: [PATCH 256/514] =?UTF-8?q?feat:=20=E2=9C=A8=20Create=20LegacySett?=
 =?UTF-8?q?ingsMigration=20to=20centralize=20migration=20methods?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Classes/LegacySettingsMigration.php | 58 +++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 app/Classes/LegacySettingsMigration.php

diff --git a/app/Classes/LegacySettingsMigration.php b/app/Classes/LegacySettingsMigration.php
new file mode 100644
index 000000000..3b6ccfafd
--- /dev/null
+++ b/app/Classes/LegacySettingsMigration.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Classes;
+
+use Exception;
+use Illuminate\Support\Facades\DB;
+use Spatie\LaravelSettings\Migrations\SettingsMigration;
+
+
+abstract class LegacySettingsMigration extends SettingsMigration
+{
+    public function getNewValue(string $name)
+    {
+        $new_value = DB::table('settings')->where([['group', '=', 'general'], ['name', '=', $name]])->get(['payload'])->first();
+
+        // Some keys returns '""' as a value.
+        if ($new_value->payload === '""') {
+            return null;
+        }
+
+        // remove the quotes from the string
+        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
+            return substr($new_value->payload, 1, -1);
+        }
+
+        return $new_value->payload;
+    }
+
+    /**
+     * Get the old value from the settings_old table.
+     * @param string $key The key to get the value from table.
+     * @param int|string|bool|null $default The default value to return if the value is null. If value is not nullable, a default must be provided.
+     */
+    public function getOldValue(string $key,  int|string|bool|null $default = null)
+    {
+        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
+
+        if (is_null($old_value->value)) {
+            return $default;
+        }
+
+        switch ($old_value->type) {
+            case 'string':
+            case 'text':
+                // Edgecase: The value is a boolean, but it's stored as a string.
+                if ($old_value->value === "false" || $old_value->value === "true") {
+                    return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
+                }
+                return $old_value->value;
+            case 'boolean':
+                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
+            case 'integer':
+                return filter_var($old_value->value, FILTER_VALIDATE_INT);
+            default:
+                throw new Exception("Unknown type: {$old_value->type}");
+        }
+    }
+}

From 48cce11ebc776fc71f3d32009fc6e01821b89d26 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 12 Apr 2024 14:04:26 +0200
Subject: [PATCH 257/514] =?UTF-8?q?fix:=20=F0=9F=9A=91=EF=B8=8F=20Use=20Le?=
 =?UTF-8?q?gacySettingsMigration=20&&=20mind=20nullable=20values?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...3_02_01_164731_create_general_settings.php | 61 +++-------------
 ..._01_181334_create_pterodactyl_settings.php | 60 +++-------------
 ...2023_02_01_181453_create_mail_settings.php | 47 +-----------
 ...2023_02_01_181925_create_user_settings.php | 71 ++++---------------
 ...23_02_01_181950_create_server_settings.php | 53 ++------------
 ...3_02_01_182021_create_invoice_settings.php | 63 +++-------------
 ...3_02_01_182043_create_discord_settings.php | 59 +++------------
 ...23_02_01_182108_create_locale_settings.php | 53 ++------------
 ..._02_01_182135_create_referral_settings.php | 55 ++------------
 ...3_02_01_182158_create_website_settings.php | 60 +++-------------
 ...23_02_04_181156_create_ticket_settings.php | 52 +-------------
 11 files changed, 78 insertions(+), 556 deletions(-)

diff --git a/database/settings/2023_02_01_164731_create_general_settings.php b/database/settings/2023_02_01_164731_create_general_settings.php
index 5d1835907..5e7360dcf 100644
--- a/database/settings/2023_02_01_164731_create_general_settings.php
+++ b/database/settings/2023_02_01_164731_create_general_settings.php
@@ -1,9 +1,9 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateGeneralSettings extends SettingsMigration
+class CreateGeneralSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
@@ -11,15 +11,15 @@ public function up(): void
 
         // Get the user-set configuration values from the old table.
         $this->migrator->add('general.store_enabled',  true);
-        $this->migrator->add('general.credits_display_name', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') : 'Credits');
+        $this->migrator->add('general.credits_display_name', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits') : 'Credits');
         $this->migrator->add('general.recaptcha_site_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SITE_KEY") : env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'));
         $this->migrator->add('general.recaptcha_secret_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SECRET_KEY") : env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'));
-        $this->migrator->add('general.recaptcha_enabled', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:ENABLED") : true);
-        $this->migrator->add('general.phpmyadmin_url', $table_exists ? $this->getOldValue("SETTINGS::MISC:PHPMYADMIN:URL") : env('PHPMYADMIN_URL', ''));
-        $this->migrator->add('general.alert_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_ENABLED") : false);
-        $this->migrator->add('general.alert_type', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_TYPE") : 'dark');
-        $this->migrator->add('general.alert_message', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_MESSAGE") : '');
-        $this->migrator->add('general.theme', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:THEME") : 'default');
+        $this->migrator->add('general.recaptcha_enabled', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:ENABLED", false) : false);
+        $this->migrator->add('general.phpmyadmin_url', $table_exists ? $this->getOldValue("SETTINGS::MISC:PHPMYADMIN:URL") : env('PHPMYADMIN_URL'));
+        $this->migrator->add('general.alert_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_ENABLED", false) : false);
+        $this->migrator->add('general.alert_type', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_TYPE", 'dark') : 'dark');
+        $this->migrator->add('general.alert_message', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_MESSAGE") : null);
+        $this->migrator->add('general.theme', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:THEME", 'default') : 'default');
     }
 
     public function down(): void
@@ -93,47 +93,4 @@ public function down(): void
         $this->migrator->delete('general.alert_message');
         $this->migrator->delete('general.theme');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'general'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index 9ab9d72f6..d8f65248a 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -1,21 +1,20 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreatePterodactylSettings extends SettingsMigration
+class CreatePterodactylSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
-        // Get the user-set configuration values from the old table.
-        //$this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
-        //$this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
-        $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
-        $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
-        $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL') : env('PTERODACTYL_URL', ''));
-        $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT') : 200);
+        $this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN', '') : env('PTERODACTYL_TOKEN', ''));
+        $this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN', '') : '');
+        // $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
+        // $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
+        $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL', '') : env('PTERODACTYL_URL', ''));
+        $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT', 200) : 200);
     }
 
     public function down(): void
@@ -54,47 +53,4 @@ public function down(): void
         $this->migrator->delete('pterodactyl.panel_url');
         $this->migrator->delete('pterodactyl.per_page_limit');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'pterodactyl'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index 8437a61ae..42ab0f4b2 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -1,9 +1,9 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateMailSettings extends SettingsMigration
+class CreateMailSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
@@ -83,47 +83,4 @@ public function down(): void
         $this->migrator->delete('mail.mail_from_name');
         $this->migrator->delete('mail.mail_mailer');
     }
-
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'mail'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_181925_create_user_settings.php b/database/settings/2023_02_01_181925_create_user_settings.php
index 524ef0b76..8c9e088bf 100644
--- a/database/settings/2023_02_01_181925_create_user_settings.php
+++ b/database/settings/2023_02_01_181925_create_user_settings.php
@@ -1,27 +1,27 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateUserSettings extends SettingsMigration
+class CreateUserSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('user.credits_reward_after_verify_discord', $table_exists ? $this->getOldValue('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') : 250);
-        $this->migrator->add('user.credits_reward_after_verify_email', $table_exists ? $this->getOldValue('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') : 250);
-        $this->migrator->add('user.force_discord_verification', $table_exists ? $this->getOldValue('SETTINGS::USER:FORCE_DISCORD_VERIFICATION') : false);
-        $this->migrator->add('user.force_email_verification', $table_exists ? $this->getOldValue('SETTINGS::USER:FORCE_EMAIL_VERIFICATION') : false);
-        $this->migrator->add('user.initial_credits', $table_exists ? $this->getOldValue('SETTINGS::USER:INITIAL_CREDITS') : 250);
-        $this->migrator->add('user.initial_server_limit', $table_exists ? $this->getOldValue('SETTINGS::USER:INITIAL_SERVER_LIMIT') : 1);
-        $this->migrator->add('user.min_credits_to_make_server', $table_exists ? $this->getOldValue('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER') : 50);
-        $this->migrator->add('user.server_limit_after_irl_purchase', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') : 10);
-        $this->migrator->add('user.server_limit_after_verify_discord', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') : 2);
-        $this->migrator->add('user.server_limit_after_verify_email', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') : 2);
-        $this->migrator->add('user.register_ip_check', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:REGISTER_IP_CHECK") : true);
-        $this->migrator->add('user.creation_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:CREATION_OF_NEW_USERS") : true);
+        $this->migrator->add('user.credits_reward_after_verify_discord', $table_exists ? $this->getOldValue('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD', 250) : 250);
+        $this->migrator->add('user.credits_reward_after_verify_email', $table_exists ? $this->getOldValue('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL', 250) : 250);
+        $this->migrator->add('user.force_discord_verification', $table_exists ? $this->getOldValue('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', false) : false);
+        $this->migrator->add('user.force_email_verification', $table_exists ? $this->getOldValue('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', false) : false);
+        $this->migrator->add('user.initial_credits', $table_exists ? $this->getOldValue('SETTINGS::USER:INITIAL_CREDITS', 250) : 250);
+        $this->migrator->add('user.initial_server_limit', $table_exists ? $this->getOldValue('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1) : 1);
+        $this->migrator->add('user.min_credits_to_make_server', $table_exists ? $this->getOldValue('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50) : 50);
+        $this->migrator->add('user.server_limit_after_irl_purchase', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE', 10) : 10);
+        $this->migrator->add('user.server_limit_after_verify_discord', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD', 2) : 2);
+        $this->migrator->add('user.server_limit_after_verify_email', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL', 2) : 2);
+        $this->migrator->add('user.register_ip_check', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:REGISTER_IP_CHECK", true) : true);
+        $this->migrator->add('user.creation_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:CREATION_OF_NEW_USERS", true) : true);
     }
 
     public function down(): void
@@ -117,47 +117,4 @@ public function down(): void
         $this->migrator->delete('user.register_ip_check');
         $this->migrator->delete('user.creation_enabled');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'user'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_181950_create_server_settings.php b/database/settings/2023_02_01_181950_create_server_settings.php
index 7198adcb6..de25c94f9 100644
--- a/database/settings/2023_02_01_181950_create_server_settings.php
+++ b/database/settings/2023_02_01_181950_create_server_settings.php
@@ -1,18 +1,18 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateServerSettings extends SettingsMigration
+class CreateServerSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('server.allocation_limit', $table_exists ? $this->getOldValue('SETTINGS::SERVER:ALLOCATION_LIMIT') : 200);
-        $this->migrator->add('server.creation_enabled', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS') : true);
-        $this->migrator->add('server.enable_upgrade', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:ENABLE_UPGRADE') : false);
+        $this->migrator->add('server.allocation_limit', $table_exists ? $this->getOldValue('SETTINGS::SERVER:ALLOCATION_LIMIT', 200) : 200);
+        $this->migrator->add('server.creation_enabled', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS', true) : true);
+        $this->migrator->add('server.enable_upgrade', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:ENABLE_UPGRADE', false) : false);
     }
 
     public function down(): void
@@ -42,47 +42,4 @@ public function down(): void
         $this->migrator->delete('server.creation_enabled');
         $this->migrator->delete('server.enable_upgrade');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'server'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_182021_create_invoice_settings.php b/database/settings/2023_02_01_182021_create_invoice_settings.php
index 8569c3ff4..effc67d7e 100644
--- a/database/settings/2023_02_01_182021_create_invoice_settings.php
+++ b/database/settings/2023_02_01_182021_create_invoice_settings.php
@@ -1,23 +1,23 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateInvoiceSettings extends SettingsMigration
+class CreateInvoiceSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('invoice.company_address', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_ADDRESS') : '');
-        $this->migrator->add('invoice.company_mail', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_MAIL') : '');
-        $this->migrator->add('invoice.company_name', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_NAME') : '');
-        $this->migrator->add('invoice.company_phone', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_PHONE') : '');
-        $this->migrator->add('invoice.company_vat', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_VAT') : '');
-        $this->migrator->add('invoice.company_website', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_WEBSITE') : '');
-        $this->migrator->add('invoice.enabled', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:ENABLED') : false);
-        $this->migrator->add('invoice.prefix', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:PREFIX') : 'INV');
+        $this->migrator->add('invoice.company_address', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_ADDRESS') : null);
+        $this->migrator->add('invoice.company_mail', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_MAIL') : null);
+        $this->migrator->add('invoice.company_name', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_NAME') : null);
+        $this->migrator->add('invoice.company_phone', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_PHONE') : null);
+        $this->migrator->add('invoice.company_vat', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_VAT') : null);
+        $this->migrator->add('invoice.company_website', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_WEBSITE') : null);
+        $this->migrator->add('invoice.enabled', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:ENABLED', false) : false);
+        $this->migrator->add('invoice.prefix', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:PREFIX') : null);
     }
 
     public function down(): void
@@ -82,47 +82,4 @@ public function down(): void
         $this->migrator->delete('invoice.enabled');
         $this->migrator->delete('invoice.prefix');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'invoice'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_182043_create_discord_settings.php b/database/settings/2023_02_01_182043_create_discord_settings.php
index 60e450b90..21ccc5b63 100644
--- a/database/settings/2023_02_01_182043_create_discord_settings.php
+++ b/database/settings/2023_02_01_182043_create_discord_settings.php
@@ -1,21 +1,21 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateDiscordSettings extends SettingsMigration
+class CreateDiscordSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('discord.bot_token', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:BOT_TOKEN') : '');
-        $this->migrator->add('discord.client_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_ID') : '');
-        $this->migrator->add('discord.client_secret', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_SECRET') : '');
-        $this->migrator->add('discord.guild_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:GUILD_ID') : '');
-        $this->migrator->add('discord.invite_url', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:INVITE_URL') : '');
-        $this->migrator->add('discord.role_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:ROLE_ID') : '');
+        $this->migrator->add('discord.bot_token', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:BOT_TOKEN') : null);
+        $this->migrator->add('discord.client_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_ID') : null);
+        $this->migrator->add('discord.client_secret', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_SECRET') : null);
+        $this->migrator->add('discord.guild_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:GUILD_ID') : null);
+        $this->migrator->add('discord.invite_url', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:INVITE_URL') : null);
+        $this->migrator->add('discord.role_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:ROLE_ID') : null);
     }
 
     public function down(): void
@@ -67,47 +67,4 @@ public function down(): void
         $this->migrator->delete('discord.invite_url');
         $this->migrator->delete('discord.role_id');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'discord'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_182108_create_locale_settings.php b/database/settings/2023_02_01_182108_create_locale_settings.php
index 014dd8fd4..13dbde9dd 100644
--- a/database/settings/2023_02_01_182108_create_locale_settings.php
+++ b/database/settings/2023_02_01_182108_create_locale_settings.php
@@ -1,9 +1,9 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateLocaleSettings extends SettingsMigration
+class CreateLocaleSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
@@ -11,10 +11,10 @@ public function up(): void
 
         // Get the user-set configuration values from the old table.
         $this->migrator->add('locale.available', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:AVAILABLE') : '');
-        $this->migrator->add('locale.clients_can_change', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') : true);
+        $this->migrator->add('locale.clients_can_change', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE', true) : true);
         $this->migrator->add('locale.datatables', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DATATABLES') : 'en-gb');
-        $this->migrator->add('locale.default', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DEFAULT') : 'en');
-        $this->migrator->add('locale.dynamic', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DYNAMIC') : false);
+        $this->migrator->add('locale.default', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DEFAULT', 'en') : 'en');
+        $this->migrator->add('locale.dynamic', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DYNAMIC', false) : false);
     }
 
     public function down(): void
@@ -58,47 +58,4 @@ public function down(): void
         $this->migrator->delete('locale.default');
         $this->migrator->delete('locale.dynamic');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'locale'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_182135_create_referral_settings.php b/database/settings/2023_02_01_182135_create_referral_settings.php
index 5727557b1..839f0e28b 100644
--- a/database/settings/2023_02_01_182135_create_referral_settings.php
+++ b/database/settings/2023_02_01_182135_create_referral_settings.php
@@ -1,20 +1,20 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateReferralSettings extends SettingsMigration
+class CreateReferralSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('referral.always_give_commission', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION') : false);
-        $this->migrator->add('referral.enabled', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ENABLED') : false);
+        $this->migrator->add('referral.always_give_commission', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION', false) : false);
+        $this->migrator->add('referral.enabled', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ENABLED', false) : false);
         $this->migrator->add('referral.reward', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::REWARD') : 100);
-        $this->migrator->add('referral.mode', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL:MODE') : 'sign-up');
-        $this->migrator->add('referral.percentage', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL:PERCENTAGE') : 100);
+        $this->migrator->add('referral.mode', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL:MODE', 'sign-up') : 'sign-up');
+        $this->migrator->add('referral.percentage', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL:PERCENTAGE', 100) : 100);
     }
 
     public function down(): void
@@ -65,47 +65,4 @@ public function down(): void
         $this->migrator->delete('referral.mode');
         $this->migrator->delete('referral.percentage');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'referral'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_01_182158_create_website_settings.php b/database/settings/2023_02_01_182158_create_website_settings.php
index fd542ff33..2bbdd5b57 100644
--- a/database/settings/2023_02_01_182158_create_website_settings.php
+++ b/database/settings/2023_02_01_182158_create_website_settings.php
@@ -1,27 +1,28 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateWebsiteSettings extends SettingsMigration
+class CreateWebsiteSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('website.motd_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_ENABLED") : true);
+        $this->migrator->add('website.motd_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_ENABLED", true) : true);
         $this->migrator->add(
             'website.motd_message',
             $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:MOTD_MESSAGE") :
                 "<h1 style='text-align: center;'><img style='display: block; margin-left: auto; margin-right: auto;' src='https://ctrlpanel.gg/img/controlpanel.png' alt=' width='200' height='200'><span style='font-size: 36pt;'>CtrlPanel.gg</span></h1>
  <p><span style='font-size: 18pt;'>Thank you for using our Software</span></p>
  <p><span style='font-size: 18pt;'>If you have any questions, make sure to join our <a href='https://discord.com/invite/4Y6HjD2uyU' target='_blank' rel='noopener'>Discord</a></span></p>
- <p><span style='font-size: 10pt;'>(you can change this message in the <a href='admin/settings#system'>Settings</a> )</span></p>");
-        $this->migrator->add('website.show_imprint', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_IMPRINT") : false);
-        $this->migrator->add('website.show_privacy', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_PRIVACY") : false);
-        $this->migrator->add('website.show_tos', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_TOS") : false);
-        $this->migrator->add('website.useful_links_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:USEFULLINKS_ENABLED") : true);
+ <p><span style='font-size: 10pt;'>(you can change this message in the <a href='admin/settings#system'>Settings</a> )</span></p>"
+        );
+        $this->migrator->add('website.show_imprint', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_IMPRINT", false) : false);
+        $this->migrator->add('website.show_privacy', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_PRIVACY", false) : false);
+        $this->migrator->add('website.show_tos', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SHOW_TOS", false) : false);
+        $this->migrator->add('website.useful_links_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:USEFULLINKS_ENABLED", true) : true);
         $this->migrator->add('website.seo_title', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SEO_TITLE") : 'CtrlPanel.gg');
         $this->migrator->add('website.seo_description', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:SEO_DESCRIPTION") : 'Billing software for Pterodactyl Panel.');
         $this->migrator->add('website.enable_login_logo', true);
@@ -96,47 +97,4 @@ public function down(): void
         $this->migrator->delete('website.seo_description');
         $this->migrator->delete('website.enable_login_logo');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'website'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }
diff --git a/database/settings/2023_02_04_181156_create_ticket_settings.php b/database/settings/2023_02_04_181156_create_ticket_settings.php
index 1e71ad3a8..41eefe737 100644
--- a/database/settings/2023_02_04_181156_create_ticket_settings.php
+++ b/database/settings/2023_02_04_181156_create_ticket_settings.php
@@ -1,9 +1,9 @@
 <?php
 
-use Spatie\LaravelSettings\Migrations\SettingsMigration;
+use App\Classes\LegacySettingsMigration;
 use Illuminate\Support\Facades\DB;
 
-class CreateTicketSettings extends SettingsMigration
+class CreateTicketSettings extends LegacySettingsMigration
 {
     public function up(): void
     {
@@ -34,52 +34,4 @@ public function down(): void
         $this->migrator->delete('ticket.enabled');
         $this->migrator->delete('ticket.notify');
     }
-
-    public function getNewValue(string $name)
-    {
-        $new_value = DB::table('settings')->where([['group', '=', 'ticket'], ['name', '=', $name]])->get(['payload'])->first();
-
-        // Some keys returns '""' as a value.
-        if ($new_value->payload === '""') {
-            return null;
-        }
-
-        // remove the quotes from the string
-        if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
-            return substr($new_value->payload, 1, -1);
-        }
-
-        return $new_value->payload;
-    }
-
-    public function getOldValue(string $key)
-    {
-        // Always get the first value of the key.
-        $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
-
-        // Handle the old values to return without it being a string in all cases.
-
-        if (is_null($old_value)) {
-            return '';
-        }
-        if ($old_value->type === "string" || $old_value->type === "text") {
-            if (is_null($old_value->value)) {
-                return '';
-            }
-
-
-            // Some values have the type string, but their values are boolean.
-            if ($old_value->value === "false" || $old_value->value === "true") {
-                return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-            }
-
-            return $old_value->value;
-        }
-
-        if ($old_value->type === "boolean") {
-            return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
-        }
-
-        return filter_var($old_value->value, FILTER_VALIDATE_INT);
-    }
 }

From 330ea45c5b9b4e3cc16d765f1c204b70bf7db42d Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 12 Apr 2024 21:01:00 +0200
Subject: [PATCH 258/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Try=20catch=20for?=
 =?UTF-8?q?=20possible=20non=20available=20settings?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Classes/LegacySettingsMigration.php   | 11 ++++++---
 app/Http/Controllers/ServerController.php |  3 ---
 app/Providers/AppServiceProvider.php      | 28 ++++++++++++-----------
 config/settings.php                       |  2 +-
 routes/web.php                            |  8 ++++---
 5 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/app/Classes/LegacySettingsMigration.php b/app/Classes/LegacySettingsMigration.php
index 3b6ccfafd..dd32a7613 100644
--- a/app/Classes/LegacySettingsMigration.php
+++ b/app/Classes/LegacySettingsMigration.php
@@ -9,15 +9,20 @@
 
 abstract class LegacySettingsMigration extends SettingsMigration
 {
-    public function getNewValue(string $name)
+    public function getNewValue(string $name, string $group)
     {
-        $new_value = DB::table('settings')->where([['group', '=', 'general'], ['name', '=', $name]])->get(['payload'])->first();
+        $new_value = DB::table('settings')->where([['group', '=', $group], ['name', '=', $name]])->get(['payload'])->first();
+
+        if (is_null($new_value) || is_null($new_value->payload)) {
+            return null;
+        }
 
         // Some keys returns '""' as a value.
         if ($new_value->payload === '""') {
             return null;
         }
 
+
         // remove the quotes from the string
         if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
             return substr($new_value->payload, 1, -1);
@@ -35,7 +40,7 @@ public function getOldValue(string $key,  int|string|bool|null $default = null)
     {
         $old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
 
-        if (is_null($old_value->value)) {
+        if (is_null($old_value) || is_null($old_value->value)) {
             return $default;
         }
 
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index d291e2986..0c18a5084 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -8,8 +8,6 @@
 use App\Models\Pterodactyl\Node;
 use App\Models\Product;
 use App\Models\Server;
-use App\Models\User;
-use App\Models\Settings;
 use App\Notifications\ServerCreationError;
 use Carbon\Carbon;
 use App\Settings\UserSettings;
@@ -18,7 +16,6 @@
 use App\Classes\PterodactylClient;
 use App\Settings\GeneralSettings;
 use Exception;
-use GuzzleHttp\Promise\Create;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Client\Response;
 use Illuminate\Http\RedirectResponse;
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index fb6e8f9ce..5e1f05d05 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -2,7 +2,6 @@
 
 namespace App\Providers;
 
-use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
 use App\Models\UsefulLink;
 use App\Settings\GeneralSettings;
 use App\Settings\MailSettings;
@@ -89,20 +88,23 @@ public function boot()
             Log::error("Couldnt find useful_links. Probably the installation is not completet. " . $e);
         }
 
-        $generalSettings = $this->app->make(GeneralSettings::class);
-        if (!file_exists(base_path('themes') . "/" . $generalSettings->theme)) {
-            $generalSettings->theme = "default";
-        }
-
-        if ($generalSettings->theme && $generalSettings->theme !== config('theme.active')) {
-            Theme::set($generalSettings->theme, "default");
-        } else {
-            Theme::set("default", "default");
-        }
 
+        try {
+            $generalSettings = $this->app->make(GeneralSettings::class);
+            if (!file_exists(base_path('themes') . "/" . $generalSettings->theme)) {
+                $generalSettings->theme = "default";
+            }
 
-        $settings = $this->app->make(MailSettings::class);
-        $settings->setConfig();
+            if ($generalSettings->theme && $generalSettings->theme !== config('theme.active')) {
+                Theme::set($generalSettings->theme, "default");
+            } else {
+                Theme::set("default", "default");
+            }
 
+            $settings = $this->app->make(MailSettings::class);
+            $settings->setConfig();
+        } catch (Exception $e) {
+            Log::error("Couldnt load Settings. Probably the installation is not completet. " . $e);
+        }
     }
 }
diff --git a/config/settings.php b/config/settings.php
index 6b6ae4b72..e9a3a4b10 100644
--- a/config/settings.php
+++ b/config/settings.php
@@ -32,7 +32,7 @@
         UserSettings::class,
         WebsiteSettings::class,
         TicketSettings::class,
-				CouponSettings::class,
+        CouponSettings::class,
     ],
 
     /*
diff --git a/routes/web.php b/routes/web.php
index a6a2ab3cc..42d2edf37 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -77,11 +77,13 @@
     Route::patch('/servers/cancel/{server}', [ServerController::class, 'cancel'])->name('servers.cancel');
     Route::resource('servers', ServerController::class);
 
-    if (config('app.key')) {
+    try {
         $serverSettings = app(App\Settings\ServerSettings::class);
-        if ($serverSettings->enable_upgrade) {
-            Route::post('servers/{server}/upgrade', [ServerController::class, 'upgrade'])->name('servers.upgrade');
+        if ($serverSettings->creation_enabled) {
+            Route::resource('servers', ServerController::class);
         }
+    } catch (Exception $e) {
+        // Do nothing if the settings are not available.
     }
 
     Route::post('profile/selfdestruct', [ProfileController::class, 'selfDestroyUser'])->name('profile.selfDestroyUser');

From 38cf81d92d4d418599514d13bdf4f0f3bd290ed1 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Fri, 12 Apr 2024 21:01:49 +0200
Subject: [PATCH 259/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Use=20groups=20on?=
 =?UTF-8?q?=20getNewValue=20method?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...08_094402_update_user_credits_datatype.php |  2 +-
 ...3_02_01_164731_create_general_settings.php | 43 ++++++++-------
 ..._01_181334_create_pterodactyl_settings.php | 20 ++++---
 ...2023_02_01_181453_create_mail_settings.php | 36 +++++++------
 ...2023_02_01_181925_create_user_settings.php | 52 ++++++++++---------
 ...23_02_01_181950_create_server_settings.php | 16 +++---
 ...3_02_01_182021_create_invoice_settings.php | 36 +++++++------
 ...3_02_01_182043_create_discord_settings.php | 28 +++++-----
 ...23_02_01_182108_create_locale_settings.php | 24 +++++----
 ..._02_01_182135_create_referral_settings.php | 28 +++++-----
 ...3_02_01_182158_create_website_settings.php | 40 +++++++-------
 ...23_02_04_181156_create_ticket_settings.php | 12 +++--
 ..._delete_notify_add_ticket_information.php} |  6 +++
 13 files changed, 196 insertions(+), 147 deletions(-)
 rename database/settings/{2023_05_07_195343_ticket_information.php => 2023_05_07_195343_delete_notify_add_ticket_information.php} (70%)

diff --git a/database/migrations/2023_05_08_094402_update_user_credits_datatype.php b/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
index 292102ccc..db0acb2f1 100644
--- a/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
+++ b/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
@@ -26,7 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->decimal('price', ['11', '2'])->change();
+            $table->decimal('credits', ['11', '2'])->change();
         });
     }
 }
diff --git a/database/settings/2023_02_01_164731_create_general_settings.php b/database/settings/2023_02_01_164731_create_general_settings.php
index 5e7360dcf..06c876c5b 100644
--- a/database/settings/2023_02_01_164731_create_general_settings.php
+++ b/database/settings/2023_02_01_164731_create_general_settings.php
@@ -27,70 +27,73 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME',
-                'value' => $this->getNewValue('credits_display_name'),
+                'value' => $this->getNewValue('credits_display_name', 'general'),
                 'type' => 'string',
                 'description' => 'The name of the credits on the panel.'
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:ALERT_ENABLED',
-                'value' => $this->getNewValue('alert_enabled'),
+                'value' => $this->getNewValue('alert_enabled', 'general'),
                 'type' => 'boolean',
                 'description' => 'Enable the alert at the top of the panel.'
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:ALERT_TYPE',
-                'value' => $this->getNewValue('alert_type'),
+                'value' => $this->getNewValue('alert_type', 'general'),
                 'type' => 'string',
                 'description' => 'The type of alert to display.'
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:ALERT_MESSAGE',
-                'value' => $this->getNewValue('alert_message'),
+                'value' => $this->getNewValue('alert_message', 'general'),
                 'type' => 'text',
                 'description' => 'The message to display in the alert.'
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:THEME',
-                'value' => $this->getNewValue('theme'),
+                'value' => $this->getNewValue('theme', 'general'),
                 'type' => 'string',
                 'description' => 'The theme to use for the panel.'
 
             ],
             [
                 'key' => 'SETTINGS::RECAPTCHA:SITE_KEY',
-                'value' => $this->getNewValue('recaptcha_site_key'),
+                'value' => $this->getNewValue('recaptcha_site_key', 'general'),
                 'type' => 'string',
                 'description' => 'The site key for reCAPTCHA.'
             ],
             [
                 'key' => 'SETTINGS::RECAPTCHA:SECRET_KEY',
-                'value' => $this->getNewValue('recaptcha_secret_key'),
+                'value' => $this->getNewValue('recaptcha_secret_key', 'general'),
                 'type' => 'string',
                 'description' => 'The secret key for reCAPTCHA.'
             ],
             [
                 'key' => 'SETTINGS::RECAPTCHA:ENABLED',
-                'value' => $this->getNewValue('recaptcha_enabled'),
+                'value' => $this->getNewValue('recaptcha_enabled', 'general'),
                 'type' => 'boolean',
                 'description' => 'Enable reCAPTCHA on the panel.'
             ],
             [
                 'key' => 'SETTINGS::MISC:PHPMYADMIN:URL',
-                'value' => $this->getNewValue('phpmyadmin_url'),
+                'value' => $this->getNewValue('phpmyadmin_url', 'general'),
                 'type' => 'string',
                 'description' => 'The URL to your phpMyAdmin installation.'
             ],
         ]);
-
-        $this->migrator->delete('general.store_enabled');
-        $this->migrator->delete('general.credits_display_name');
-        $this->migrator->delete('general.recaptcha_site_key');
-        $this->migrator->delete('general.recaptcha_secret_key');
-        $this->migrator->delete('general.recaptcha_enabled');
-        $this->migrator->delete('general.phpmyadmin_url');
-        $this->migrator->delete('general.alert_enabled');
-        $this->migrator->delete('general.alert_type');
-        $this->migrator->delete('general.alert_message');
-        $this->migrator->delete('general.theme');
+        try {
+            $this->migrator->delete('general.store_enabled');
+            $this->migrator->delete('general.credits_display_name');
+            $this->migrator->delete('general.recaptcha_site_key');
+            $this->migrator->delete('general.recaptcha_secret_key');
+            $this->migrator->delete('general.recaptcha_enabled');
+            $this->migrator->delete('general.phpmyadmin_url');
+            $this->migrator->delete('general.alert_enabled');
+            $this->migrator->delete('general.alert_type');
+            $this->migrator->delete('general.alert_message');
+            $this->migrator->delete('general.theme');
+        } catch (Exception $e) {
+            // Do nothing
+        }
     }
 }
diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index d8f65248a..1bf0c7c08 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -24,33 +24,37 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN',
-                'value' => $this->getNewValue('admin_token'),
+                'value' => $this->getNewValue('admin_token', 'pterodactyl'),
                 'type' => 'string',
                 'description' => 'The admin token for the Pterodactyl panel.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN',
-                'value' => $this->getNewValue('user_token'),
+                'value' => $this->getNewValue('user_token', 'pterodactyl'),
                 'type' => 'string',
                 'description' => 'The user token for the Pterodactyl panel.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:PTERODACTYL:URL',
-                'value' => $this->getNewValue('panel_url'),
+                'value' => $this->getNewValue('panel_url', 'pterodactyl'),
                 'type' => 'string',
                 'description' => 'The URL for the Pterodactyl panel.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT',
-                'value' => $this->getNewValue('per_page_limit'),
+                'value' => $this->getNewValue('per_page_limit', 'pterodactyl'),
                 'type' => 'integer',
                 'description' => 'The number of servers to show per page.',
             ],
         ]);
 
-        $this->migrator->delete('pterodactyl.admin_token');
-        $this->migrator->delete('pterodactyl.user_token');
-        $this->migrator->delete('pterodactyl.panel_url');
-        $this->migrator->delete('pterodactyl.per_page_limit');
+        try {
+            $this->migrator->delete('pterodactyl.admin_token');
+            $this->migrator->delete('pterodactyl.user_token');
+            $this->migrator->delete('pterodactyl.panel_url');
+            $this->migrator->delete('pterodactyl.per_page_limit');
+        } catch (Exception $e) {
+            echo 'Caught exception: ',  $e->getMessage(), "\n";
+        }
     }
 }
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index 42ab0f4b2..b7d2c0d38 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -25,62 +25,66 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::MAIL:HOST',
-                'value' => $this->getNewValue('mail_host'),
+                'value' => $this->getNewValue('mail_host', 'mail'),
                 'type' => 'string',
                 'description' => 'The host of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:PORT',
-                'value' => $this->getNewValue('mail_port'),
+                'value' => $this->getNewValue('mail_port', 'mail'),
                 'type' => 'integer',
                 'description' => 'The port of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:USERNAME',
-                'value' => $this->getNewValue('mail_username'),
+                'value' => $this->getNewValue('mail_username', 'mail'),
                 'type' => 'string',
                 'description' => 'The username of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:PASSWORD',
-                'value' => $this->getNewValue('mail_password'),
+                'value' => $this->getNewValue('mail_password', 'mail'),
                 'type' => 'string',
                 'description' => 'The password of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:ENCRYPTION',
-                'value' => $this->getNewValue('mail_encryption'),
+                'value' => $this->getNewValue('mail_encryption', 'mail'),
                 'type' => 'string',
                 'description' => 'The encryption of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:FROM_ADDRESS',
-                'value' => $this->getNewValue('mail_from_address'),
+                'value' => $this->getNewValue('mail_from_address', 'mail'),
                 'type' => 'string',
                 'description' => 'The from address of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:FROM_NAME',
-                'value' => $this->getNewValue('mail_from_name'),
+                'value' => $this->getNewValue('mail_from_name', 'mail'),
                 'type' => 'string',
                 'description' => 'The from name of the mail server.',
             ],
             [
                 'key' => 'SETTINGS::MAIL:MAILER',
-                'value' => $this->getNewValue('mail_mailer'),
+                'value' => $this->getNewValue('mail_mailer', 'mail'),
                 'type' => 'string',
                 'description' => 'The mailer of the mail server.',
             ],
 
         ]);
 
-        $this->migrator->delete('mail.mail_host');
-        $this->migrator->delete('mail.mail_port');
-        $this->migrator->delete('mail.mail_username');
-        $this->migrator->delete('mail.mail_password');
-        $this->migrator->delete('mail.mail_encryption');
-        $this->migrator->delete('mail.mail_from_address');
-        $this->migrator->delete('mail.mail_from_name');
-        $this->migrator->delete('mail.mail_mailer');
+        try {
+            $this->migrator->delete('mail.mail_host');
+            $this->migrator->delete('mail.mail_port');
+            $this->migrator->delete('mail.mail_username');
+            $this->migrator->delete('mail.mail_password');
+            $this->migrator->delete('mail.mail_encryption');
+            $this->migrator->delete('mail.mail_from_address');
+            $this->migrator->delete('mail.mail_from_name');
+            $this->migrator->delete('mail.mail_mailer');
+        } catch (Exception $e) {
+            //
+        }
     }
 }
diff --git a/database/settings/2023_02_01_181925_create_user_settings.php b/database/settings/2023_02_01_181925_create_user_settings.php
index 8c9e088bf..683c998b0 100644
--- a/database/settings/2023_02_01_181925_create_user_settings.php
+++ b/database/settings/2023_02_01_181925_create_user_settings.php
@@ -29,92 +29,96 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD',
-                'value' => $this->getNewValue('credits_reward_after_verify_discord'),
+                'value' => $this->getNewValue('credits_reward_after_verify_discord', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of credits that the user will receive after verifying their Discord account.',
             ],
             [
                 'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL',
-                'value' => $this->getNewValue('credits_reward_after_verify_email'),
+                'value' => $this->getNewValue('credits_reward_after_verify_email', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of credits that the user will receive after verifying their email.',
 
             ],
             [
                 'key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION',
-                'value' => $this->getNewValue('force_discord_verification'),
+                'value' => $this->getNewValue('force_discord_verification', 'user'),
                 'type' => 'boolean',
                 'description' => 'If the user must verify their Discord account to use the panel.',
             ],
             [
                 'key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION',
-                'value' => $this->getNewValue('force_email_verification'),
+                'value' => $this->getNewValue('force_email_verification', 'user'),
                 'type' => 'boolean',
                 'description' => 'If the user must verify their email to use the panel.',
 
             ],
             [
                 'key' => 'SETTINGS::USER:INITIAL_CREDITS',
-                'value' => $this->getNewValue('initial_credits'),
+                'value' => $this->getNewValue('initial_credits', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of credits that the user will receive when they register.',
             ],
             [
                 'key' => 'SETTINGS::USER:INITIAL_SERVER_LIMIT',
-                'value' => $this->getNewValue('initial_server_limit'),
+                'value' => $this->getNewValue('initial_server_limit', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of servers that the user will be able to create when they register.',
             ],
             [
                 'key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
-                'value' => $this->getNewValue('min_credits_to_make_server'),
+                'value' => $this->getNewValue('min_credits_to_make_server', 'user'),
                 'type' => 'integer',
                 'description' => 'The minimum amount of credits that the user must have to create a server.',
             ],
             [
                 'key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE',
-                'value' => $this->getNewValue('server_limit_after_irl_purchase'),
+                'value' => $this->getNewValue('server_limit_after_irl_purchase', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of servers that the user will be able to create after making a real purchase.',
             ],
             [
                 'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
-                'value' => $this->getNewValue('server_limit_after_verify_discord'),
+                'value' => $this->getNewValue('server_limit_after_verify_discord', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of servers that the user will be able to create after verifying their Discord account.',
 
             ],
             [
                 'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
-                'value' => $this->getNewValue('server_limit_after_verify_email'),
+                'value' => $this->getNewValue('server_limit_after_verify_email', 'user'),
                 'type' => 'integer',
                 'description' => 'The amount of servers that the user will be able to create after verifying their email.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK',
-                'value' => $this->getNewValue('register_ip_check'),
+                'value' => $this->getNewValue('register_ip_check', 'user'),
                 'type' => 'boolean',
                 'description' => 'If the user must verify their IP address to register.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:CREATION_OF_NEW_USERS',
-                'value' => $this->getNewValue('creation_enabled'),
+                'value' => $this->getNewValue('creation_enabled', 'user'),
                 'type' => 'boolean',
                 'description' => 'If the user can register.',
             ],
         ]);
 
-        $this->migrator->delete('user.credits_reward_after_verify_discord');
-        $this->migrator->delete('user.credits_reward_after_verify_email');
-        $this->migrator->delete('user.force_discord_verification');
-        $this->migrator->delete('user.force_email_verification');
-        $this->migrator->delete('user.initial_credits');
-        $this->migrator->delete('user.initial_server_limit');
-        $this->migrator->delete('user.min_credits_to_make_server');
-        $this->migrator->delete('user.server_limit_after_irl_purchase');
-        $this->migrator->delete('user.server_limit_after_verify_discord');
-        $this->migrator->delete('user.server_limit_after_verify_email');
-        $this->migrator->delete('user.register_ip_check');
-        $this->migrator->delete('user.creation_enabled');
+        try {
+            $this->migrator->delete('user.credits_reward_after_verify_discord');
+            $this->migrator->delete('user.credits_reward_after_verify_email');
+            $this->migrator->delete('user.force_discord_verification');
+            $this->migrator->delete('user.force_email_verification');
+            $this->migrator->delete('user.initial_credits');
+            $this->migrator->delete('user.initial_server_limit');
+            $this->migrator->delete('user.min_credits_to_make_server');
+            $this->migrator->delete('user.server_limit_after_irl_purchase');
+            $this->migrator->delete('user.server_limit_after_verify_discord');
+            $this->migrator->delete('user.server_limit_after_verify_email');
+            $this->migrator->delete('user.register_ip_check');
+            $this->migrator->delete('user.creation_enabled');
+        } catch (Exception $e) {
+            // Do nothing
+        }
     }
 }
diff --git a/database/settings/2023_02_01_181950_create_server_settings.php b/database/settings/2023_02_01_181950_create_server_settings.php
index de25c94f9..bd63d8e71 100644
--- a/database/settings/2023_02_01_181950_create_server_settings.php
+++ b/database/settings/2023_02_01_181950_create_server_settings.php
@@ -20,26 +20,30 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT',
-                'value' => $this->getNewValue('allocation_limit'),
+                'value' => $this->getNewValue('allocation_limit', 'server'),
                 'type' => 'integer',
                 'description' => 'The number of servers to show per page.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS',
-                'value' => $this->getNewValue('creation_enabled'),
+                'value' => $this->getNewValue('creation_enabled', 'server'),
                 'type' => 'boolean',
                 'description' => 'Whether or not users can create new servers.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:ENABLE_UPGRADE',
-                'value' => $this->getNewValue('enable_upgrade'),
+                'value' => $this->getNewValue('enable_upgrade', 'server'),
                 'type' => 'boolean',
                 'description' => 'Whether or not users can upgrade their servers.',
             ],
         ]);
 
-        $this->migrator->delete('server.allocation_limit');
-        $this->migrator->delete('server.creation_enabled');
-        $this->migrator->delete('server.enable_upgrade');
+        try {
+            $this->migrator->delete('server.allocation_limit');
+            $this->migrator->delete('server.creation_enabled');
+            $this->migrator->delete('server.enable_upgrade');
+        } catch (Exception $e) {
+            // Do nothing
+        }
     }
 }
diff --git a/database/settings/2023_02_01_182021_create_invoice_settings.php b/database/settings/2023_02_01_182021_create_invoice_settings.php
index effc67d7e..d3ac8f637 100644
--- a/database/settings/2023_02_01_182021_create_invoice_settings.php
+++ b/database/settings/2023_02_01_182021_create_invoice_settings.php
@@ -25,61 +25,65 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::INVOICE:COMPANY_ADDRESS',
-                'value' => $this->getNewValue('company_address'),
+                'value' => $this->getNewValue('company_address', 'invoice'),
                 'type' => 'string',
                 'description' => 'The address of the company.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:COMPANY_MAIL',
-                'value' => $this->getNewValue('company_mail'),
+                'value' => $this->getNewValue('company_mail', 'invoice'),
                 'type' => 'string',
                 'description' => 'The email address of the company.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:COMPANY_NAME',
-                'value' => $this->getNewValue('company_name'),
+                'value' => $this->getNewValue('company_name', 'invoice'),
                 'type' => 'string',
                 'description' => 'The name of the company.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:COMPANY_PHONE',
-                'value' => $this->getNewValue('company_phone'),
+                'value' => $this->getNewValue('company_phone', 'invoice'),
                 'type' => 'string',
                 'description' => 'The phone number of the company.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:COMPANY_VAT',
-                'value' => $this->getNewValue('company_vat'),
+                'value' => $this->getNewValue('company_vat', 'invoice'),
                 'type' => 'string',
                 'description' => 'The VAT number of the company.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:COMPANY_WEBSITE',
-                'value' => $this->getNewValue('company_website'),
+                'value' => $this->getNewValue('company_website', 'invoice'),
                 'type' => 'string',
                 'description' => 'The website of the company.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:ENABLED',
-                'value' => $this->getNewValue('enabled'),
+                'value' => $this->getNewValue('enabled', 'invoice'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the invoice system.',
             ],
             [
                 'key' => 'SETTINGS::INVOICE:PREFIX',
-                'value' => $this->getNewValue('prefix'),
+                'value' => $this->getNewValue('prefix', 'invoice'),
                 'type' => 'string',
                 'description' => 'The prefix of the invoice.',
             ],
         ]);
 
-        $this->migrator->delete('invoice.company_address');
-        $this->migrator->delete('invoice.company_mail');
-        $this->migrator->delete('invoice.company_name');
-        $this->migrator->delete('invoice.company_phone');
-        $this->migrator->delete('invoice.company_vat');
-        $this->migrator->delete('invoice.company_website');
-        $this->migrator->delete('invoice.enabled');
-        $this->migrator->delete('invoice.prefix');
+        try {
+            $this->migrator->delete('invoice.company_address');
+            $this->migrator->delete('invoice.company_mail');
+            $this->migrator->delete('invoice.company_name');
+            $this->migrator->delete('invoice.company_phone');
+            $this->migrator->delete('invoice.company_vat');
+            $this->migrator->delete('invoice.company_website');
+            $this->migrator->delete('invoice.enabled');
+            $this->migrator->delete('invoice.prefix');
+        } catch (Exception $e) {
+            // Do nothing
+        }
     }
 }
diff --git a/database/settings/2023_02_01_182043_create_discord_settings.php b/database/settings/2023_02_01_182043_create_discord_settings.php
index 21ccc5b63..c8216c495 100644
--- a/database/settings/2023_02_01_182043_create_discord_settings.php
+++ b/database/settings/2023_02_01_182043_create_discord_settings.php
@@ -23,48 +23,52 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::DISCORD:BOT_TOKEN',
-                'value' => $this->getNewValue('bot_token'),
+                'value' => $this->getNewValue('bot_token', 'discord'),
                 'type' => 'string',
                 'description' => 'The bot token for the Discord bot.',
             ],
             [
                 'key' => 'SETTINGS::DISCORD:CLIENT_ID',
-                'value' => $this->getNewValue('client_id'),
+                'value' => $this->getNewValue('client_id', 'discord'),
                 'type' => 'string',
                 'description' => 'The client ID for the Discord bot.',
 
             ],
             [
                 'key' => 'SETTINGS::DISCORD:CLIENT_SECRET',
-                'value' => $this->getNewValue('client_secret'),
+                'value' => $this->getNewValue('client_secret', 'discord'),
                 'type' => 'string',
                 'description' => 'The client secret for the Discord bot.',
             ],
             [
                 'key' => 'SETTINGS::DISCORD:GUILD_ID',
-                'value' => $this->getNewValue('guild_id'),
+                'value' => $this->getNewValue('guild_id', 'discord'),
                 'type' => 'string',
                 'description' => 'The guild ID for the Discord bot.',
             ],
             [
                 'key' => 'SETTINGS::DISCORD:INVITE_URL',
-                'value' => $this->getNewValue('invite_url'),
+                'value' => $this->getNewValue('invite_url', 'discord'),
                 'type' => 'string',
                 'description' => 'The invite URL for the Discord bot.',
             ],
             [
                 'key' => 'SETTINGS::DISCORD:ROLE_ID',
-                'value' => $this->getNewValue('role_id'),
+                'value' => $this->getNewValue('role_id', 'discord'),
                 'type' => 'string',
                 'description' => 'The role ID for the Discord bot.',
             ]
         ]);
 
-        $this->migrator->delete('discord.bot_token');
-        $this->migrator->delete('discord.client_id');
-        $this->migrator->delete('discord.client_secret');
-        $this->migrator->delete('discord.guild_id');
-        $this->migrator->delete('discord.invite_url');
-        $this->migrator->delete('discord.role_id');
+        try {
+            $this->migrator->delete('discord.bot_token');
+            $this->migrator->delete('discord.client_id');
+            $this->migrator->delete('discord.client_secret');
+            $this->migrator->delete('discord.guild_id');
+            $this->migrator->delete('discord.invite_url');
+            $this->migrator->delete('discord.role_id');
+        } catch (Exception $e) {
+            // Do nothing.
+        }
     }
 }
diff --git a/database/settings/2023_02_01_182108_create_locale_settings.php b/database/settings/2023_02_01_182108_create_locale_settings.php
index 13dbde9dd..86f3d6e42 100644
--- a/database/settings/2023_02_01_182108_create_locale_settings.php
+++ b/database/settings/2023_02_01_182108_create_locale_settings.php
@@ -22,40 +22,44 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::LOCALE:AVAILABLE',
-                'value' => $this->getNewValue('available'),
+                'value' => $this->getNewValue('available', 'locale'),
                 'type' => 'string',
                 'description' => 'The available locales.',
             ],
             [
                 'key' => 'SETTINGS::LOCALE:CLIENTS_CAN_CHANGE',
-                'value' => $this->getNewValue('clients_can_change'),
+                'value' => $this->getNewValue('clients_can_change', 'locale'),
                 'type' => 'boolean',
                 'description' => 'If clients can change their locale.',
             ],
             [
                 'key' => 'SETTINGS::LOCALE:DATATABLES',
-                'value' => $this->getNewValue('datatables'),
+                'value' => $this->getNewValue('datatables', 'locale'),
                 'type' => 'string',
                 'description' => 'The locale for datatables.',
             ],
             [
                 'key' => 'SETTINGS::LOCALE:DEFAULT',
-                'value' => $this->getNewValue('default'),
+                'value' => $this->getNewValue('default', 'locale'),
                 'type' => 'string',
                 'description' => 'The default locale.',
             ],
             [
                 'key' => 'SETTINGS::LOCALE:DYNAMIC',
-                'value' => $this->getNewValue('dynamic'),
+                'value' => $this->getNewValue('dynamic', 'locale'),
                 'type' => 'boolean',
                 'description' => 'If the locale should be dynamic.',
             ],
         ]);
 
-        $this->migrator->delete('locale.available');
-        $this->migrator->delete('locale.clients_can_change');
-        $this->migrator->delete('locale.datatables');
-        $this->migrator->delete('locale.default');
-        $this->migrator->delete('locale.dynamic');
+        try {
+            $this->migrator->delete('locale.available');
+            $this->migrator->delete('locale.clients_can_change');
+            $this->migrator->delete('locale.datatables');
+            $this->migrator->delete('locale.default');
+            $this->migrator->delete('locale.dynamic');
+        } catch (Exception $e) {
+            // Do nothing
+        }
     }
 }
diff --git a/database/settings/2023_02_01_182135_create_referral_settings.php b/database/settings/2023_02_01_182135_create_referral_settings.php
index 839f0e28b..ed7ff3fd4 100644
--- a/database/settings/2023_02_01_182135_create_referral_settings.php
+++ b/database/settings/2023_02_01_182135_create_referral_settings.php
@@ -22,47 +22,51 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::REFERRAL::ALLOWED',
-                'value' => $this->getNewValue('allowed'),
+                'value' => $this->getNewValue('allowed', 'referral'),
                 'type' => 'string',
                 'description' => 'The allowed referral types.',
             ],
             [
                 'key' => 'SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION',
-                'value' => $this->getNewValue('always_give_commission'),
+                'value' => $this->getNewValue('always_give_commission', 'referral'),
                 'type' => 'boolean',
                 'description' => 'Whether to always give commission to the referrer.',
             ],
             [
                 'key' => 'SETTINGS::REFERRAL::ENABLED',
-                'value' => $this->getNewValue('enabled'),
+                'value' => $this->getNewValue('enabled', 'referral'),
                 'type' => 'boolean',
                 'description' => 'Whether to enable the referral system.',
             ],
             [
                 'key' => 'SETTINGS::REFERRAL::REWARD',
-                'value' => $this->getNewValue('reward'),
+                'value' => $this->getNewValue('reward', 'referral'),
                 'type' => 'integer',
                 'description' => 'The reward for the referral.',
             ],
             [
                 'key' => 'SETTINGS::REFERRAL:MODE',
-                'value' => $this->getNewValue('mode'),
+                'value' => $this->getNewValue('mode', 'referral'),
                 'type' => 'string',
                 'description' => 'The referral mode.',
             ],
             [
                 'key' => 'SETTINGS::REFERRAL:PERCENTAGE',
-                'value' => $this->getNewValue('percentage'),
+                'value' => $this->getNewValue('percentage', 'referral'),
                 'type' => 'integer',
                 'description' => 'The referral percentage.',
             ],
         ]);
 
-        $this->migrator->delete('referral.allowed');
-        $this->migrator->delete('referral.always_give_commission');
-        $this->migrator->delete('referral.enabled');
-        $this->migrator->delete('referral.reward');
-        $this->migrator->delete('referral.mode');
-        $this->migrator->delete('referral.percentage');
+        try {
+            $this->migrator->delete('referral.allowed');
+            $this->migrator->delete('referral.always_give_commission');
+            $this->migrator->delete('referral.enabled');
+            $this->migrator->delete('referral.reward');
+            $this->migrator->delete('referral.mode');
+            $this->migrator->delete('referral.percentage');
+        } catch (Exception $e) {
+            //
+        }
     }
 }
diff --git a/database/settings/2023_02_01_182158_create_website_settings.php b/database/settings/2023_02_01_182158_create_website_settings.php
index 2bbdd5b57..eb8f3295d 100644
--- a/database/settings/2023_02_01_182158_create_website_settings.php
+++ b/database/settings/2023_02_01_182158_create_website_settings.php
@@ -33,68 +33,72 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::SYSTEM:MOTD_ENABLED',
-                'value' => $this->getNewValue('motd_enabled'),
+                'value' => $this->getNewValue('motd_enabled', 'website'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the MOTD.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:MOTD_MESSAGE',
-                'value' => $this->getNewValue('motd_message'),
+                'value' => $this->getNewValue('motd_message', 'website'),
                 'type' => 'text',
                 'description' => 'The message that will be displayed in the MOTD.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:SHOW_IMPRINT',
-                'value' => $this->getNewValue('show_imprint'),
+                'value' => $this->getNewValue('show_imprint', 'website'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the imprint.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:SHOW_PRIVACY',
-                'value' => $this->getNewValue('show_privacy'),
+                'value' => $this->getNewValue('show_privacy', 'website'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the privacy policy.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:SHOW_TOS',
-                'value' => $this->getNewValue('show_tos'),
+                'value' => $this->getNewValue('show_tos', 'website'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the terms of service.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:USEFULLINKS_ENABLED',
-                'value' => $this->getNewValue('useful_links_enabled'),
+                'value' => $this->getNewValue('useful_links_enabled', 'website'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the useful links.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:SEO_TITLE',
-                'value' => $this->getNewValue('seo_title'),
+                'value' => $this->getNewValue('seo_title', 'website'),
                 'type' => 'string',
                 'description' => 'The title of the website.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:SEO_DESCRIPTION',
-                'value' => $this->getNewValue('seo_description'),
+                'value' => $this->getNewValue('seo_description', 'website'),
                 'type' => 'string',
                 'description' => 'The description of the website.',
             ],
             [
                 'key' => 'SETTINGS::SYSTEM:ENABLE_LOGIN_LOGO',
-                'value' => $this->getNewValue('enable_login_logo'),
+                'value' => $this->getNewValue('enable_login_logo', 'website'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the login logo.',
             ]
         ]);
 
-        $this->migrator->delete('website.motd_enabled');
-        $this->migrator->delete('website.motd_message');
-        $this->migrator->delete('website.show_imprint');
-        $this->migrator->delete('website.show_privacy');
-        $this->migrator->delete('website.show_tos');
-        $this->migrator->delete('website.useful_links_enabled');
-        $this->migrator->delete('website.seo_title');
-        $this->migrator->delete('website.seo_description');
-        $this->migrator->delete('website.enable_login_logo');
+        try {
+            $this->migrator->delete('website.motd_enabled');
+            $this->migrator->delete('website.motd_message');
+            $this->migrator->delete('website.show_imprint');
+            $this->migrator->delete('website.show_privacy');
+            $this->migrator->delete('website.show_tos');
+            $this->migrator->delete('website.useful_links_enabled');
+            $this->migrator->delete('website.seo_title');
+            $this->migrator->delete('website.seo_description');
+            $this->migrator->delete('website.enable_login_logo');
+        } catch (Exception $e) {
+            // Do nothing
+        }
     }
 }
diff --git a/database/settings/2023_02_04_181156_create_ticket_settings.php b/database/settings/2023_02_04_181156_create_ticket_settings.php
index 41eefe737..b4cfd8f2f 100644
--- a/database/settings/2023_02_04_181156_create_ticket_settings.php
+++ b/database/settings/2023_02_04_181156_create_ticket_settings.php
@@ -19,19 +19,23 @@ public function down(): void
         DB::table('settings_old')->insert([
             [
                 'key' => 'SETTINGS::TICKET:NOTIFY',
-                'value' => $this->getNewValue('notify'),
+                'value' => $this->getNewValue('notify', 'ticket'),
                 'type' => 'string',
                 'description' => 'The notification type for tickets.',
             ],
             [
                 'key' => 'SETTINGS::TICKET:ENABLED',
-                'value' => $this->getNewValue('enabled'),
+                'value' => $this->getNewValue('enabled', 'ticket'),
                 'type' => 'boolean',
                 'description' => 'Enable or disable the ticket system.',
             ]
         ]);
 
-        $this->migrator->delete('ticket.enabled');
-        $this->migrator->delete('ticket.notify');
+        try {
+            $this->migrator->delete('ticket.enabled');
+            $this->migrator->delete('ticket.notify');
+        } catch (Exception $e) {
+            // Do nothing.
+        }
     }
 }
diff --git a/database/settings/2023_05_07_195343_ticket_information.php b/database/settings/2023_05_07_195343_delete_notify_add_ticket_information.php
similarity index 70%
rename from database/settings/2023_05_07_195343_ticket_information.php
rename to database/settings/2023_05_07_195343_delete_notify_add_ticket_information.php
index 21d9aa67b..68ec45556 100644
--- a/database/settings/2023_05_07_195343_ticket_information.php
+++ b/database/settings/2023_05_07_195343_delete_notify_add_ticket_information.php
@@ -9,4 +9,10 @@ public function up(): void
         $this->migrator->delete('ticket.notify');
         $this->migrator->add('ticket.information',  "Can't start your server? Need an additional port? Do you have any other questions? Let us know by opening a ticket.");
     }
+
+    public function down(): void
+    {
+        $this->migrator->add('ticket.notify', 'all');
+        $this->migrator->delete('ticket.information');
+    }
 };

From 931f08a1d7e73fdbfe5bfe2041e32d5ce0c2c6e1 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Wed, 24 Apr 2024 10:47:39 +0200
Subject: [PATCH 260/514] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Try=20Catch=20for?=
 =?UTF-8?q?=20upgrade=20routing?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/web.php | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/routes/web.php b/routes/web.php
index 42d2edf37..c575ea981 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -34,6 +34,7 @@
 use App\Http\Controllers\TranslationController;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Route;
 
 /*
@@ -80,10 +81,10 @@
     try {
         $serverSettings = app(App\Settings\ServerSettings::class);
         if ($serverSettings->creation_enabled) {
-            Route::resource('servers', ServerController::class);
+            Route::post('servers/{server}/upgrade', [ServerController::class, 'upgrade'])->name('servers.upgrade');
         }
     } catch (Exception $e) {
-        // Do nothing if the settings are not available.
+        Log::error("ServerSettings not found, skipping server upgrade route");
     }
 
     Route::post('profile/selfdestruct', [ProfileController::class, 'selfDestroyUser'])->name('profile.selfDestroyUser');

From e35bbddc40d65b581dccd584e916dffd775273b2 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Wed, 24 Apr 2024 10:54:06 +0200
Subject: [PATCH 261/514] =?UTF-8?q?chore:=20=E2=99=BB=EF=B8=8F=20Add=20enc?=
 =?UTF-8?q?rypted=20prop=20back=20in?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Settings/DiscordSettings.php                          | 2 --
 app/Settings/MailSettings.php                             | 7 ++++++-
 app/Settings/PterodactylSettings.php                      | 8 +++++++-
 .../2023_02_01_181334_create_pterodactyl_settings.php     | 2 --
 4 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/app/Settings/DiscordSettings.php b/app/Settings/DiscordSettings.php
index 4788ae7eb..79981c71b 100644
--- a/app/Settings/DiscordSettings.php
+++ b/app/Settings/DiscordSettings.php
@@ -18,8 +18,6 @@ public static function group(): string
         return 'discord';
     }
 
-
-
     /**
      * Summary of validations array
      * @return array<string, string>
diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php
index 90b5a3283..c3a9a367f 100644
--- a/app/Settings/MailSettings.php
+++ b/app/Settings/MailSettings.php
@@ -20,7 +20,12 @@ public static function group(): string
         return 'mail';
     }
 
-
+    public static function encrypted(): array
+    {
+        return [
+            'mail_password',
+        ];
+    }
 
     public function setConfig()
     {
diff --git a/app/Settings/PterodactylSettings.php b/app/Settings/PterodactylSettings.php
index 3e888b937..c96933867 100644
--- a/app/Settings/PterodactylSettings.php
+++ b/app/Settings/PterodactylSettings.php
@@ -16,7 +16,13 @@ public static function group(): string
         return 'pterodactyl';
     }
 
-
+    public static function encrypted(): array
+    {
+        return [
+            'admin_token',
+            'user_token',
+        ];
+    }
 
     /**
      * Get url with ensured ending backslash
diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index 1bf0c7c08..dbbb93b67 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -11,8 +11,6 @@ public function up(): void
 
         $this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN', '') : env('PTERODACTYL_TOKEN', ''));
         $this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN', '') : '');
-        // $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
-        // $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
         $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL', '') : env('PTERODACTYL_URL', ''));
         $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT', 200) : 200);
     }

From 4404d4a0aa75bb7f7d370ebe51da0eb752e6a51f Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Sat, 27 Apr 2024 16:24:04 -0300
Subject: [PATCH 262/514] Standardization and Organization

I standardized the functions to be the same as other payments, I removed MpPayment and only put it for the webhook to set the payment status (as done in Mollie) I changed the way Success works to the same as Mollie, I didn't understand what @ IceToast talked about Spatie, to me the way to call the Mercado Pago token appears to be correct
---
 .../MercadoPago/MercadoPagoExtension.php      | 127 ++++++------------
 .../MercadoPago/web_routes.php                |   6 +-
 2 files changed, 46 insertions(+), 87 deletions(-)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index c37d640e6..ffd545d18 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -48,9 +48,9 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                 'Authorization' => 'Bearer ' . $settings->access_token,
             ])->post($url, [
                 'back_urls' => [
-                    'success' => route('payment.MercadoPagoChecker'),
+                    'success' => route('payment.MercadoPagoSuccess'),
                     'failure' => route('payment.Cancel'),
-                    'pending' => route('payment.MercadoPagoChecker'),
+                    'pending' => route('payment.MercadoPagoSuccess'),
                 ],
                 'notification_url' => route('payment.MercadoPagoWebhook'),
                 'payer' => [
@@ -73,8 +73,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
             ]);
 
             if ($response->successful()) {
-                // Redirect link
-                Redirect::to($response->json()['init_point'])->send();
+                return $response->json()['init_point'];
             } else {
                 Log::error('MercadoPago Payment: ' . $response->body());
                 throw new Exception('Payment failed');
@@ -85,27 +84,13 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
         }
     }
 
-    static function Checker(Request $request): void
+    static function Success(Request $request): void
     {
-        // paymentID (not is preferenceID or paymentID for store)
-        $paymentId = $request->input('payment_id');
-
-        $MpPayment = self::MpPayment($paymentId, false);
-
-        switch ($MpPayment) {
-            case "paid":
-                Redirect::route('home')->with('success', 'Payment successful')->send();
-                break;
-            case "cancelled":
-                Redirect::route('home')->with('info', 'Your canceled the payment')->send();
-                break;
-            case "processing":
-                Redirect::route('home')->with('info', 'Your payment is being processed')->send();
-                break;
-            default:
-                Redirect::route('home')->with('error', 'Your payment is unknown')->send();
-                break;
-        }
+        $payment = Payment::findOrFail($request->input('payment'));
+        $payment->status = PaymentStatus::PROCESSING;
+        $payment->save();
+        Redirect::route('home')->with('success', 'Your payment is being processed')->send();
+        return;
     }
 
     static function Webhook(Request $request): JsonResponse
@@ -126,7 +111,40 @@ static function Webhook(Request $request): JsonResponse
                     // mercado pago api test
                     return response()->json(['success' => true]);
                 } else {
-                    self::MpPayment($notificationId, true);
+                    $url = "https://api.mercadopago.com/v1/payments/" . $notificationId;
+                    $settings = new MercadoPagoSettings();
+                    $response = Http::withHeaders([
+                        'Content-Type' => 'application/json',
+                        'Authorization' => 'Bearer ' . $settings->access_token,
+                    ])->get($url);
+
+                    if ($response->successful()) {
+                        $mercado = $response->json();
+                        $status = $mercado['status'];
+                        $payment = Payment::findOrFail($mercado['metadata']['crtl_panel_payment_id']);
+                        $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
+                        if ($status == "approved") {
+                            // avoids double additions, if the user enters after the webhook has already added the credits
+                            if ($payment->status !== PaymentStatus::PAID) {
+                                $user = User::findOrFail($payment->user_id);
+                                $payment->status = PaymentStatus::PAID;
+                                $payment->save();
+                                $user->notify(new ConfirmPaymentNotification($payment));
+                                event(new PaymentEvent($user, $payment, $shopProduct));
+                                event(new UserUpdateCreditsEvent($user));
+                            }
+                        } else {
+                            if ($status == "cancelled") {
+                                $user = User::findOrFail($payment->user_id);
+                                $payment->status = PaymentStatus::CANCELED;
+                            } else {
+                                $user = User::findOrFail($payment->user_id);
+                                $payment->status = PaymentStatus::PROCESSING;
+                            }
+                            $payment->save();
+                            event(new PaymentEvent($user, $payment, $shopProduct));
+                        }
+                    }
                 }
             } catch (Exception $ex) {
                 Log::error('MercadoPago Webhook(IPN) Payment: ' . $ex->getMessage());
@@ -135,63 +153,4 @@ static function Webhook(Request $request): JsonResponse
         }
         return response()->json(['success' => true]);
     }
-    /**
-     * Mercado Pago Payment checker 
-     */
-    private function MpPayment(string $paymentID, bool $notification): string
-    {
-        $MpResponse = "unknown";
-        $url = "https://api.mercadopago.com/v1/payments/" . $paymentID;
-        $settings = new MercadoPagoSettings();
-        $response = Http::withHeaders([
-            'Content-Type' => 'application/json',
-            'Authorization' => 'Bearer ' . $settings->access_token,
-        ])->get($url);
-
-        if ($response->successful()) {
-            $mercado = $response->json();
-            $status = $mercado['status'];
-            $payment = Payment::findOrFail($mercado['metadata']['crtl_panel_payment_id']);
-            $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
-
-            if ($status == "approved") {
-                // avoids double additions, if the user enters after the webhook has already added the credits
-                if ($payment->status !== PaymentStatus::PAID) {
-                    $user = User::findOrFail($payment->user_id);
-                    $payment->update([
-                        'status' => PaymentStatus::PAID,
-                        'payment_id' => $paymentID,
-                    ]);
-                    $payment->save();
-                    if ($notification) {
-                        $user->notify(new ConfirmPaymentNotification($payment));
-                    }
-                    event(new PaymentEvent($user, $payment, $shopProduct));
-                    event(new UserUpdateCreditsEvent($user));
-                }
-                $MpResponse = "paid";
-            } else {
-                if ($status == "cancelled") {
-                    $user = User::findOrFail($payment->user_id);
-                    $payment->update([
-                        'status' => PaymentStatus::CANCELED,
-                        'payment_id' => $paymentID,
-                    ]);
-                    $payment->save();
-                    event(new PaymentEvent($user, $payment, $shopProduct));
-                    $MpResponse = "cancelled";
-                } else {
-                    $user = User::findOrFail($payment->user_id);
-                    $payment->update([
-                        'status' => PaymentStatus::PROCESSING,
-                        'payment_id' => $paymentID,
-                    ]);
-                    $payment->save();
-                    event(new PaymentEvent($user, $payment, $shopProduct));
-                    $MpResponse = "processing";
-                }
-            }
-        }
-        return $MpResponse;
-    }
 }
diff --git a/app/Extensions/PaymentGateways/MercadoPago/web_routes.php b/app/Extensions/PaymentGateways/MercadoPago/web_routes.php
index a43179a64..e826d6da5 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/web_routes.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/web_routes.php
@@ -5,11 +5,11 @@
 
 Route::middleware(['web', 'auth'])->group(function () {
     Route::get(
-        'payment/MercadoPagoChecker',
+        'payment/MercadoPagoSuccess',
         function () {
-            MercadoPagoExtension::Checker(request());
+            MercadoPagoExtension::Success(request());
         }
-    )->name('payment.MercadoPagoChecker');
+    )->name('payment.MercadoPagoSuccess');
 });
 
 

From 312e53a01e1e97e0f928a0eb30e43877cc703649 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:07:42 +0200
Subject: [PATCH 263/514] UPDATE: moved the developement docker into a
 developement folder

---
 docker/{ => development}/docker-compose.yml | 12 ++++++------
 docker/{ => development}/nginx/Dockerfile   |  4 ++--
 docker/{ => development}/nginx/default.conf |  0
 docker/{ => development}/nginx/nginx.conf   |  0
 docker/{ => development}/php/Dockerfile     |  2 +-
 docker/{ => development}/php/www.conf       |  0
 6 files changed, 9 insertions(+), 9 deletions(-)
 rename docker/{ => development}/docker-compose.yml (82%)
 rename docker/{ => development}/nginx/Dockerfile (60%)
 rename docker/{ => development}/nginx/default.conf (100%)
 rename docker/{ => development}/nginx/nginx.conf (100%)
 rename docker/{ => development}/php/Dockerfile (90%)
 rename docker/{ => development}/php/www.conf (100%)

diff --git a/docker/docker-compose.yml b/docker/development/docker-compose.yml
similarity index 82%
rename from docker/docker-compose.yml
rename to docker/development/docker-compose.yml
index 56c9e24de..16c9bf94f 100644
--- a/docker/docker-compose.yml
+++ b/docker/development/docker-compose.yml
@@ -6,13 +6,13 @@ networks:
 services:
   nginx:
     build:
-      context: ../
-      dockerfile: docker/nginx/Dockerfile
+      context: ../../
+      dockerfile: docker/development/nginx/Dockerfile
     container_name: controlpanel_nginx
     ports:
       - 80:80
     volumes:
-      - "../:/var/www/html"
+      - "../../:/var/www/html"
     depends_on:
       - php
       - mysql
@@ -38,11 +38,11 @@ services:
 
   php:
     build:
-      context: ../
-      dockerfile: docker/php/Dockerfile
+      context: ../../
+      dockerfile: docker/development/php/Dockerfile
     container_name: controlpanel_php
     volumes:
-      - "../:/var/www/html"
+      - "../../:/var/www/html"
     networks:
       - laravel
 
diff --git a/docker/nginx/Dockerfile b/docker/development/nginx/Dockerfile
similarity index 60%
rename from docker/nginx/Dockerfile
rename to docker/development/nginx/Dockerfile
index 51bf97ea1..deca865f1 100644
--- a/docker/nginx/Dockerfile
+++ b/docker/development/nginx/Dockerfile
@@ -2,8 +2,8 @@ FROM nginx:stable-alpine
 
 RUN addgroup -g 1000 laravel && adduser -G laravel -g laravel -s /bin/sh -D laravel
 
-ADD ./docker/nginx/nginx.conf /etc/nginx/
-ADD ./docker/nginx/default.conf /etc/nginx/conf.d/
+ADD ./docker/development/nginx/nginx.conf /etc/nginx/
+ADD ./docker/development/nginx/default.conf /etc/nginx/conf.d/
 
 RUN mkdir -p /var/www/html
 
diff --git a/docker/nginx/default.conf b/docker/development/nginx/default.conf
similarity index 100%
rename from docker/nginx/default.conf
rename to docker/development/nginx/default.conf
diff --git a/docker/nginx/nginx.conf b/docker/development/nginx/nginx.conf
similarity index 100%
rename from docker/nginx/nginx.conf
rename to docker/development/nginx/nginx.conf
diff --git a/docker/php/Dockerfile b/docker/development/php/Dockerfile
similarity index 90%
rename from docker/php/Dockerfile
rename to docker/development/php/Dockerfile
index 4b8d91dd9..3ec761ae7 100644
--- a/docker/php/Dockerfile
+++ b/docker/development/php/Dockerfile
@@ -4,7 +4,7 @@ RUN apt-get update \
 
 RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
 
-ADD ./docker/php/www.conf /usr/local/etc/php-fpm.d/
+ADD ./docker/development/php/www.conf /usr/local/etc/php-fpm.d/
 
 RUN mkdir -p /var/www/html
 
diff --git a/docker/php/www.conf b/docker/development/php/www.conf
similarity index 100%
rename from docker/php/www.conf
rename to docker/development/php/www.conf

From 31c79cbc99223ce73700e5786a7fd6cd49fc9a12 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:07:53 +0200
Subject: [PATCH 264/514] ADD: added a standalone docker

---
 docker/standalone/Dockerfile         |  45 +++
 docker/standalone/docker-compose.yml |  18 ++
 docker/standalone/nginx/default.conf |  21 ++
 docker/standalone/nginx/nginx.conf   |  29 ++
 docker/standalone/php/www.conf       | 439 +++++++++++++++++++++++++++
 5 files changed, 552 insertions(+)
 create mode 100644 docker/standalone/Dockerfile
 create mode 100644 docker/standalone/docker-compose.yml
 create mode 100644 docker/standalone/nginx/default.conf
 create mode 100644 docker/standalone/nginx/nginx.conf
 create mode 100644 docker/standalone/php/www.conf

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
new file mode 100644
index 000000000..a0efd6ed3
--- /dev/null
+++ b/docker/standalone/Dockerfile
@@ -0,0 +1,45 @@
+FROM php:8.1-fpm
+
+# Install Nginx and other dependencies
+RUN apt-get update && apt-get install -y \
+    nginx \
+    curl \
+    libcurl4-openssl-dev \
+    libicu-dev \
+    libzip-dev \
+    && rm -rf /var/lib/apt/lists/*
+
+# Install PHP extensions
+RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip
+
+# Copy the custom PHP-FPM configuration
+ADD ./docker/standalone/php/www.conf /usr/local/etc/php-fpm.d/
+
+# Create directory for application and set ownership
+RUN mkdir -p /var/www/html && \
+    groupadd -g 1000 laravel && \
+    useradd -u 1000 -g laravel -ms /bin/bash laravel && \
+    chown laravel:laravel /var/www/html
+
+# Set the working directory
+WORKDIR /var/www/html
+
+# Copy Composer binary from Composer image
+COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
+
+# Configure Nginx
+COPY ./docker/standalone/nginx/nginx.conf /etc/nginx/nginx.conf
+COPY ./docker/standalone/nginx/default.conf /etc/nginx/conf.d/default.conf
+
+# Create directory for Nginx logs and set ownership
+RUN mkdir -p /var/log/nginx && \
+    chown -R laravel:laravel /var/log/nginx
+
+# Expose ports
+EXPOSE 80
+
+# Run composer install if composer.json is present
+RUN if [ -f composer.json ]; then composer install --no-dev --optimize-autoloader; fi
+
+# Start both PHP-FPM and Nginx
+CMD ["sh", "-c", "service nginx start && php-fpm -F"]
diff --git a/docker/standalone/docker-compose.yml b/docker/standalone/docker-compose.yml
new file mode 100644
index 000000000..a55c85d86
--- /dev/null
+++ b/docker/standalone/docker-compose.yml
@@ -0,0 +1,18 @@
+version: '3'
+
+services:
+  web:
+    build:
+      context: ../../
+      dockerfile: ./docker/standalone/Dockerfile
+    container_name: controlpanel_web
+    ports:
+      - "80:80"
+    volumes:
+      - "../../:/var/www/html:delegated"
+    environment:
+      - DB_HOST=10.0.0.16
+      - DB_PORT=3306
+      - DB_DATABASE=controlpanel
+      - DB_USERNAME=controlpaneluser
+      - DB_PASSWORD=pass
diff --git a/docker/standalone/nginx/default.conf b/docker/standalone/nginx/default.conf
new file mode 100644
index 000000000..2fe700465
--- /dev/null
+++ b/docker/standalone/nginx/default.conf
@@ -0,0 +1,21 @@
+server {
+    listen 80;
+    server_name _;
+    root /var/www/html/public;
+    index index.php index.html index.htm index.nginx-debian.html;
+
+    location / {
+        try_files $uri $uri/ /index.php?$query_string;
+    }
+
+    location ~ \.php$ {
+        include snippets/fastcgi-php.conf;
+        fastcgi_pass 127.0.0.1:9000;
+        include fastcgi_params;
+        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+    }
+
+    location ~ /\.ht {
+        deny all;
+    }
+}
diff --git a/docker/standalone/nginx/nginx.conf b/docker/standalone/nginx/nginx.conf
new file mode 100644
index 000000000..060e50253
--- /dev/null
+++ b/docker/standalone/nginx/nginx.conf
@@ -0,0 +1,29 @@
+user laravel;
+worker_processes  auto;
+
+error_log  /var/log/nginx/error.log warn;
+pid        /var/run/nginx.pid;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+    include       /etc/nginx/mime.types;
+    default_type  application/octet-stream;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    access_log  /var/log/nginx/access.log  main;
+
+    sendfile        on;
+    #tcp_nopush     on;
+
+    keepalive_timeout  65;
+
+    #gzip  on;
+
+    include /etc/nginx/conf.d/*.conf;
+}
diff --git a/docker/standalone/php/www.conf b/docker/standalone/php/www.conf
new file mode 100644
index 000000000..eb028e111
--- /dev/null
+++ b/docker/standalone/php/www.conf
@@ -0,0 +1,439 @@
+; Start a new pool named 'www'.
+; the variable $pool can be used in any directive and will be replaced by the
+; pool name ('www' here)
+[www]
+
+; Per pool prefix
+; It only applies on the following directives:
+; - 'access.log'
+; - 'slowlog'
+; - 'listen' (unixsocket)
+; - 'chroot'
+; - 'chdir'
+; - 'php_values'
+; - 'php_admin_values'
+; When not set, the global prefix (or NONE) applies instead.
+; Note: This directive can also be relative to the global prefix.
+; Default Value: none
+;prefix = /path/to/pools/$pool
+
+; Unix user/group of processes
+; Note: The user is mandatory. If the group is not set, the default user's group
+;       will be used.
+user = laravel
+group = laravel
+
+; The address on which to accept FastCGI requests.
+; Valid syntaxes are:
+;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
+;                            a specific port;
+;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
+;                            a specific port;
+;   'port'                 - to listen on a TCP socket to all addresses
+;                            (IPv6 and IPv4-mapped) on a specific port;
+;   '/path/to/unix/socket' - to listen on a unix socket.
+; Note: This value is mandatory.
+listen = 127.0.0.1:9000
+
+; Set listen(2) backlog.
+; Default Value: 511 (-1 on FreeBSD and OpenBSD)
+;listen.backlog = 511
+
+; Set permissions for unix socket, if one is used. In Linux, read/write
+; permissions must be set in order to allow connections from a web server. Many
+; BSD-derived systems allow connections regardless of permissions. The owner
+; and group can be specified either by name or by their numeric IDs.
+; Default Values: user and group are set as the running user
+;                 mode is set to 0660
+;listen.owner = www-data
+;listen.group = www-data
+;listen.mode = 0660
+; When POSIX Access Control Lists are supported you can set them using
+; these options, value is a comma separated list of user/group names.
+; When set, listen.owner and listen.group are ignored
+;listen.acl_users =
+;listen.acl_groups =
+
+; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.
+; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
+; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
+; must be separated by a comma. If this value is left blank, connections will be
+; accepted from any ip address.
+; Default Value: any
+;listen.allowed_clients = 127.0.0.1
+
+; Specify the nice(2) priority to apply to the pool processes (only if set)
+; The value can vary from -19 (highest priority) to 20 (lower priority)
+; Note: - It will only work if the FPM master process is launched as root
+;       - The pool processes will inherit the master process priority
+;         unless it specified otherwise
+; Default Value: no set
+; process.priority = -19
+
+; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user
+; or group is differrent than the master process user. It allows to create process
+; core dump and ptrace the process for the pool user.
+; Default Value: no
+; process.dumpable = yes
+
+; Choose how the process manager will control the number of child processes.
+; Possible Values:
+;   static  - a fixed number (pm.max_children) of child processes;
+;   dynamic - the number of child processes are set dynamically based on the
+;             following directives. With this process management, there will be
+;             always at least 1 children.
+;             pm.max_children      - the maximum number of children that can
+;                                    be alive at the same time.
+;             pm.start_servers     - the number of children created on startup.
+;             pm.min_spare_servers - the minimum number of children in 'idle'
+;                                    state (waiting to process). If the number
+;                                    of 'idle' processes is less than this
+;                                    number then some children will be created.
+;             pm.max_spare_servers - the maximum number of children in 'idle'
+;                                    state (waiting to process). If the number
+;                                    of 'idle' processes is greater than this
+;                                    number then some children will be killed.
+;  ondemand - no children are created at startup. Children will be forked when
+;             new requests will connect. The following parameter are used:
+;             pm.max_children           - the maximum number of children that
+;                                         can be alive at the same time.
+;             pm.process_idle_timeout   - The number of seconds after which
+;                                         an idle process will be killed.
+; Note: This value is mandatory.
+pm = dynamic
+
+; The number of child processes to be created when pm is set to 'static' and the
+; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
+; This value sets the limit on the number of simultaneous requests that will be
+; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
+; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
+; CGI. The below defaults are based on a server without much resources. Don't
+; forget to tweak pm.* to fit your needs.
+; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
+; Note: This value is mandatory.
+pm.max_children = 5
+
+; The number of child processes created on startup.
+; Note: Used only when pm is set to 'dynamic'
+; Default Value: (min_spare_servers + max_spare_servers) / 2
+pm.start_servers = 2
+
+; The desired minimum number of idle server processes.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+pm.min_spare_servers = 1
+
+; The desired maximum number of idle server processes.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+pm.max_spare_servers = 3
+
+; The number of seconds after which an idle process will be killed.
+; Note: Used only when pm is set to 'ondemand'
+; Default Value: 10s
+;pm.process_idle_timeout = 10s;
+
+; The number of requests each child process should execute before respawning.
+; This can be useful to work around memory leaks in 3rd party libraries. For
+; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
+; Default Value: 0
+;pm.max_requests = 500
+
+; The URI to view the FPM status page. If this value is not set, no URI will be
+; recognized as a status page. It shows the following informations:
+;   pool                 - the name of the pool;
+;   process manager      - static, dynamic or ondemand;
+;   start time           - the date and time FPM has started;
+;   start since          - number of seconds since FPM has started;
+;   accepted conn        - the number of request accepted by the pool;
+;   listen queue         - the number of request in the queue of pending
+;                          connections (see backlog in listen(2));
+;   max listen queue     - the maximum number of requests in the queue
+;                          of pending connections since FPM has started;
+;   listen queue len     - the size of the socket queue of pending connections;
+;   idle processes       - the number of idle processes;
+;   active processes     - the number of active processes;
+;   total processes      - the number of idle + active processes;
+;   max active processes - the maximum number of active processes since FPM
+;                          has started;
+;   max children reached - number of times, the process limit has been reached,
+;                          when pm tries to start more children (works only for
+;                          pm 'dynamic' and 'ondemand');
+; Value are updated in real time.
+; Example output:
+;   pool:                 www
+;   process manager:      static
+;   start time:           01/Jul/2011:17:53:49 +0200
+;   start since:          62636
+;   accepted conn:        190460
+;   listen queue:         0
+;   max listen queue:     1
+;   listen queue len:     42
+;   idle processes:       4
+;   active processes:     11
+;   total processes:      15
+;   max active processes: 12
+;   max children reached: 0
+;
+; By default the status page output is formatted as text/plain. Passing either
+; 'html', 'xml' or 'json' in the query string will return the corresponding
+; output syntax. Example:
+;   http://www.foo.bar/status
+;   http://www.foo.bar/status?json
+;   http://www.foo.bar/status?html
+;   http://www.foo.bar/status?xml
+;
+; By default the status page only outputs short status. Passing 'full' in the
+; query string will also return status for each pool process.
+; Example:
+;   http://www.foo.bar/status?full
+;   http://www.foo.bar/status?json&full
+;   http://www.foo.bar/status?html&full
+;   http://www.foo.bar/status?xml&full
+; The Full status returns for each process:
+;   pid                  - the PID of the process;
+;   state                - the state of the process (Idle, Running, ...);
+;   start time           - the date and time the process has started;
+;   start since          - the number of seconds since the process has started;
+;   requests             - the number of requests the process has served;
+;   request duration     - the duration in µs of the requests;
+;   request method       - the request method (GET, POST, ...);
+;   request URI          - the request URI with the query string;
+;   content length       - the content length of the request (only with POST);
+;   user                 - the user (PHP_AUTH_USER) (or '-' if not set);
+;   script               - the main script called (or '-' if not set);
+;   last request cpu     - the %cpu the last request consumed
+;                          it's always 0 if the process is not in Idle state
+;                          because CPU calculation is done when the request
+;                          processing has terminated;
+;   last request memory  - the max amount of memory the last request consumed
+;                          it's always 0 if the process is not in Idle state
+;                          because memory calculation is done when the request
+;                          processing has terminated;
+; If the process is in Idle state, then informations are related to the
+; last request the process has served. Otherwise informations are related to
+; the current request being served.
+; Example output:
+;   ************************
+;   pid:                  31330
+;   state:                Running
+;   start time:           01/Jul/2011:17:53:49 +0200
+;   start since:          63087
+;   requests:             12808
+;   request duration:     1250261
+;   request method:       GET
+;   request URI:          /test_mem.php?N=10000
+;   content length:       0
+;   user:                 -
+;   script:               /home/fat/web/docs/php/test_mem.php
+;   last request cpu:     0.00
+;   last request memory:  0
+;
+; Note: There is a real-time FPM status monitoring sample web page available
+;       It's available in: /usr/local/share/php/fpm/status.html
+;
+; Note: The value must start with a leading slash (/). The value can be
+;       anything, but it may not be a good idea to use the .php extension or it
+;       may conflict with a real PHP file.
+; Default Value: not set
+;pm.status_path = /status
+
+; The ping URI to call the monitoring page of FPM. If this value is not set, no
+; URI will be recognized as a ping page. This could be used to test from outside
+; that FPM is alive and responding, or to
+; - create a graph of FPM availability (rrd or such);
+; - remove a server from a group if it is not responding (load balancing);
+; - trigger alerts for the operating team (24/7).
+; Note: The value must start with a leading slash (/). The value can be
+;       anything, but it may not be a good idea to use the .php extension or it
+;       may conflict with a real PHP file.
+; Default Value: not set
+;ping.path = /ping
+
+; This directive may be used to customize the response of a ping request. The
+; response is formatted as text/plain with a 200 response code.
+; Default Value: pong
+;ping.response = pong
+
+; The access log file
+; Default: not set
+;access.log = log/$pool.access.log
+
+; The access log format.
+; The following syntax is allowed
+;  %%: the '%' character
+;  %C: %CPU used by the request
+;      it can accept the following format:
+;      - %{user}C for user CPU only
+;      - %{system}C for system CPU only
+;      - %{total}C  for user + system CPU (default)
+;  %d: time taken to serve the request
+;      it can accept the following format:
+;      - %{seconds}d (default)
+;      - %{miliseconds}d
+;      - %{mili}d
+;      - %{microseconds}d
+;      - %{micro}d
+;  %e: an environment variable (same as $_ENV or $_SERVER)
+;      it must be associated with embraces to specify the name of the env
+;      variable. Some exemples:
+;      - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
+;      - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
+;  %f: script filename
+;  %l: content-length of the request (for POST request only)
+;  %m: request method
+;  %M: peak of memory allocated by PHP
+;      it can accept the following format:
+;      - %{bytes}M (default)
+;      - %{kilobytes}M
+;      - %{kilo}M
+;      - %{megabytes}M
+;      - %{mega}M
+;  %n: pool name
+;  %o: output header
+;      it must be associated with embraces to specify the name of the header:
+;      - %{Content-Type}o
+;      - %{X-Powered-By}o
+;      - %{Transfert-Encoding}o
+;      - ....
+;  %p: PID of the child that serviced the request
+;  %P: PID of the parent of the child that serviced the request
+;  %q: the query string
+;  %Q: the '?' character if query string exists
+;  %r: the request URI (without the query string, see %q and %Q)
+;  %R: remote IP address
+;  %s: status (response code)
+;  %t: server time the request was received
+;      it can accept a strftime(3) format:
+;      %d/%b/%Y:%H:%M:%S %z (default)
+;      The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
+;      e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t
+;  %T: time the log has been written (the request has finished)
+;      it can accept a strftime(3) format:
+;      %d/%b/%Y:%H:%M:%S %z (default)
+;      The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
+;      e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t
+;  %u: remote user
+;
+; Default: "%R - %u %t \"%m %r\" %s"
+;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
+
+; The log file for slow requests
+; Default Value: not set
+; Note: slowlog is mandatory if request_slowlog_timeout is set
+;slowlog = log/$pool.log.slow
+
+; The timeout for serving a single request after which a PHP backtrace will be
+; dumped to the 'slowlog' file. A value of '0s' means 'off'.
+; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
+; Default Value: 0
+;request_slowlog_timeout = 0
+
+; Depth of slow log stack trace.
+; Default Value: 20
+;request_slowlog_trace_depth = 20
+
+; The timeout for serving a single request after which the worker process will
+; be killed. This option should be used when the 'max_execution_time' ini option
+; does not stop script execution for some reason. A value of '0' means 'off'.
+; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
+; Default Value: 0
+;request_terminate_timeout = 0
+
+; The timeout set by 'request_terminate_timeout' ini option is not engaged after
+; application calls 'fastcgi_finish_request' or when application has finished and
+; shutdown functions are being called (registered via register_shutdown_function).
+; This option will enable timeout limit to be applied unconditionally
+; even in such cases.
+; Default Value: no
+;request_terminate_timeout_track_finished = no
+
+; Set open file descriptor rlimit.
+; Default Value: system defined value
+;rlimit_files = 1024
+
+; Set max core size rlimit.
+; Possible Values: 'unlimited' or an integer greater or equal to 0
+; Default Value: system defined value
+;rlimit_core = 0
+
+; Chroot to this directory at the start. This value must be defined as an
+; absolute path. When this value is not set, chroot is not used.
+; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
+; of its subdirectories. If the pool prefix is not set, the global prefix
+; will be used instead.
+; Note: chrooting is a great security feature and should be used whenever
+;       possible. However, all PHP paths will be relative to the chroot
+;       (error_log, sessions.save_path, ...).
+; Default Value: not set
+;chroot =
+
+; Chdir to this directory at the start.
+; Note: relative path can be used.
+; Default Value: current directory or / when chroot
+;chdir = /var/www
+
+; Redirect worker stdout and stderr into main error log. If not set, stdout and
+; stderr will be redirected to /dev/null according to FastCGI specs.
+; Note: on highloaded environement, this can cause some delay in the page
+; process time (several ms).
+; Default Value: no
+;catch_workers_output = yes
+
+; Decorate worker output with prefix and suffix containing information about
+; the child that writes to the log and if stdout or stderr is used as well as
+; log level and time. This options is used only if catch_workers_output is yes.
+; Settings to "no" will output data as written to the stdout or stderr.
+; Default value: yes
+;decorate_workers_output = no
+
+; Clear environment in FPM workers
+; Prevents arbitrary environment variables from reaching FPM worker processes
+; by clearing the environment in workers before env vars specified in this
+; pool configuration are added.
+; Setting to "no" will make all environment variables available to PHP code
+; via getenv(), $_ENV and $_SERVER.
+; Default Value: yes
+;clear_env = no
+
+; Limits the extensions of the main script FPM will allow to parse. This can
+; prevent configuration mistakes on the web server side. You should only limit
+; FPM to .php extensions to prevent malicious users to use other extensions to
+; execute php code.
+; Note: set an empty value to allow all extensions.
+; Default Value: .php
+;security.limit_extensions = .php .php3 .php4 .php5 .php7
+
+; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
+; the current environment.
+; Default Value: clean env
+;env[HOSTNAME] = $HOSTNAME
+;env[PATH] = /usr/local/bin:/usr/bin:/bin
+;env[TMP] = /tmp
+;env[TMPDIR] = /tmp
+;env[TEMP] = /tmp
+
+; Additional php.ini defines, specific to this pool of workers. These settings
+; overwrite the values previously defined in the php.ini. The directives are the
+; same as the PHP SAPI:
+;   php_value/php_flag             - you can set classic ini defines which can
+;                                    be overwritten from PHP call 'ini_set'.
+;   php_admin_value/php_admin_flag - these directives won't be overwritten by
+;                                     PHP call 'ini_set'
+; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
+
+; Defining 'extension' will load the corresponding shared extension from
+; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
+; overwrite previously defined php.ini values, but will append the new value
+; instead.
+
+; Note: path INI options can be relative and will be expanded with the prefix
+; (pool, global or /usr/local)
+
+; Default Value: nothing is defined by default except the values in php.ini and
+;                specified at startup with the -d argument
+;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
+;php_flag[display_errors] = off
+;php_admin_value[error_log] = /var/log/fpm-php.www.log
+;php_admin_flag[log_errors] = on
+;php_admin_value[memory_limit] = 32M

From d5ffe982d8c4f0ee21b4cddbea6abd0176531963 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:28:48 +0200
Subject: [PATCH 265/514] UPDATE: moved building.md to a readme in the
 developement docker

---
 BUILDING.md => docker/README.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename BUILDING.md => docker/README.md (100%)

diff --git a/BUILDING.md b/docker/README.md
similarity index 100%
rename from BUILDING.md
rename to docker/README.md

From 75c6dfcb798089bb188493bb395359f2d734eca0 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:29:03 +0200
Subject: [PATCH 266/514] UPDATE: moved contributing.md to .github

---
 CONTRIBUTING.md => .github/CONTRIBUTING.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%)

diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to .github/CONTRIBUTING.md

From 5c32ff24912bfeac82a11d039a0b50a80482e2cc Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:29:18 +0200
Subject: [PATCH 267/514] ADD: empty code of conduct in .github

---
 .github/CODE_OF_CONDUCT.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .github/CODE_OF_CONDUCT.md

diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..e69de29bb

From bc190dceb6f62229c5018fabc07c50207c2bda16 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:41:18 +0200
Subject: [PATCH 268/514] FIX: bug and feature displaying differently

---
 .github/ISSUE_TEMPLATE/bug.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index 24b38f4fb..f9e8e9ec3 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -1,6 +1,6 @@
 name: "\U0001F41B Bug report"
 description: Create a report to help us improve
-title: "[Bug]: "
+title: "[Bug] "
 labels: ["bug"]
 body:
   - type: textarea

From 971458a01b8d5a35c66730d051c244441f035c51 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 30 Apr 2024 14:46:10 +0200
Subject: [PATCH 269/514] ADD: empty issue template

---
 .github/PULL_REQUEST_TEMPLATE.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .github/PULL_REQUEST_TEMPLATE.md

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..e69de29bb

From d10c7ac4aaabbb6c70e945a28629aa423e2425b7 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 3 May 2024 13:25:58 +0200
Subject: [PATCH 270/514] REMOVED: binary for docker compose execution that
 where not used anymore

---
 bin/rebuild.sh     | 2 --
 bin/startdocker.sh | 2 --
 bin/stopdocker.sh  | 1 -
 3 files changed, 5 deletions(-)
 delete mode 100644 bin/rebuild.sh
 delete mode 100644 bin/startdocker.sh
 delete mode 100644 bin/stopdocker.sh

diff --git a/bin/rebuild.sh b/bin/rebuild.sh
deleted file mode 100644
index 7aba0c5cc..000000000
--- a/bin/rebuild.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-docker-compose -f docker/docker-compose.yml down
-docker-compose -f docker/docker-compose.yml build --no-cache
diff --git a/bin/startdocker.sh b/bin/startdocker.sh
deleted file mode 100644
index 57a6c5154..000000000
--- a/bin/startdocker.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-docker-compose -f docker/docker-compose.yml down
-docker-compose -f docker/docker-compose.yml up -d --force-recreate --remove-orphans
diff --git a/bin/stopdocker.sh b/bin/stopdocker.sh
deleted file mode 100644
index f0bed643b..000000000
--- a/bin/stopdocker.sh
+++ /dev/null
@@ -1 +0,0 @@
-docker-compose -f docker/docker-compose.yml down

From e3403963d3509f6f639da5323e24e8e5c2a04387 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 3 May 2024 13:28:03 +0200
Subject: [PATCH 271/514] UPDATE: moved the building.md to the developement
 docker

---
 BUILDING.md => docker/development/README.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename BUILDING.md => docker/development/README.md (100%)

diff --git a/BUILDING.md b/docker/development/README.md
similarity index 100%
rename from BUILDING.md
rename to docker/development/README.md

From 96041d1eac02f85847156b50c04412adc50495c7 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 3 May 2024 13:28:15 +0200
Subject: [PATCH 272/514] ADD: empty readme for the standalone docker

---
 docker/standalone/README.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 docker/standalone/README.md

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
new file mode 100644
index 000000000..e69de29bb

From b52aeb229616e689438fe50b4df1adab4347c7aa Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Sun, 5 May 2024 18:22:28 +0200
Subject: [PATCH 273/514] UPDATE: made a working standalone docker whit a
 startup script for easy deployment and managability

---
 docker/standalone/Dockerfile         | 20 +++++++++++---------
 docker/standalone/docker-compose.yml | 13 ++++---------
 docker/standalone/scripts/startup.sh | 23 +++++++++++++++++++++++
 3 files changed, 38 insertions(+), 18 deletions(-)
 create mode 100644 docker/standalone/scripts/startup.sh

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index a0efd6ed3..aafd194ad 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -16,20 +16,19 @@ RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip
 ADD ./docker/standalone/php/www.conf /usr/local/etc/php-fpm.d/
 
 # Create directory for application and set ownership
-RUN mkdir -p /var/www/html && \
+RUN mkdir -p /var/default && \
     groupadd -g 1000 laravel && \
     useradd -u 1000 -g laravel -ms /bin/bash laravel && \
-    chown laravel:laravel /var/www/html
+    chown laravel:laravel /var/default
 
-# Set the working directory
-WORKDIR /var/www/html
+# Copy application files into the container
+COPY . /var/default
 
 # Copy Composer binary from Composer image
 COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
 
 # Configure Nginx
 COPY ./docker/standalone/nginx/nginx.conf /etc/nginx/nginx.conf
-COPY ./docker/standalone/nginx/default.conf /etc/nginx/conf.d/default.conf
 
 # Create directory for Nginx logs and set ownership
 RUN mkdir -p /var/log/nginx && \
@@ -38,8 +37,11 @@ RUN mkdir -p /var/log/nginx && \
 # Expose ports
 EXPOSE 80
 
-# Run composer install if composer.json is present
-RUN if [ -f composer.json ]; then composer install --no-dev --optimize-autoloader; fi
+# Copy startup script
+COPY ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh
 
-# Start both PHP-FPM and Nginx
-CMD ["sh", "-c", "service nginx start && php-fpm -F"]
+# Make startup script executable
+RUN chmod +x /usr/local/bin/startup-script.sh
+
+# Start the startup script
+CMD ["/usr/local/bin/startup-script.sh"]
diff --git a/docker/standalone/docker-compose.yml b/docker/standalone/docker-compose.yml
index a55c85d86..ed5dc8478 100644
--- a/docker/standalone/docker-compose.yml
+++ b/docker/standalone/docker-compose.yml
@@ -1,18 +1,13 @@
 version: '3'
 
 services:
-  web:
+  controlpanel_web:
     build:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile
-    container_name: controlpanel_web
+    container_name: controlpanel
     ports:
       - "80:80"
     volumes:
-      - "../../:/var/www/html:delegated"
-    environment:
-      - DB_HOST=10.0.0.16
-      - DB_PORT=3306
-      - DB_DATABASE=controlpanel
-      - DB_USERNAME=controlpaneluser
-      - DB_PASSWORD=pass
+      - '/mnt/user/appdata/ctrlpanel/www/:/var/www/html:rw'
+      - '/mnt/user/appdata/ctrlpanel/nginx/:/etc/nginx/conf.d/:rw'
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
new file mode 100644
index 000000000..942e9f8e1
--- /dev/null
+++ b/docker/standalone/scripts/startup.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# Check if /var/www/html is empty or .env file doesn't exist
+if [ -z "$(ls -A /var/www/html)" ] || [ ! -f "/var/www/html/.env" ]; then
+    # Copy everything from /var/default to /var/www/html
+    cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
+
+    # Copy default Nginx configuration
+    cp -n /var/default/docker/standalone/nginx/default.conf /etc/nginx/conf.d/default.conf
+
+    # Execute composer install if composer.json is present and there's no vendor directory
+    if [ -f "/var/www/html/composer.json" ] && [ ! -d "/var/www/html/vendor" ]; then
+        cd /var/www/html
+        composer install --no-dev --optimize-autoloader
+        cd -
+    fi
+fi
+
+# Start Nginx
+service nginx start
+
+# Start PHP-FPM
+php-fpm -F

From 37e505c37eb286fc9d62b32839ed6f360dea7b4c Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 11:52:52 +0200
Subject: [PATCH 274/514] REMOVE: empty composer file at root

---
 composer | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 composer

diff --git a/composer b/composer
deleted file mode 100644
index e69de29bb..000000000

From 077ee2c7e4b325257dd3d160f161f931941c5347 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 11:54:03 +0200
Subject: [PATCH 275/514] REMOVE: strange unused test.json file

---
 test.json | 12 ------------
 1 file changed, 12 deletions(-)
 delete mode 100644 test.json

diff --git a/test.json b/test.json
deleted file mode 100644
index e0ff42154..000000000
--- a/test.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
-    {
-        "PASSWORD": "",
-        "USERNAME": "",
-        "AUTO_UPDATE": "0",
-        "BOT_PY_FILE": "bot.py",
-        "PY_PACKAGES": "",
-        "USER_UPLOAD": "0",
-        "INSTALL_REPO": "",
-        "INSTALL_BRANCH": ""
-    }
-]

From 3656c8169d74300c8a3be2a52f3ee5067738066d Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 11:59:44 +0200
Subject: [PATCH 276/514] UPDATE: cleared and documented git files

---
 .gitattributes |  5 +++++
 .gitignore     | 35 ++++++++++++++++++++---------------
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index 967315dd3..2f74b7dd8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,5 +1,10 @@
+# Automatically detect text files
 * text=auto
+
+# Vendored files for specific languages
 *.css linguist-vendored
 *.scss linguist-vendored
 *.js linguist-vendored
+
+# Ignore CHANGELOG.md when exporting
 CHANGELOG.md export-ignore
diff --git a/.gitignore b/.gitignore
index ad9d095b8..f72249a83 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,29 +1,34 @@
+# Ignore dependencies and cache
 /node_modules
+/vendor
+/storage/*.key
+
+# Ignore public assets
 /public/hot
 /public/storage
-/storage/*.key
-/vendor
-/storage/credit_deduction_log
-storage/debugbar
+/storage/app/public/logo.png
+
+# Ignore environment files and configuration
 .env
 .env.testing
 .env.backup
-.idea
+.env.dev
+
+# Ignore testing and debug logs
 .phpunit.result.cache
-.editorconfig
-docker-compose.override.yml
-Homestead.json
-Homestead.yaml
 npm-debug.log
 yarn-error.log
 yarn.lock
+
+# Ignore Docker and Homestead configuration
+docker-compose.override.yml
+Homestead.json
+Homestead.yaml
+
+# Ignore gitignore itself
 .gitignore
-.env.dev
-.env.testing
-storage/invoices.zip
-storage/app/public/logo.png
-*vscode
- - Kopie.env
+
+# Ignore installation logs and locks
 public/install/logs.txt
 install.lock
 public/install/logs/installer.log

From f18e8c817774edfde0475439065ab0f60aa2c241 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 11:59:57 +0200
Subject: [PATCH 277/514] UPDATE: cleared and documented .env.exemple

---
 .env.example | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/.env.example b/.env.example
index 98f9662bd..46f1a273a 100644
--- a/.env.example
+++ b/.env.example
@@ -4,25 +4,24 @@ APP_ENV=production
 APP_KEY=
 APP_DEBUG=false
 APP_URL=http://localhost
-# List with timezones https://www.php.net/manual/en/timezones.php
-APP_TIMEZONE=UTC
+APP_TIMEZONE=UTC # List with timezones https://www.php.net/manual/en/timezones.php
 ### --- App Settings End --- ###
 
-### --- DB Settings (required) --- ###
+### --- Database Settings (required) --- ###
 DB_CONNECTION=mysql
 DB_HOST=127.0.0.1
 DB_PORT=3306
 DB_DATABASE=dashboard
 DB_USERNAME=dashboarduser
 DB_PASSWORD=
-### --- DB Settings End --- ###
+### --- Database Settings End --- ###
 
-
-# Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)
+### --- Google Recaptcha Settings --- ###
 RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
 RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
+### --- Google Recaptcha Settings End --- ###
 
-# Mail Server Settings - (HOST -> SMTP Server)
+### --- Mail Server Settings --- ###
 MAIL_MAILER=smtp
 MAIL_HOST=mailhog
 MAIL_PORT=1025
@@ -31,25 +30,22 @@ MAIL_PASSWORD=null
 MAIL_ENCRYPTION=null
 MAIL_FROM_ADDRESS=null
 MAIL_FROM_NAME="${APP_NAME}"
+### --- Mail Server Settings End --- ###
 
-
-# Laravel Logging Settings - https://laravel.com/docs/5.7/logging - Not needed to be changed
+### --- Logging Settings --- ###
 LOG_CHANNEL=stack
 LOG_LEVEL=debug
+### --- Logging Settings End --- ###
 
-# Do not change anything below this line
-BROADCAST_DRIVER=log
+### --- Cache and Queue Settings --- ###
 CACHE_DRIVER=file
 QUEUE_CONNECTION=database
 SESSION_DRIVER=file
 SESSION_LIFETIME=120
+SETTINGS_CACHE_ENABLED=true
+### --- Cache and Queue Settings End --- ###
 
-MEMCACHED_HOST=127.0.0.1
-
-REDIS_HOST=127.0.0.1
-REDIS_PASSWORD=null
-REDIS_PORT=6379
-
+### --- External Services Credentials --- ###
 AWS_ACCESS_KEY_ID=
 AWS_SECRET_ACCESS_KEY=
 AWS_DEFAULT_REGION=us-east-1
@@ -59,9 +55,15 @@ PUSHER_APP_ID=
 PUSHER_APP_KEY=
 PUSHER_APP_SECRET=
 PUSHER_APP_CLUSTER=mt1
+### --- External Services Credentials End --- ###
+
+### --- Additional Configuration --- ###
+MEMCACHED_HOST=127.0.0.1
+
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
 
 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
-
-# Settings Cache
-SETTINGS_CACHE_ENABLED=true
+### --- Additional Configuration End --- ###

From b2ee49f534059cc75115f2702970413f4adf94f8 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 12:02:18 +0200
Subject: [PATCH 278/514] UPDATE: de-mixed the code of conduct from the
 contribute file

---
 .github/CODE_OF_CONDUCT.md | 25 +++++++++++++++++++++++++
 .github/CONTRIBUTING.md    | 26 --------------------------
 2 files changed, 25 insertions(+), 26 deletions(-)

diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
index e69de29bb..1714350ae 100644
--- a/.github/CODE_OF_CONDUCT.md
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,25 @@
+## Code of Conduct
+
+### Our Pledge
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+### Coding Style
+
+We are following the PSR12 code standard for PHP.
+
+### Our Standards
+Examples of behavior that contributes to creating a positive environment include:
+
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+- The use of sexualized language or imagery and unwelcome sexual attention or advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 74ddb1f9f..c7d336441 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -15,29 +15,3 @@ php artisan translatable:export en
 1. Give your PR a good descriptive title, so we can view immediately what the PR is about.
 2. The dev team will look at your code and approve / merge when possible.
 3. Make sure your PR follows our code of conduct and coding style.
-
-## Code of Conduct
-
-### Our Pledge
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
-
-### Coding Style
-
-We are following the PSR12 code standard for PHP.
-
-### Our Standards
-Examples of behavior that contributes to creating a positive environment include:
-
-- Using welcoming and inclusive language
-- Being respectful of differing viewpoints and experiences
-- Gracefully accepting constructive criticism
-- Focusing on what is best for the community
-- Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-- The use of sexualized language or imagery and unwelcome sexual attention or advances
-- Trolling, insulting/derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others' private information, such as a physical or electronic address, without explicit permission
-- Other conduct which could reasonably be considered inappropriate in a professional setting

From 0f138cab1dffd0c046b6854d2ae8133210e2f2f3 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 12:13:35 +0200
Subject: [PATCH 279/514] ADD: basic Pull request tempalte

---
 .github/PULL_REQUEST_TEMPLATE.md | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index e69de29bb..50d3e3885 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,31 @@
+⚠️ Please be sure that you have read pull request rules.
+
+Tick the checkbox if you understand [x]:
+- [ ] I have read and understand the pull request rules.
+
+# Description
+
+Fixes #(issue)
+
+## Type of change
+
+Please delete any options that are not relevant.
+
+- Bug fix (non-breaking change which fixes an issue)
+- User interface (UI)
+- New feature (non-breaking change which adds functionality)
+- Breaking change (a fix or feature that would cause existing functionality to not work as expected)
+- Other
+- This change requires a documentation update
+
+## Checklist
+
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my own code and tested it
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] My changes generates no new warnings
+- [ ] My code needed automated testing. I have added them (this is optional task)
+
+## Screenshots (if any)
+
+Please do not use any external image service. Instead, just paste in or drag and drop the image here, and it will be uploaded automatically.
\ No newline at end of file

From 9b45d76b445cf166c16c1ab026d967a8cabb2ee5 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 6 May 2024 12:30:52 +0200
Subject: [PATCH 280/514] ADD: Basic Security Policy

---
 .github/SECURITY.md | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 .github/SECURITY.md

diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 000000000..e3c6ecee8
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,17 @@
+# Security Policy
+
+## Reporting a Vulnerability
+
+Please report security issues to ...
+
+Do not use the public issue tracker or discuss it in public as it will cause more damage.
+
+## Do you accept other 3rd-party bug bounty platforms?
+
+At this moment, we do not accept other bug bounty platforms, please report through GitHub Advisories only. We will ignore all 3rd-party bug bounty platforms emails.
+
+## Supported Versions
+
+### ControlPanel Versions
+
+You should use or upgrade to the latest version of ControlPanel.

From 44a6946c44257bb5dc781c024c1d75003c3c0f6f Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 09:59:15 +0200
Subject: [PATCH 281/514] UPDATE: made a better security policy

---
 .github/SECURITY.md | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index e3c6ecee8..278e81e71 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -2,16 +2,16 @@
 
 ## Reporting a Vulnerability
 
-Please report security issues to ...
+🛡️ If you discover a security vulnerability, please report it to us via GitHub Advisories.
 
-Do not use the public issue tracker or discuss it in public as it will cause more damage.
+⚠️ Please refrain from using the public issue tracker or discussing the vulnerability in public channels, as it may exacerbate the issue.
 
-## Do you accept other 3rd-party bug bounty platforms?
+## Acceptance of Bug Bounty Platforms
 
-At this moment, we do not accept other bug bounty platforms, please report through GitHub Advisories only. We will ignore all 3rd-party bug bounty platforms emails.
+At this time, we only accept vulnerability reports through GitHub Advisories. We kindly ask that you do not submit reports via other third-party bug bounty platforms, as they will be disregarded.
 
 ## Supported Versions
 
 ### ControlPanel Versions
 
-You should use or upgrade to the latest version of ControlPanel.
+We strongly recommend using or upgrading to the latest version of ControlPanel to ensure you have access to the latest security fixes and enhancements.

From f12ab58c8e0d3cb91e4a44b403a71f0db68fbec8 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 09:59:27 +0200
Subject: [PATCH 282/514] UPDATE: made a better code of conduct

---
 .github/CODE_OF_CONDUCT.md | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
index 1714350ae..6b807f423 100644
--- a/.github/CODE_OF_CONDUCT.md
+++ b/.github/CODE_OF_CONDUCT.md
@@ -1,13 +1,10 @@
 ## Code of Conduct
 
-### Our Pledge
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+### 🤝 Our Pledge
 
-### Coding Style
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
 
-We are following the PSR12 code standard for PHP.
-
-### Our Standards
+### 🌟 Our Standards
 Examples of behavior that contributes to creating a positive environment include:
 
 - Using welcoming and inclusive language

From cad6361e492e312dcd011ef6ff59c477a6b84618 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 09:59:39 +0200
Subject: [PATCH 283/514] UPDATE: made a better contributing policy

---
 .github/CONTRIBUTING.md | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index c7d336441..ff44e2115 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,17 +1,34 @@
-# Contributing
+# Contributing Guidelines
 
-When contributing to this repository, please go through the open issues to see if you can contribute to something. If you want to contribute something that is not in the issues you can make an issue and wait for response from the dev team.
+Thank you for considering contributing to this repository! Before making a contribution, please take a moment to review the following guidelines.
 
-Please note we have a code of conduct, please follow it in all your interactions with the project.
+## 🕵️‍♂️ Finding Tasks
 
-If you added any Strings which are displayed at the frontend please localize them (e.g. "New String" -> {{ __('New String') }}) and run the localization string generation:
+Check the open issues to see if there's something you can contribute to. If you have an idea or encounter a bug that's not already listed, feel free to create a new issue and wait for feedback from the development team.
 
+## 🤝 Code of Conduct
+
+Please adhere to our [Code of Conduct](link-to-code-of-conduct) in all your interactions with the project.
+
+## 🌍 Localization
+
+If you add any strings that are displayed on the frontend, please localize them using the following format:
+```
+"New String" -> {{ __('New String') }}
+```
+After adding localized strings, run the following command to generate localization files:
 ```cmd
 php artisan translatable:export en
 ```
 
-## Pull request process
+## 🚀 Pull Request Process
+
+1. Give your pull request (PR) a clear and descriptive title that summarizes the changes.
+2. The development team will review your code and provide feedback or approve/merge it when appropriate.
+3. Ensure that your PR follows our Code of Conduct and coding style guidelines.
+
+### 💻 Coding Style
+
+We follow the PSR12 code standard for PHP.
 
-1. Give your PR a good descriptive title, so we can view immediately what the PR is about.
-2. The dev team will look at your code and approve / merge when possible.
-3. Make sure your PR follows our code of conduct and coding style.
+Thank you for your contributions! 🎉

From 14e200f88e655a6f337677d7baf03854b90a7123 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 09:59:50 +0200
Subject: [PATCH 284/514] UPDATE: made a better pull request template

---
 .github/PULL_REQUEST_TEMPLATE.md | 38 ++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 50d3e3885..095ada5e9 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,31 +1,35 @@
-⚠️ Please be sure that you have read pull request rules.
+✨ Thank you for your contribution to our project! Before you submit your pull request, please take a moment to review and complete the following
 
-Tick the checkbox if you understand [x]:
-- [ ] I have read and understand the pull request rules.
+⚠️ Please modify this template below and if not already one, read our pull request rules, Thanks!
 
-# Description
+Ensure that your pull request meets the following criteria:
 
-Fixes #(issue)
+- The code follows the style guidelines of this project
+- You have performed a self-review of your own code and tested it
+- You have commented your code, particularly in hard-to-understand areas
+- Your changes generate no new warnings
 
-## Type of change
+---
 
-Please delete any options that are not relevant.
+💡 **Description**
+
+Briefly describe the purpose of your pull request, including any relevant issue numbers it addresses.
+
+---
+
+🛠️ **Type of Change**
+
+Please select the appropriate type of change:
 
 - Bug fix (non-breaking change which fixes an issue)
-- User interface (UI)
+- User interface (UI) improvement
 - New feature (non-breaking change which adds functionality)
 - Breaking change (a fix or feature that would cause existing functionality to not work as expected)
 - Other
 - This change requires a documentation update
 
-## Checklist
-
-- [ ] My code follows the style guidelines of this project
-- [ ] I have performed a self-review of my own code and tested it
-- [ ] I have commented my code, particularly in hard-to-understand areas
-- [ ] My changes generates no new warnings
-- [ ] My code needed automated testing. I have added them (this is optional task)
+---
 
-## Screenshots (if any)
+🖼️ **Screenshots (if applicable)**
 
-Please do not use any external image service. Instead, just paste in or drag and drop the image here, and it will be uploaded automatically.
\ No newline at end of file
+If your pull request includes any visual changes, please provide screenshots here, do not use any external link.

From 5ea4ceda6babd1468791b41c470ca53e71d36b54 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 10:00:00 +0200
Subject: [PATCH 285/514] UPDATE: made a better main readme

---
 README.md | 100 +++++++++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 43 deletions(-)

diff --git a/README.md b/README.md
index c121ff78a..092ac2171 100644
--- a/README.md
+++ b/README.md
@@ -1,67 +1,81 @@
-### Features
-
--   PayPal, Stripe and Mollie Integration
--   Hourly, Weekely, Monthly, Quarterly and Annual billing Cycles
--   Referral System
--   Partner System
--   Ticket System
--   Upgrade/Downgrade Server Resources
--   Store (credit system with hourly billing and invoices)
--   Email Verification
--   Audit Log
--   Admin Dashboard
--   User/Server Management
--   Customisable server plans
--   Vouchers
--   Alert System
--   Theme Support
--   and so much more!
+<div align="center">
+    <img src="./public/favicon" width="128" alt="" />
+</div>
 
 # CtrlPanel-gg
 
-![ctrlpanel](https://user-images.githubusercontent.com/67899387/214684708-739c1d21-06e8-4dec-a4f1-81533a46cc7e.png)
+CtrlPanel offers an easy-to-use and free billing solution for all starting and experienced hosting providers that seamlessly integrates with the Pterodactyl panel. It facilitates account creation, server ordering, and management, while offering addons, multiple payment methods, and customizable themes for a comprehensive solution.
 
+![GitHub tag](https://img.shields.io/github/tag/ControlPanel-gg/dashboard)
+![Overall Installations](https://img.shields.io/badge/Overall%20Installations-5000%2B-green)
+![GitHub stars](https://img.shields.io/github/stars/ControlPanel-gg/dashboard)
+[![Crowdin](https://badges.crowdin.net/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg)
+![License](https://img.shields.io/github/license/ControlPanel-gg/dashboard)
+![Discord](https://img.shields.io/discord/787829714483019826)
 
-![](https://img.shields.io/endpoint?label=v0.9%20Installations&url=https%3A%2F%2Fmarket.ctrlpanel.gg%2Fcallhome.php%3Fgetinstalls)
-![](https://img.shields.io/badge/Overall%20Installations-5000%2B-green)
-![](https://img.shields.io/github/stars/ctrlpanel-gg/dashboard) ![](https://img.shields.io/github/forks/ctrlpanel-gg/panel) ![](https://img.shields.io/github/tag/ctrlpanel-gg/panel) [![Crowdin](https://badges.crowdin.com/project/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ctrlpanel-gg/panel) ![](https://img.shields.io/github/license/ctrlpanel-gg/panel) ![](https://img.shields.io/discord/787829714483019826)
-## About
+![CtrlPanel](https://user-images.githubusercontent.com/67899387/214684708-739c1d21-06e8-4dec-a4f1-81533a46cc7e.png)
 
-CtrlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that charges users depending on the billing cycle you chose for each server they have and suspends them if they run out of credits.
+## ⭐ Features
 
-This dashboard offers an easy to use and free billing solution for all starting and experienced hosting providers. This dashboard has many customisation options and added discord Oauth verification to offer a solid link between your discord server and your dashboard. You can check our [Demo here](https://demo.CtrlPanel.gg "Demo").
+- Store (credit system with hourly billing and invoices)
+- Many Popular Payment Methods
+- Referral
+- Partner
+- Vouchers
+- Ticket
+- Account Management
+- Admin Dashboard and Tools
+- Addon Support
+- and more!
 
-### [Installation](https://ctrlpanel.gg/docs/intro "Installation")
+## ⛰️ Live Demo
 
-### [Updating](https://ctrlpanel.gg/docs/Installation/updating "Updating")
+Try it!
 
-### [Discord](https://discord.gg/4Y6HjD2uyU "Discord")
+Demo Server: [demo.CtrlPanel.gg](https://demo.CtrlPanel.gg)
 
-### [Contributing](https://ctrlpanel.gg/docs/Contributing/contributing "Contributing")
+It is a temporary live demo; all data will be deleted.
 
-### [Donating](https://ctrlpanel.gg/docs/Contributing/donating "Donating")
+## 🔧 How to Install
 
+### 🐳 Docker
 
+```bash
+docker run ...
+```
 
-# Preview
+CtrlPanel is now running on [0.0.0.0:3001](http://0.0.0.0:3001). Don't forget to configure the database and Pterodactyl. [Documentation](documentation link here)
 
-### Server Creation
-![image](https://user-images.githubusercontent.com/67899387/214687234-d1ae58c0-5667-4e99-ac39-adeaabfcc7f2.png)
+more info: [Docker](docker documentation link here)
 
-### Overview
-![image](https://user-images.githubusercontent.com/67899387/214685859-03c8d9e1-c685-4a07-979f-df2e88ec3931.png)
+### 💪🏻 Non-Docker
 
-### Example server products
-![image](https://user-images.githubusercontent.com/67899387/214686950-218e1ede-6a1f-4e53-b3f4-fe1abc371a9c.png)
+Requirements:
 
-### Ticket System
-![image](https://user-images.githubusercontent.com/67899387/214687123-0a3d0f8f-b53c-4b0d-869a-4d5df45f5184.png)
+- Platform
+  - Major Linux distros such as Debian, Ubuntu, CentOS, Fedora, and ArchLinux etc.
+  - Windows 10 (x64), Windows Server ...
 
-### Voucher System
-![image](https://user-images.githubusercontent.com/67899387/214686578-ec9f0b0f-6047-4665-835f-70594b56dfd5.png)
+Follow the [documentation](documentation link here) to know how to install.
 
-### Partner System
-![image](https://user-images.githubusercontent.com/67899387/214686321-36ba97a3-4181-4e60-9ba3-c9b318fe66a8.png)
+### MarketPlace
 
+If you need more functionality, check out [Marketplace](https://market.ctrlpanel.gg/resources/).
 
+## 🆙 How to Update
 
+Please read: [Update Instructions](https://ctrlpanel.gg/docs/Installation/updating)
+
+## 🆕 What's Next?
+
+Roadmap: [CtrlPanel Roadmap](https://github.com/orgs/Ctrlpanel-gg/projects/1)
+
+## 🗣️ Discussion / Ask for Help
+
+For any general or technical questions, join CtrlPanel Discord for finding answers to your question. If you cannot find the information you need, feel free to ask.
+
+## 🤝 Contributing
+
+Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
+
+Thanks to all contributors and supporters!

From 8c98acb20a5a0d9bc93ba5c1d7a228b9e8311191 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 10:18:22 +0200
Subject: [PATCH 286/514] FIX: links in main readme

---
 README.md | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 092ac2171..36c11d002 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 <div align="center">
-    <img src="./public/favicon" width="128" alt="" />
+    <img src="https://ctrlpanel.gg/img/controlpanel.png" width="128" alt="" />
 </div>
 
 # CtrlPanel-gg
@@ -34,19 +34,21 @@ Try it!
 
 Demo Server: [demo.CtrlPanel.gg](https://demo.CtrlPanel.gg)
 
-It is a temporary live demo; all data will be deleted.
+<!-- It is a temporary live demo; all data will be deleted. -->
 
 ## 🔧 How to Install
 
 ### 🐳 Docker
 
-```bash
+Soon...
+
+<!-- ```bash
 docker run ...
 ```
 
 CtrlPanel is now running on [0.0.0.0:3001](http://0.0.0.0:3001). Don't forget to configure the database and Pterodactyl. [Documentation](documentation link here)
 
-more info: [Docker](docker documentation link here)
+more info: [Docker](docker documentation link here) -->
 
 ### 💪🏻 Non-Docker
 
@@ -56,7 +58,7 @@ Requirements:
   - Major Linux distros such as Debian, Ubuntu, CentOS, Fedora, and ArchLinux etc.
   - Windows 10 (x64), Windows Server ...
 
-Follow the [documentation](documentation link here) to know how to install.
+Follow the [documentation](https://ctrlpanel.gg/docs/intro) to know how to install.
 
 ### MarketPlace
 
@@ -76,6 +78,6 @@ For any general or technical questions, join CtrlPanel Discord for finding answe
 
 ## 🤝 Contributing
 
-Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
+Please read [CONTRIBUTING.md](https://github.com/Ctrlpanel-gg/panel/blob/main/.github/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
 
 Thanks to all contributors and supporters!

From f563dcdd741ed080d12d1c5fddd482143a5c5796 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 10:19:27 +0200
Subject: [PATCH 287/514] FIX: links in contributing.md

---
 .github/CONTRIBUTING.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index ff44e2115..72eb32a7b 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -8,7 +8,7 @@ Check the open issues to see if there's something you can contribute to. If you
 
 ## 🤝 Code of Conduct
 
-Please adhere to our [Code of Conduct](link-to-code-of-conduct) in all your interactions with the project.
+Please adhere to our [Code of Conduct](https://github.com/Ctrlpanel-gg/panel/blob/main/.github/CODE_OF_CONDUCT.md) in all your interactions with the project.
 
 ## 🌍 Localization
 

From 6f55e306c1dce4756a0c21d23114abcee3cbf5f1 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 10:22:32 +0200
Subject: [PATCH 288/514] ADD: warning to default pull request text

---
 .github/PULL_REQUEST_TEMPLATE.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 095ada5e9..89224a428 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
 ✨ Thank you for your contribution to our project! Before you submit your pull request, please take a moment to review and complete the following
 
-⚠️ Please modify this template below and if not already one, read our pull request rules, Thanks!
+⚠️ Please modify this template below and if not already done, read our pull request rules, Thanks!
 
 Ensure that your pull request meets the following criteria:
 
@@ -9,6 +9,8 @@ Ensure that your pull request meets the following criteria:
 - You have commented your code, particularly in hard-to-understand areas
 - Your changes generate no new warnings
 
+Delete the above text and the following sections before submitting your pull request.
+
 ---
 
 💡 **Description**

From 812b817968e656588f56e3a076082a03ee267051 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 10:32:24 +0200
Subject: [PATCH 289/514] ADD: donation to the project main readme

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index 36c11d002..291c86cff 100644
--- a/README.md
+++ b/README.md
@@ -81,3 +81,7 @@ For any general or technical questions, join CtrlPanel Discord for finding answe
 Please read [CONTRIBUTING.md](https://github.com/Ctrlpanel-gg/panel/blob/main/.github/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
 
 Thanks to all contributors and supporters!
+
+## ♥️ Donations
+
+If you like what we do, please consider [supporting](https://ctrlpanel.gg/docs/Contributing/donating) us.

From 1403985b24201d795a9199f3e0f7da26d73b3c85 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 13:52:51 +0200
Subject: [PATCH 290/514] UPDATE: added more php dependency to the standalone
 dockerfile

---
 docker/standalone/Dockerfile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index aafd194ad..62957baf0 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -7,10 +7,11 @@ RUN apt-get update && apt-get install -y \
     libcurl4-openssl-dev \
     libicu-dev \
     libzip-dev \
+    libpng-dev \
     && rm -rf /var/lib/apt/lists/*
 
 # Install PHP extensions
-RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip
+RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
 
 # Copy the custom PHP-FPM configuration
 ADD ./docker/standalone/php/www.conf /usr/local/etc/php-fpm.d/

From 469a814a6bb3898849ff55da2557e072237676cb Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 13:53:19 +0200
Subject: [PATCH 291/514] UPDATE: made a better standalone docker compose

---
 docker/standalone/docker-compose.yml | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/docker/standalone/docker-compose.yml b/docker/standalone/docker-compose.yml
index ed5dc8478..cd980a2af 100644
--- a/docker/standalone/docker-compose.yml
+++ b/docker/standalone/docker-compose.yml
@@ -1,13 +1,15 @@
 version: '3'
 
 services:
-  controlpanel_web:
+  controlpanel_standalone:
     build:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile
-    container_name: controlpanel
+    container_name: controlpanel_standalone
+    restart: on-failure
     ports:
       - "80:80"
+      - "443:443"
     volumes:
-      - '/mnt/user/appdata/ctrlpanel/www/:/var/www/html:rw'
-      - '/mnt/user/appdata/ctrlpanel/nginx/:/etc/nginx/conf.d/:rw'
+      - './website_files:/var/www/html:rw' # change it
+      - './nginx_config:/etc/nginx/conf.d/:rw' # change it

From cb2ea111e720badbe13626bf3972b8683716674a Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 13:53:37 +0200
Subject: [PATCH 292/514] UPDATE: made a better readme documentation for the
 standalone docker

---
 docker/standalone/README.md | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index e69de29bb..0b7fa291b 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -0,0 +1,23 @@
+## 🐳 Standalone Docker
+
+The CtrlPanel standalone Docker enables users to run CtrlPanel easily with just a few clicks.
+
+To run CtrlPanel standalone Docker, you need to have Docker installed on your machine. Some server operating systems like Unraid, TrueNAS, etc.. already have Docker installed, making it even easier to run CtrlPanel.
+
+If you're using a different operating system, you can follow the official Docker installation guide [here](https://docs.docker.com/get-docker/).
+
+Once you have Docker installed, you can run CtrlPanel standalone Docker by executing the following command:
+
+```bash
+docker run ...
+```
+
+This command will pull the latest CtrlPanel Docker image from Docker Hub and run it.
+
+The control panel will be available at http://localhost/install and will be a completely fresh installation.
+
+Note that while the container contains the full CtrlPanel installation, you will still need to perform the basic setup. You can find instructions for this [here](https://ctrlpanel.gg/docs/Installation/getting-started#basic-setup).
+
+## 🏗️ Advanced Docker
+
+If you are migrating, or want to create your own Docker image, you can follow the instructions [here]().

From 5faea04fba77626e961d6b11a78ec0f7a638d367 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 14:21:10 +0200
Subject: [PATCH 293/514] UPDATE: updated the standalone docker configuration

---
 docker/standalone/README.md | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index 0b7fa291b..992b80c82 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -1,23 +1,26 @@
-## 🐳 Standalone Docker
+# 🐳 Standalone Docker
 
 The CtrlPanel standalone Docker enables users to run CtrlPanel easily with just a few clicks.
 
 To run CtrlPanel standalone Docker, you need to have Docker installed on your machine. Some server operating systems like Unraid, TrueNAS, etc.. already have Docker installed, making it even easier to run CtrlPanel.
-
 If you're using a different operating system, you can follow the official Docker installation guide [here](https://docs.docker.com/get-docker/).
 
 Once you have Docker installed, you can run CtrlPanel standalone Docker by executing the following command:
 
 ```bash
-docker run ...
+docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html -v /path/to/nginx_config:/etc/nginx/conf.d/ ctrlpanel/ctrlpanel
 ```
 
-This command will pull the latest CtrlPanel Docker image from Docker Hub and run it.
+This command will run the latest CtrlPanel Docker image from Docker Hub and run it.
 
 The control panel will be available at http://localhost/install and will be a completely fresh installation.
 
 Note that while the container contains the full CtrlPanel installation, you will still need to perform the basic setup. You can find instructions for this [here](https://ctrlpanel.gg/docs/Installation/getting-started#basic-setup).
 
-## 🏗️ Advanced Docker
+## 🏗️ Migrating from a previous bare metal installation
+
+If you are migrating, from a previous bare metal installation, you can follow the instructions [here]() (Soon on documentation).
+
+## 🧰 Creating your own Docker image
 
-If you are migrating, or want to create your own Docker image, you can follow the instructions [here]().
+If you want to create your own Docker image, you can follow the instructions [here]() (Soon on documentation).

From 27cad9173eb351efe3ebd39d27bc2b8522aaa2fd Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 14:34:19 +0200
Subject: [PATCH 294/514] FIX: standalone dockerfile now expose port 443

---
 docker/standalone/Dockerfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index 62957baf0..d59ca6947 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -37,6 +37,7 @@ RUN mkdir -p /var/log/nginx && \
 
 # Expose ports
 EXPOSE 80
+EXPOSE 443
 
 # Copy startup script
 COPY ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh

From 84417a9f6119f8017c04a2d1d07336a1248a29e7 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 7 May 2024 23:36:45 +0200
Subject: [PATCH 295/514] UPDATE: added redis php extention to standalone
 docker

---
 docker/standalone/Dockerfile | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index d59ca6947..5c4a0c277 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -10,8 +10,9 @@ RUN apt-get update && apt-get install -y \
     libpng-dev \
     && rm -rf /var/lib/apt/lists/*
 
-# Install PHP extensions
-RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
+# Install PHP extensions including Redis
+RUN pecl install redis && docker-php-ext-enable redis \
+    && docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
 
 # Copy the custom PHP-FPM configuration
 ADD ./docker/standalone/php/www.conf /usr/local/etc/php-fpm.d/

From 7d191efa1b2b5d225aad69e39de05449dd70098c Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 10 May 2024 18:36:35 +0200
Subject: [PATCH 296/514] ADD: some permission to files

---
 docker/standalone/Dockerfile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index 5c4a0c277..2477e2337 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -36,6 +36,9 @@ COPY ./docker/standalone/nginx/nginx.conf /etc/nginx/nginx.conf
 RUN mkdir -p /var/log/nginx && \
     chown -R laravel:laravel /var/log/nginx
 
+# Set permissions for Laravel directories
+RUN chown -R www-data:www-data /var/default/storage /var/default/bootstrap/cache
+
 # Expose ports
 EXPOSE 80
 EXPOSE 443

From a7e5ab29bdc5e340d55e9decd4b4afc1c31e97e9 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 10 May 2024 18:37:01 +0200
Subject: [PATCH 297/514] ADD: standalone docker Queue Worker

---
 docker/standalone/scripts/startup.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 942e9f8e1..1c0de62ca 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -16,6 +16,9 @@ if [ -z "$(ls -A /var/www/html)" ] || [ ! -f "/var/www/html/.env" ]; then
     fi
 fi
 
+# Start the queue worker service
+php /var/www/html/artisan queue:work --sleep=3 --tries=3 &
+
 # Start Nginx
 service nginx start
 

From 0683e2d62bc9db5c7204ca31d30e105b7b2eb365 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 13 May 2024 10:29:24 +0200
Subject: [PATCH 298/514] ADD: nano to the standalone docker

---
 docker/standalone/Dockerfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index 2477e2337..f0bf06272 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -3,6 +3,7 @@ FROM php:8.1-fpm
 # Install Nginx and other dependencies
 RUN apt-get update && apt-get install -y \
     nginx \
+    nano \
     curl \
     libcurl4-openssl-dev \
     libicu-dev \

From 26a279fcb815e2d4b31abf20ddbb0566d1ccc494 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Mon, 13 May 2024 10:31:26 +0200
Subject: [PATCH 299/514] FIX: tried to fix the standalone docker permissions

---
 docker/standalone/Dockerfile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index f0bf06272..bed185d42 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -37,8 +37,8 @@ COPY ./docker/standalone/nginx/nginx.conf /etc/nginx/nginx.conf
 RUN mkdir -p /var/log/nginx && \
     chown -R laravel:laravel /var/log/nginx
 
-# Set permissions for Laravel directories
-RUN chown -R www-data:www-data /var/default/storage /var/default/bootstrap/cache
+# Set permissions (i don't know why but this is necessary, otherwise the panel won't work properly)
+RUN chown -R 777 /var/default/
 
 # Expose ports
 EXPOSE 80

From 00397c1dc8eb8d959cf1b9c64fa18c8f6af644a7 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 14 May 2024 14:47:27 +0200
Subject: [PATCH 300/514] FIX: logging config permissions

---
 config/logging.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/config/logging.php b/config/logging.php
index 5aa1dbb78..5d4134ffa 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -61,6 +61,7 @@
             'driver' => 'single',
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
+            'permission' => 0664,
         ],
 
         'daily' => [
@@ -68,6 +69,7 @@
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
             'days' => 14,
+            'permission' => 0664,
         ],
 
         'slack' => [
@@ -116,6 +118,7 @@
 
         'emergency' => [
             'path' => storage_path('logs/laravel.log'),
+            'permission' => 0664,
         ],
     ],
 

From e3957bc1924ee9eca685dba502e7b24e3dd9fa5d Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 14 May 2024 14:52:37 +0200
Subject: [PATCH 301/514] UPDATE: made a lot of change to the standalone
 dockerfile and script

---
 docker/standalone/Dockerfile         | 66 ++++++++++++++++------------
 docker/standalone/scripts/startup.sh | 55 ++++++++++++++++++-----
 2 files changed, 82 insertions(+), 39 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index bed185d42..a16bed8cb 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -1,54 +1,62 @@
 FROM php:8.1-fpm
 
-# Install Nginx and other dependencies
-RUN apt-get update && apt-get install -y \
+# Install system dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
     nginx \
     nano \
     curl \
+    git \
     libcurl4-openssl-dev \
     libicu-dev \
     libzip-dev \
     libpng-dev \
     && rm -rf /var/lib/apt/lists/*
 
-# Install PHP extensions including Redis
-RUN pecl install redis && docker-php-ext-enable redis \
-    && docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
-
-# Copy the custom PHP-FPM configuration
-ADD ./docker/standalone/php/www.conf /usr/local/etc/php-fpm.d/
-
-# Create directory for application and set ownership
-RUN mkdir -p /var/default && \
-    groupadd -g 1000 laravel && \
-    useradd -u 1000 -g laravel -ms /bin/bash laravel && \
-    chown laravel:laravel /var/default
+# Install PHP extensions
+RUN pecl install redis \
+    && docker-php-ext-enable redis \
+    && docker-php-ext-install -j$(nproc) \
+        mysqli \
+        pdo \
+        pdo_mysql \
+        intl \
+        zip \
+        gd \
+        bcmath \
+    && rm -rf /tmp/* /var/cache/*
+
+# Install Composer
+COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
 
-# Copy application files into the container
-COPY . /var/default
+# Create directory for application
+RUN mkdir -p /var/default /var/www/html
 
-# Copy Composer binary from Composer image
-COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
+# Create user and group for Laravel
+RUN groupadd -g 1000 laravel \
+    && useradd -u 1000 -g laravel -ms /bin/bash laravel \
+    && chown -R laravel:laravel /var/default /var/www/html
 
-# Configure Nginx
-COPY ./docker/standalone/nginx/nginx.conf /etc/nginx/nginx.conf
+# Copy application files
+COPY --chown=laravel:laravel . /var/default
 
-# Create directory for Nginx logs and set ownership
-RUN mkdir -p /var/log/nginx && \
-    chown -R laravel:laravel /var/log/nginx
+# Copy PHP-FPM configuration
+COPY --chown=laravel:laravel ./docker/standalone/php/www.conf /usr/local/etc/php-fpm.d/
 
-# Set permissions (i don't know why but this is necessary, otherwise the panel won't work properly)
-RUN chown -R 777 /var/default/
+# Copy Nginx configuration
+COPY --chown=laravel:laravel ./docker/standalone/nginx/nginx.conf /etc/nginx/nginx.conf
+# Create directory for Nginx logs
+RUN mkdir -p /var/log/nginx && chown -R laravel:laravel /var/log/nginx
 
 # Expose ports
-EXPOSE 80
-EXPOSE 443
+EXPOSE 80 443
 
 # Copy startup script
-COPY ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh
-
+COPY --chown=laravel:laravel ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh
 # Make startup script executable
 RUN chmod +x /usr/local/bin/startup-script.sh
 
+# Set the working directory
+WORKDIR /var/www/html
+
 # Start the startup script
 CMD ["/usr/local/bin/startup-script.sh"]
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 1c0de62ca..5f36512d9 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -1,26 +1,61 @@
 #!/bin/bash
 
-# Check if /var/www/html is empty or .env file doesn't exist
-if [ -z "$(ls -A /var/www/html)" ] || [ ! -f "/var/www/html/.env" ]; then
+# Log directory
+LOG_DIR="/var/www/html/storage/logs"
+
+echo "Starting script..."
+
+echo "Clearing log file..."
+# clean all logs in log directory
+if [ -n "$LOG_DIR" ]; then
+    rm -f "$LOG_DIR/startup-script.log"
+fi
+
+# Check if log directory exists
+if [ ! -d "$LOG_DIR" ]; then
+    echo "Warning: Log directory does not exist (maybe first install ?). Logging disabled until restart."
+    LOG_DIR=""
+fi
+
+# Function to log messages
+log_message() {
+    if [ -n "$LOG_DIR" ]; then
+        echo "$1" >> "$LOG_DIR/startup-script.log"
+    fi
+    echo "$1"
+}
+
+# Check if project folder is empty.
+if [ -z "$(ls -A /var/www/html)" ]; then
+    log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
+    chown -R laravel:laravel /var/www/html/
+    chmod -R 755 /var/www/html
+fi
 
-    # Copy default Nginx configuration
+# Check and copy default Nginx configuration if not exists
+if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
+    log_message "Warning: Nginx configuration not found. Copying default configuration..."
     cp -n /var/default/docker/standalone/nginx/default.conf /etc/nginx/conf.d/default.conf
+fi
 
-    # Execute composer install if composer.json is present and there's no vendor directory
-    if [ -f "/var/www/html/composer.json" ] && [ ! -d "/var/www/html/vendor" ]; then
-        cd /var/www/html
-        composer install --no-dev --optimize-autoloader
-        cd -
-    fi
+# Check and execute composer install if composer.json is present and there's no vendor directory
+if [ -f "/var/www/html/composer.json" ] && [ ! -d "/var/www/html/vendor" ]; then
+    log_message "Warning: Composer dependencies not found. Running composer install..."
+    cd /var/www/html || exit
+    composer install --no-dev --optimize-autoloader
+    cd - || exit
 fi
 
 # Start the queue worker service
-php /var/www/html/artisan queue:work --sleep=3 --tries=3 &
+log_message "Starting the queue worker service..."
+runuser -u laravel -- php /var/www/html/artisan queue:work --sleep=3 --tries=3 &
 
 # Start Nginx
+log_message "Starting Nginx..."
 service nginx start
 
 # Start PHP-FPM
+log_message "Starting PHP-FPM..."
 php-fpm -F

From dc1eca34ef2652909e55cdb6105cc99f98f5adb9 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 14 May 2024 14:52:56 +0200
Subject: [PATCH 302/514] ADD: warning on top of the developement docker readme

---
 docker/development/README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docker/development/README.md b/docker/development/README.md
index 1581bd17a..1838becbc 100644
--- a/docker/development/README.md
+++ b/docker/development/README.md
@@ -1,3 +1,5 @@
+⚠ Caution: These instructions have not been updated since before version 1.0 of the project. Therefore, there may be inaccuracies, instability, or non-functional aspects. Proceed with care. (you may want to take a look at the standalone docker instread)
+
 # Building the development environment
 
 cd into the project directory and run the following command: `sh bin/startdocker.sh`
@@ -31,5 +33,3 @@ php artisan migrate:fresh --seed --env=testing
 Now when running tests with PHPUnit it will use your testing database and not your local development one.
 This is configured in the __phpunit.xml__. You can run your tests by running the command like this. Just type and enter.
 `php artisan test`.
-
-

From 1c30f1310d16a0e3cc3cbce6dc86633b9027a636 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 14 May 2024 15:03:06 +0200
Subject: [PATCH 303/514] ADD: redis to php extention check of the panel
 installer

---
 public/install/functions.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/install/functions.php b/public/install/functions.php
index a5f2b0454..01dbcd04d 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -15,7 +15,7 @@
 
 (new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
 
-$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl'];
+$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
 
 $requirements = [
     'minPhp' => '8.1',

From 98ce2e331501d6b3459e20c8df86b5e4b87a3855 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 14 May 2024 15:10:03 +0200
Subject: [PATCH 304/514] FIX: trusted proxy depreciated issue

---
 config/trustedproxy.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/trustedproxy.php b/config/trustedproxy.php
index dc46c31ba..f3b88cd52 100644
--- a/config/trustedproxy.php
+++ b/config/trustedproxy.php
@@ -26,7 +26,7 @@
      * subsequently passed through.
      */
     'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ?
-        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)),
+        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', '')),
 
     /*
      * Or, to trust all proxies that connect

From cea4e9efd7b936f743ed0a43531cd816793dbac0 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 16 May 2024 13:14:55 +0200
Subject: [PATCH 305/514] implementing a mechanism to detect the absence of
 install.lock and redirecting users to /install to initiate the installation
 process.

---
 .gitignore                            |  1 +
 app/Http/Kernel.php                   |  2 ++
 app/Http/Middleware/InstallerLock.php | 24 ++++++++++++++++++++++++
 3 files changed, 27 insertions(+)
 create mode 100644 app/Http/Middleware/InstallerLock.php

diff --git a/.gitignore b/.gitignore
index f72249a83..feb1500a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 # Ignore dependencies and cache
+/.idea
 /node_modules
 /vendor
 /storage/*.key
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index d0b1c7f7e..96815f452 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -4,6 +4,7 @@
 
 use App\Http\Middleware\ApiAuthToken;
 use App\Http\Middleware\CheckSuspended;
+use App\Http\Middleware\InstallerLock;
 use App\Http\Middleware\isAdmin;
 use App\Http\Middleware\isMod;
 use App\Http\Middleware\LastSeen;
@@ -36,6 +37,7 @@ class Kernel extends HttpKernel
      */
     protected $middlewareGroups = [
         'web' => [
+            InstallerLock::class,
             \App\Http\Middleware\EncryptCookies::class,
             \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
             \Illuminate\Session\Middleware\StartSession::class,
diff --git a/app/Http/Middleware/InstallerLock.php b/app/Http/Middleware/InstallerLock.php
new file mode 100644
index 000000000..9390a598c
--- /dev/null
+++ b/app/Http/Middleware/InstallerLock.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Http\Request;
+
+class InstallerLock
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
+     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        if (!file_exists(base_path()."/install.lock")){
+            return redirect('/install');
+        }
+        return $next($request);
+    }
+}

From d13365e856f8d61a4b4cd1d7853fbed3512680cd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 16 May 2024 13:22:44 +0200
Subject: [PATCH 306/514] Remove unused Middlewares

---
 app/Http/Kernel.php | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 96815f452..cd7cef5fb 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -5,8 +5,6 @@
 use App\Http\Middleware\ApiAuthToken;
 use App\Http\Middleware\CheckSuspended;
 use App\Http\Middleware\InstallerLock;
-use App\Http\Middleware\isAdmin;
-use App\Http\Middleware\isMod;
 use App\Http\Middleware\LastSeen;
 use Illuminate\Foundation\Http\Kernel as HttpKernel;
 
@@ -72,8 +70,6 @@ class Kernel extends HttpKernel
         'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
-        'admin' => isAdmin::class,
-        'moderator' => isMod::class,
         'api.token' => ApiAuthToken::class,
         'checkSuspended' => CheckSuspended::class,
         'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,

From ddb628a34c957965a77a3fda14f4ad96b8382f8a Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 17 May 2024 14:35:17 +0200
Subject: [PATCH 307/514] FIX: csrf forms missing the hidden inputs

---
 themes/BlueInfinity/views/layouts/main.blade.php  |  3 +++
 .../views/admin/activitylogs/index.blade.php      |  2 ++
 themes/default/views/admin/api/create.blade.php   |  2 ++
 themes/default/views/admin/api/edit.blade.php     |  2 ++
 .../default/views/admin/coupons/create.blade.php  |  2 ++
 themes/default/views/admin/coupons/edit.blade.php |  2 ++
 themes/default/views/admin/legal/index.blade.php  |  2 ++
 .../default/views/admin/partners/create.blade.php |  2 ++
 .../default/views/admin/partners/edit.blade.php   |  2 ++
 .../default/views/admin/products/create.blade.php |  2 ++
 .../default/views/admin/products/edit.blade.php   |  2 ++
 themes/default/views/admin/roles/edit.blade.php   |  3 ++-
 themes/default/views/admin/servers/edit.blade.php |  2 ++
 .../default/views/admin/settings/index.blade.php  |  4 ++++
 themes/default/views/admin/store/create.blade.php |  2 ++
 themes/default/views/admin/store/edit.blade.php   |  2 ++
 .../views/admin/ticket/blacklist.blade.php        |  5 +++--
 .../default/views/admin/ticket/category.blade.php |  7 +++++--
 .../views/admin/usefullinks/create.blade.php      |  3 ++-
 .../views/admin/usefullinks/edit.blade.php        |  2 ++
 themes/default/views/admin/users/edit.blade.php   | 15 +++++++++------
 .../views/admin/users/notifications.blade.php     |  2 ++
 .../default/views/admin/vouchers/create.blade.php |  2 ++
 .../default/views/admin/vouchers/edit.blade.php   |  2 ++
 themes/default/views/auth/login.blade.php         |  2 ++
 .../views/auth/passwords/confirm.blade.php        |  2 ++
 .../default/views/auth/passwords/email.blade.php  |  1 +
 .../default/views/auth/passwords/reset.blade.php  |  2 ++
 themes/default/views/auth/register.blade.php      |  6 ++++--
 themes/default/views/auth/verify.blade.php        |  2 ++
 themes/default/views/layouts/main.blade.php       |  3 +++
 themes/default/views/profile/index.blade.php      |  3 ++-
 themes/default/views/servers/create.blade.php     |  1 +
 themes/default/views/servers/settings.blade.php   | 10 ++++++----
 themes/default/views/store/checkout.blade.php     |  2 ++
 themes/default/views/ticket/create.blade.php      |  2 ++
 36 files changed, 91 insertions(+), 19 deletions(-)

diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index b6549a7a0..71de7c9f7 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -85,6 +85,7 @@ class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                                 </button>
                             @endforeach
 
+                            <input type="hidden" name="_token" value="{{ csrf_token() }}">
                         </form>
                     </div>
                 </li>
@@ -190,6 +191,8 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                             <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
                             {{ __('Logout') }}
                         </button>
+
+                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                     </form>
                 </div>
             </li>
diff --git a/themes/default/views/admin/activitylogs/index.blade.php b/themes/default/views/admin/activitylogs/index.blade.php
index fda21cf8e..57cc4015b 100644
--- a/themes/default/views/admin/activitylogs/index.blade.php
+++ b/themes/default/views/admin/activitylogs/index.blade.php
@@ -56,6 +56,8 @@
                                         <button class="btn btn-light btn-sm" type="submit"><i class="fa fa-search"></i></button>
                                     </div>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/api/create.blade.php b/themes/default/views/admin/api/create.blade.php
index e0025e859..24fba4459 100644
--- a/themes/default/views/admin/api/create.blade.php
+++ b/themes/default/views/admin/api/create.blade.php
@@ -50,6 +50,8 @@ class="form-control @error('memo') is-invalid @enderror">
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/api/edit.blade.php b/themes/default/views/admin/api/edit.blade.php
index f99e0b278..e9ebdc669 100644
--- a/themes/default/views/admin/api/edit.blade.php
+++ b/themes/default/views/admin/api/edit.blade.php
@@ -51,6 +51,8 @@ class="form-control @error('memo') is-invalid @enderror">
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/coupons/create.blade.php b/themes/default/views/admin/coupons/create.blade.php
index 7cef744e7..765a4b4f4 100644
--- a/themes/default/views/admin/coupons/create.blade.php
+++ b/themes/default/views/admin/coupons/create.blade.php
@@ -233,6 +233,8 @@ class="input-group-append"
                     {{__('Submit')}}
                   </button>
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
               </form>
             </div>
           </div>
diff --git a/themes/default/views/admin/coupons/edit.blade.php b/themes/default/views/admin/coupons/edit.blade.php
index aa3c81eec..e527e9d62 100644
--- a/themes/default/views/admin/coupons/edit.blade.php
+++ b/themes/default/views/admin/coupons/edit.blade.php
@@ -234,6 +234,8 @@ class="input-group-append"
                                 {{__('Submit')}}
                               </button>
                             </div>
+
+                            <input type="hidden" name="_token" value="{{ csrf_token() }}">
                           </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/legal/index.blade.php b/themes/default/views/admin/legal/index.blade.php
index 5fb6025f9..d6120eeb7 100644
--- a/themes/default/views/admin/legal/index.blade.php
+++ b/themes/default/views/admin/legal/index.blade.php
@@ -96,6 +96,8 @@ class="form-control @error('imprint') is-invalid @enderror">
                 <div class="row">
                     <button class="btn btn-primary ml-3 mt-3">{{ __('Save') }}</button>
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
         </div>
         <!-- END CUSTOM CONTENT -->
diff --git a/themes/default/views/admin/partners/create.blade.php b/themes/default/views/admin/partners/create.blade.php
index 03f8cab31..6d3aad1e9 100644
--- a/themes/default/views/admin/partners/create.blade.php
+++ b/themes/default/views/admin/partners/create.blade.php
@@ -106,6 +106,8 @@ class="form-control @error('referral_system_commission') is-invalid @enderror">
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/partners/edit.blade.php b/themes/default/views/admin/partners/edit.blade.php
index 289edf5ba..3c87549c2 100644
--- a/themes/default/views/admin/partners/edit.blade.php
+++ b/themes/default/views/admin/partners/edit.blade.php
@@ -113,6 +113,8 @@ class="form-control @error('referral_system_commission') is-invalid @enderror">
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index c6c5427f6..d93bd4023 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -340,6 +340,8 @@ class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
                     </div>
 
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
 
         </div>
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 8f7649580..4546730c7 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -343,6 +343,8 @@ class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
                     </div>
 
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
         </div>
     </section>
diff --git a/themes/default/views/admin/roles/edit.blade.php b/themes/default/views/admin/roles/edit.blade.php
index 91fef77df..600fcd093 100644
--- a/themes/default/views/admin/roles/edit.blade.php
+++ b/themes/default/views/admin/roles/edit.blade.php
@@ -53,6 +53,8 @@
                 <div class="form-group d-flex justify-content-end mt-3">
                     <button name="submit" type="submit" class="btn btn-primary">{{__('Submit')}}</button>
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
 
         </div>
@@ -65,4 +67,3 @@
         })
     </script>
 @endsection
-
diff --git a/themes/default/views/admin/servers/edit.blade.php b/themes/default/views/admin/servers/edit.blade.php
index f9afd2b28..db3dc8925 100644
--- a/themes/default/views/admin/servers/edit.blade.php
+++ b/themes/default/views/admin/servers/edit.blade.php
@@ -80,6 +80,8 @@ class="fas fa-info-circle"></i>
 
                                 <button type="submit" class="btn btn-primary">{{ __('Submit') }}</button>
 
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
+                            </form>
                         </div>
                     </div>
                 </div>
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 799e426de..c023977e2 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -157,6 +157,8 @@ class="form-control" name="logo" id="logo">
                                         <div class="row">
                                             <button class="mt-3 ml-3 btn btn-primary">{{ __('Save') }}</button>
                                         </div>
+
+                                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                                     </form>
                                 </div>
                                 @foreach ($settings as $category => $options)
@@ -307,6 +309,8 @@ class="float-right ml-2 btn btn-secondary">Reset
                                                         </button>
                                                     </div>
                                                 </div>
+
+                                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                                             </form>
                                         </div>
                                     @endcanany
diff --git a/themes/default/views/admin/store/create.blade.php b/themes/default/views/admin/store/create.blade.php
index 85b3b18df..91acc0b44 100644
--- a/themes/default/views/admin/store/create.blade.php
+++ b/themes/default/views/admin/store/create.blade.php
@@ -152,6 +152,8 @@ class="form-control @error('description') is-invalid @enderror"
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/store/edit.blade.php b/themes/default/views/admin/store/edit.blade.php
index 9e8ff2303..3dc469213 100644
--- a/themes/default/views/admin/store/edit.blade.php
+++ b/themes/default/views/admin/store/edit.blade.php
@@ -142,6 +142,8 @@ class="form-control @error('description') is-invalid @enderror" required="requir
                                         {{ __('Submit') }}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/ticket/blacklist.blade.php b/themes/default/views/admin/ticket/blacklist.blade.php
index f501d3995..ac47b456b 100644
--- a/themes/default/views/admin/ticket/blacklist.blade.php
+++ b/themes/default/views/admin/ticket/blacklist.blade.php
@@ -61,7 +61,7 @@ class="fas fa-info-circle"></i></h5>
                         </div>
                         <div class="card-body">
                             <form action="{{route('admin.ticket.blacklist.add')}}" method="POST" class="ticket-form">
-                            @csrf
+                                @csrf
                                 <div class="p-0 mb-3 custom-control">
                                     <label for="user_id">{{ __('User') }}:
                                         <i data-toggle="popover" data-trigger="hover"
@@ -78,6 +78,8 @@ class="fas fa-info-circle"></i></h5>
                                 <button type="submit" class="btn btn-primary ticket-once">
                                     {{__('Submit')}}
                                 </button>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
@@ -179,4 +181,3 @@ function escapeHtml(str) {
         });
     </script>
 @endsection
-
diff --git a/themes/default/views/admin/ticket/category.blade.php b/themes/default/views/admin/ticket/category.blade.php
index 42524285e..04414502e 100644
--- a/themes/default/views/admin/ticket/category.blade.php
+++ b/themes/default/views/admin/ticket/category.blade.php
@@ -57,7 +57,7 @@
                         </div>
                         <div class="card-body">
                             <form action="{{route("admin.ticket.category.store")}}" method="POST" class="ticket-form">
-                            @csrf
+                                @csrf
                                 <div class="form-group ">
                                     <label for="name" class="control-label">{{__("Name")}}</label>
                                     <input id="name" type="text" class="form-control" name="name" required>
@@ -65,6 +65,8 @@
                                 <button type="submit" class="btn btn-primary">
                                     {{__('Submit')}}
                                 </button>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
@@ -90,6 +92,8 @@
                                 <button type="submit" class="btn btn-primary">
                                     {{__('Submit')}}
                                 </button>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
@@ -129,4 +133,3 @@
 
     </script>
 @endsection
-
diff --git a/themes/default/views/admin/usefullinks/create.blade.php b/themes/default/views/admin/usefullinks/create.blade.php
index 2c09571a1..3eb63dc4b 100644
--- a/themes/default/views/admin/usefullinks/create.blade.php
+++ b/themes/default/views/admin/usefullinks/create.blade.php
@@ -34,7 +34,6 @@
                             <form action="{{route('admin.usefullinks.store')}}" method="POST">
                                 @csrf
 
-
                                 <div class="form-group">
                                     <label for="icon">{{__('Icon class name')}}</label>
                                     <input value="{{old('icon')}}" id="icon" name="icon"
@@ -117,6 +116,8 @@ class="form-control @error('description') is-invalid @enderror">
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/usefullinks/edit.blade.php b/themes/default/views/admin/usefullinks/edit.blade.php
index 72d8c9a69..acbfee4e3 100644
--- a/themes/default/views/admin/usefullinks/edit.blade.php
+++ b/themes/default/views/admin/usefullinks/edit.blade.php
@@ -118,6 +118,8 @@ class="form-control @error('description') is-invalid @enderror">
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/users/edit.blade.php b/themes/default/views/admin/users/edit.blade.php
index 221571918..a8a221ad8 100644
--- a/themes/default/views/admin/users/edit.blade.php
+++ b/themes/default/views/admin/users/edit.blade.php
@@ -106,7 +106,7 @@ class="custom-select @error('role') is-invalid @enderror"
                                                         @endif value="{{$role->id}}">{{$role->name}}</option>
                                             @endforeach
                                         </select>
-                            </div>
+                                    </div>
                                 </div>
                                     <div class="form-group">
                                         <label for="name">{{__('Referral-Code')}}</label>
@@ -118,15 +118,18 @@ class="form-control @error('referral_code') is-invalid @enderror" required="requ
                                         </div>
                                         @enderror
                                     </div>
-                            @error('role')
-                            <div class="text-danger">
-                                {{$message}}
-                                    </div>
-                                    @enderror
+                                @error('role')
+                                <div class="text-danger">
+                                    {{$message}}
+                                </div>
+                                @enderror
 
                                 <div class="form-group text-right">
                                     <button type="submit" class="btn btn-primary">{{__('Submit')}}</button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
+                            </form>
                         </div>
                     </div>
                 </div>
diff --git a/themes/default/views/admin/users/notifications.blade.php b/themes/default/views/admin/users/notifications.blade.php
index e29303add..13290c6f4 100644
--- a/themes/default/views/admin/users/notifications.blade.php
+++ b/themes/default/views/admin/users/notifications.blade.php
@@ -104,6 +104,8 @@ class="form-control @error('content') is-invalid @enderror">
                                 <div class="form-group text-right">
                                     <button type="submit" class="btn btn-primary">{{__('Submit')}}</button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/vouchers/create.blade.php b/themes/default/views/admin/vouchers/create.blade.php
index f5ba3591b..77a337f88 100644
--- a/themes/default/views/admin/vouchers/create.blade.php
+++ b/themes/default/views/admin/vouchers/create.blade.php
@@ -133,6 +133,8 @@ class="form-control @error('expires_at') is-invalid @enderror datetimepicker-inp
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/admin/vouchers/edit.blade.php b/themes/default/views/admin/vouchers/edit.blade.php
index 92cfd0369..d145d0a72 100644
--- a/themes/default/views/admin/vouchers/edit.blade.php
+++ b/themes/default/views/admin/vouchers/edit.blade.php
@@ -136,6 +136,8 @@ class="form-control @error('expires_at') is-invalid @enderror datetimepicker-inp
                                         {{__('Submit')}}
                                     </button>
                                 </div>
+
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </div>
diff --git a/themes/default/views/auth/login.blade.php b/themes/default/views/auth/login.blade.php
index c570550d9..323d03e41 100644
--- a/themes/default/views/auth/login.blade.php
+++ b/themes/default/views/auth/login.blade.php
@@ -93,6 +93,8 @@ class="form-control @error('password') is-invalid @enderror"
                             </div>
                             <!-- /.col -->
                         </div>
+
+                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                     </form>
                     <p class="mb-1">
                         @if (Route::has('password.request'))
diff --git a/themes/default/views/auth/passwords/confirm.blade.php b/themes/default/views/auth/passwords/confirm.blade.php
index ca78fc1d3..ec68ae653 100644
--- a/themes/default/views/auth/passwords/confirm.blade.php
+++ b/themes/default/views/auth/passwords/confirm.blade.php
@@ -40,6 +40,8 @@
                                 @endif
                             </div>
                         </div>
+
+                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                     </form>
                 </div>
             </div>
diff --git a/themes/default/views/auth/passwords/email.blade.php b/themes/default/views/auth/passwords/email.blade.php
index 216b7ce3e..40f1d6764 100644
--- a/themes/default/views/auth/passwords/email.blade.php
+++ b/themes/default/views/auth/passwords/email.blade.php
@@ -56,6 +56,7 @@ class="btn btn-primary btn-block">{{ __('Request new password') }}</button>
                             <!-- /.col -->
                         </div>
 
+                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                     </form>
                     <p class="mt-3 mb-1">
                         <a href="{{ route('login') }}">{{ __('Login') }}</a>
diff --git a/themes/default/views/auth/passwords/reset.blade.php b/themes/default/views/auth/passwords/reset.blade.php
index a2648b1d0..99b9f14d8 100644
--- a/themes/default/views/auth/passwords/reset.blade.php
+++ b/themes/default/views/auth/passwords/reset.blade.php
@@ -67,6 +67,8 @@ class="btn btn-primary btn-block">{{ __('Change password') }}</button>
                             </div>
                             <!-- /.col -->
                         </div>
+
+                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                     </form>
 
                     <p class="mt-3 mb-1">
diff --git a/themes/default/views/auth/register.blade.php b/themes/default/views/auth/register.blade.php
index 6386371e1..02acc2470 100644
--- a/themes/default/views/auth/register.blade.php
+++ b/themes/default/views/auth/register.blade.php
@@ -154,8 +154,10 @@ class="form-control  @error('email') is-invalid @enderror"
                             <button type="submit" class="btn btn-primary">{{ __('Register') }}</button>
                         </div>
                         <!-- /.col -->
-            </div>
-            </form>
+                    </div>
+
+                    <input type="hidden" name="_token" value="{{ csrf_token() }}">
+                </form>
             <a href="{{ route('login') }}" class="text-center">{{ __('I already have a membership') }}</a>
         </div>
         <!-- /.form-box -->
diff --git a/themes/default/views/auth/verify.blade.php b/themes/default/views/auth/verify.blade.php
index 9f8c1bc0f..521400148 100644
--- a/themes/default/views/auth/verify.blade.php
+++ b/themes/default/views/auth/verify.blade.php
@@ -19,6 +19,8 @@
                     <form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
                         @csrf
                         <button type="submit" class="btn btn-link p-0 m-0 align-baseline">{{ __('click here to request another') }}</button>.
+
+                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                     </form>
                 </div>
             </div>
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 9631ef64d..9a9b8022c 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -85,6 +85,7 @@ class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
                                     </button>
                                 @endforeach
 
+                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                             </form>
                         </div>
                     </li>
@@ -190,6 +191,8 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
                                 <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
                                 {{ __('Logout') }}
                             </button>
+
+                            <input type="hidden" name="_token" value="{{ csrf_token() }}">
                         </form>
                     </div>
                 </li>
diff --git a/themes/default/views/profile/index.blade.php b/themes/default/views/profile/index.blade.php
index 14117343d..628f8daf9 100644
--- a/themes/default/views/profile/index.blade.php
+++ b/themes/default/views/profile/index.blade.php
@@ -304,8 +304,9 @@ class="mr-1 fab fa-discord"></i>{{ __('Re-Sync Discord') }}
                             </div>
                         </div>
                     </div>
-                </form>
 
+                    <input type="hidden" name="_token" value="{{ csrf_token() }}">
+                </form>
 
             </div>
             <!-- END CUSTOM CONTENT -->
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 588da5a40..c4c30f020 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -258,6 +258,7 @@ class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
                     </div>
                 </div>
 
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
             <!-- END FORM -->
 
diff --git a/themes/default/views/servers/settings.blade.php b/themes/default/views/servers/settings.blade.php
index 7aba57d01..ae659be2b 100644
--- a/themes/default/views/servers/settings.blade.php
+++ b/themes/default/views/servers/settings.blade.php
@@ -269,10 +269,11 @@ class="btn btn-info btn-md">
 
                                           <br> <strong>{{__("Caution") }}:</strong> {{__("Upgrading/Downgrading your server will reset your billing cycle to now. Your overpayed Credits will be refunded. The price for the new billing cycle will be withdrawed")}}. <br>
                                           <br> {{__("Server will be automatically restarted once upgraded")}}
-                                    </div>
-                                    <div class="modal-footer card-body">
-                                        <button type="submit" class="btn btn-primary upgrade-once" style="width: 100%"><strong>{{__("Change Product")}}</strong></button>
-                                    </div>
+                                      </div>
+                                      <div class="modal-footer card-body">
+                                          <button type="submit" class="btn btn-primary upgrade-once" style="width: 100%"><strong>{{__("Change Product")}}</strong></button>
+                                      </div>
+                                      <input type="hidden" name="_token" value="{{ csrf_token() }}">
                                     </form>
                                 </div>
                             </div>
@@ -303,6 +304,7 @@ class="btn btn-danger btn-md">
                                   @csrf
                                   @method('DELETE')
                                   <button data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-danger mr-1">{{__("Delete")}}</button>
+                                  <input type="hidden" name="_token" value="{{ csrf_token() }}">
                                 </form>
                               </div>
                             </div>
diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index b0f91f0de..f1f836c55 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -223,6 +223,8 @@ class="text-muted d-inline-block">{{ strtolower($product->type) == 'credits' ? $
                         </div>
                     </div>
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
         </div>
 
diff --git a/themes/default/views/ticket/create.blade.php b/themes/default/views/ticket/create.blade.php
index c25b20e6b..a8e1b1a20 100644
--- a/themes/default/views/ticket/create.blade.php
+++ b/themes/default/views/ticket/create.blade.php
@@ -132,6 +132,8 @@
                         </div>
                     </div>
                 </div>
+
+                <input type="hidden" name="_token" value="{{ csrf_token() }}">
             </form>
         </div>
     </section>

From ab64fafbf2c30a0eaf0c8c33c15160af85654c95 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 17 May 2024 15:37:13 +0200
Subject: [PATCH 308/514] DELETE: unused / deprecated files

---
 .../default/views/admin/nests/index.blade.php | 100 ------------------
 .../default/views/admin/nodes/index.blade.php | 100 ------------------
 2 files changed, 200 deletions(-)
 delete mode 100644 themes/default/views/admin/nests/index.blade.php
 delete mode 100644 themes/default/views/admin/nodes/index.blade.php

diff --git a/themes/default/views/admin/nests/index.blade.php b/themes/default/views/admin/nests/index.blade.php
deleted file mode 100644
index 152773e48..000000000
--- a/themes/default/views/admin/nests/index.blade.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<!--
-THIS FILE IS DEPRECATED
- -->
-
-
-@extends('layouts.main')
-
-@section('content')
-    <!-- CONTENT HEADER -->
-    <section class="content-header">
-        <div class="container-fluid">
-            <div class="row mb-2">
-                <div class="col-sm-6">
-                    <h1>{{__('Nests')}}</h1>
-                </div>
-                <div class="col-sm-6">
-                    <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('admin.nests.index')}}">{{__('Nests')}}</a></li>
-                    </ol>
-                </div>
-            </div>
-        </div>
-    </section>
-    <!-- END CONTENT HEADER -->
-
-    <!-- MAIN CONTENT -->
-    <section class="content">
-        <div class="container-fluid">
-
-            <div class="card">
-
-                <div class="card-header">
-                    <div class="d-flex justify-content-between">
-                        <h5 class="card-title"><i class="fas fa-sitemap mr-2"></i>{{__('Nests')}}</h5>
-                        <a href="{{route('admin.nests.sync')}}" class="btn btn-sm btn-info"><i
-                                class="fas fa-sync mr-1"></i>{{__('Sync')}}</a>
-                    </div>
-                </div>
-
-                <div class="card-body table-responsive">
-
-                    <table id="datatable" class="table table-striped">
-                        <thead>
-                        <tr>
-                            <th>{{__('Active')}}</th>
-                            <th>{{__('ID')}}</th>
-                            <th>{{__('eggs')}}</th>
-                            <th>{{__('Name')}}</th>
-                            <th>{{__('Description')}}</th>
-                            <th>{{__('Created at')}}</th>
-
-                        </tr>
-                        </thead>
-                        <tbody>
-                        </tbody>
-                    </table>
-
-                </div>
-            </div>
-
-
-        </div>
-        <!-- END CUSTOM CONTENT -->
-
-    </section>
-    <!-- END CONTENT -->
-
-    <script>
-        function submitResult() {
-            return confirm({{__("Are you sure you wish to delete?")}}) !== false;
-        }
-
-        document.addEventListener("DOMContentLoaded", function () {
-            $('#datatable').DataTable({
-                language: {
-                    url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
-                },
-                processing: true,
-                serverSide: true,
-                stateSave: true,
-                ajax: "{{route('admin.nests.datatable')}}",
-                order: [[ 1, "desc" ]],
-                columns: [
-                    {data: 'actions', name : 'disabled'},
-                    {data: 'id'},
-                    {data: 'eggs' , sortable : false},
-                    {data: 'name' , name : 'nests.name'},
-                    {data: 'description'},
-                    {data: 'created_at'},
-
-                ]
-            });
-        });
-    </script>
-
-
-
-@endsection
diff --git a/themes/default/views/admin/nodes/index.blade.php b/themes/default/views/admin/nodes/index.blade.php
deleted file mode 100644
index bb57e0cee..000000000
--- a/themes/default/views/admin/nodes/index.blade.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<!--
-THIS FILE IS DEPRECATED
- -->
-
-
-@extends('layouts.main')
-
-@section('content')
-    <!-- CONTENT HEADER -->
-    <section class="content-header">
-        <div class="container-fluid">
-            <div class="row mb-2">
-                <div class="col-sm-6">
-                    <h1>{{__('Nodes')}}</h1>
-                </div>
-                <div class="col-sm-6">
-                    <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('admin.nodes.index')}}">{{__('Nodes')}}</a></li>
-                    </ol>
-                </div>
-            </div>
-        </div>
-    </section>
-    <!-- END CONTENT HEADER -->
-
-    <!-- MAIN CONTENT -->
-    <section class="content">
-        <div class="container-fluid">
-
-            <div class="card">
-
-                <div class="card-header">
-                    <div class="d-flex justify-content-between">
-                        <h5 class="card-title"><i class="fas fa-sitemap mr-2"></i>{{__('Nodes')}}</h5>
-                        <a href="{{route('admin.nodes.sync')}}" class="btn btn-sm btn-info"><i
-                                class="fas fa-sync mr-1"></i>{{__('Sync')}}</a>
-                    </div>
-                </div>
-
-                <div class="card-body table-responsive">
-
-                    <table id="datatable" class="table table-striped">
-                        <thead>
-                        <tr>
-                            <th>{{__('Active')}}</th>
-                            <th>{{__('ID')}}</th>
-                            <th>{{__('Location')}}</th>
-                            <th>{{__('Name')}}</th>
-                            <th>{{__('Description')}}</th>
-                            <th>{{__('Created at')}}</th>
-
-                        </tr>
-                        </thead>
-                        <tbody>
-                        </tbody>
-                    </table>
-
-                </div>
-            </div>
-
-
-        </div>
-        <!-- END CUSTOM CONTENT -->
-
-    </section>
-    <!-- END CONTENT -->
-
-    <script>
-        function submitResult() {
-            return confirm({{__("Are you sure you wish to delete?")}}) !== false;
-        }
-
-        document.addEventListener("DOMContentLoaded", function () {
-            $('#datatable').DataTable({
-                language: {
-                    url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
-                },
-                processing: true,
-                serverSide: true,
-                stateSave: true,
-                ajax: "{{route('admin.nodes.datatable')}}",
-                order: [[ 1, "desc" ]],
-                columns: [
-                    {data: 'actions', name : 'disabled'},
-                    {data: 'id'},
-                    {data: 'location' , name : 'location.name'},
-                    {data: 'name' , name : 'nodes.name'},
-                    {data: 'description'},
-                    {data: 'created_at'},
-
-                ]
-            });
-        });
-    </script>
-
-
-
-@endsection

From be6c5d7addc299edde2e45d46d9d85ba44e69427 Mon Sep 17 00:00:00 2001
From: Vikas Dongre <zvikasdongre@gmail.com>
Date: Mon, 20 May 2024 18:10:22 +0530
Subject: [PATCH 309/514] fix: pterodactyl settings not getting encrypted
 during installation Also fixes minor issues like spelling / sentence
 mistakes. Refactored some variable names, and made it actually show error
 message on the page instead of only in logs. Now email settings have select
 input for mail method and encryption.

---
 app/Console/Commands/GetSettingCommand.php | 49 +++++++++++++
 app/Console/Commands/SetSettingCommand.php | 52 ++++++++++++++
 public/install/forms.php                   | 84 +++++++++++-----------
 public/install/index.php                   | 58 +++++++++------
 4 files changed, 176 insertions(+), 67 deletions(-)
 create mode 100644 app/Console/Commands/GetSettingCommand.php
 create mode 100644 app/Console/Commands/SetSettingCommand.php

diff --git a/app/Console/Commands/GetSettingCommand.php b/app/Console/Commands/GetSettingCommand.php
new file mode 100644
index 000000000..9be2191ad
--- /dev/null
+++ b/app/Console/Commands/GetSettingCommand.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+
+class GetSettingCommand extends Command
+{
+  /**
+   * The name and signature of the console command.
+   *
+   * @var string
+   */
+  protected $signature = 'settings:get {class : Settings Class (Example: GeneralSettings)} {key} {--sameline : Outputs the result without newline, useful for implementing in scripts.}';
+
+  /**
+   * The console command description.
+   *
+   * @var string
+   */
+  protected $description = 'Gets value of a setting key and decrypts it if needed.';
+
+  /**
+   * Execute the console command.
+   *
+   * @return int
+   */
+  public function handle()
+  {
+
+    $class = $this->argument('class');
+    $key = $this->argument('key');
+    $sameline = $this->option('sameline');
+
+    try {
+      $settings_class = "App\\Settings\\$class";
+      $settings = new $settings_class();
+
+      $this->output->write($settings->$key, !$sameline);
+
+      return Command::SUCCESS;
+    } catch (\Throwable $th) {
+      $this->error('Error: ' . $th->getMessage());
+      return Command::FAILURE;
+    }
+
+    return Command::SUCCESS;
+  }
+}
diff --git a/app/Console/Commands/SetSettingCommand.php b/app/Console/Commands/SetSettingCommand.php
new file mode 100644
index 000000000..03481f93e
--- /dev/null
+++ b/app/Console/Commands/SetSettingCommand.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Exception;
+use Illuminate\Console\Command;
+
+class SetSettingCommand extends Command
+{
+  /**
+   * The name and signature of the console command.
+   *
+   * @var string
+   */
+  protected $signature = 'settings:set {class : Settings Class (Example: GeneralSettings)} {key : Unique setting key} {value : Value to set}';
+
+  /**
+   * The console command description.
+   *
+   * @var string
+   */
+  protected $description = 'Set value of a setting key.';
+
+  /**
+   * Execute the console command.
+   *
+   * @return int
+   */
+  public function handle()
+  {
+
+    $class = $this->argument('class');
+    $key = $this->argument('key');
+    $value = $this->argument('value');
+
+    try {
+      $settings_class = "App\\Settings\\$class";
+      $settings = new $settings_class();
+
+      $settings->$key = $value;
+
+      $settings->save();
+
+      $this->info("Successfully updated '$key'.");
+    } catch (\Throwable $th) {
+      $this->error('Error: ' . $th->getMessage());
+      return Command::FAILURE;
+    }
+
+    return Command::SUCCESS;
+  }
+}
diff --git a/public/install/forms.php b/public/install/forms.php
index 96f1dfa17..9bed6eda2 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -97,27 +97,30 @@
         $mail = new PHPMailer(true);
 
         //Server settings
-        $mail->isSMTP();                                            // Send using SMTP
-        $mail->Host = $_POST['host'];                    // Set the SMTP server to send through
-        $mail->SMTPAuth = true;                                   // Enable SMTP authentication
-        $mail->Username = $_POST['user'];                     // SMTP username
-        $mail->Password = $_POST['pass'];                               // SMTP password
-        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;         // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
-        $mail->Port = $_POST['port'];                                    // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS`
-
-        //Recipients
+        // Send using SMTP
+        $mail->isSMTP();
+        $mail->Host = $_POST['host'];
+        // Enable SMTP authentication
+        $mail->SMTPAuth = true;
+        $mail->Username = $_POST['user'];
+        $mail->Password = $_POST['pass'];
+        $mail->SMTPSecure = $_POST['encryption'];
+        $mail->Port = (int) $_POST['port'];
+
+        // Test E-mail metadata
         $mail->setFrom($_POST['user'], $_POST['user']);
-        $mail->addAddress($_POST['user'], $_POST['user']);     // Add a recipient
+        $mail->addAddress($_POST['user'], $_POST['user']);
 
         // Content
-        $mail->isHTML(true);                                  // Set email format to HTML
-        $mail->Subject = 'It Worked!';
+        // Set email format to HTML
+        $mail->isHTML(true);
+        $mail->Subject = 'It Worked! - Test E-Mail from Ctrlpanel.gg';
         $mail->Body = 'Your E-Mail Settings are correct!';
 
         $mail->send();
     } catch (Exception $e) {
         wh_log($mail->ErrorInfo, 'error');
-        header('LOCATION: index.php?step=4&message=Something wasnt right when sending the E-Mail!');
+        header('LOCATION: index.php?step=4&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
         exit();
     }
 
@@ -140,8 +143,7 @@
     ];
 
     foreach ($values as $key => $value) {
-        $query = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '$value' WHERE `name` = '$key' AND `group` = 'mail'";
-        $db->query($query);
+        run_console("php artisan settings:set 'MailSettings' '$key' '$value'");
     }
 
     wh_log('Database updated', 'debug');
@@ -197,34 +199,22 @@
         exit();
     } else {
         wh_log('Pterodactyl Settings are correct', 'debug');
-        wh_log('Updating Database', 'debug');
 
-        $key = $key;
-        $clientkey = $clientkey;
-
-        $query1 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($url) . "' WHERE (`name` = 'panel_url' AND `group` = 'pterodactyl')";
-        $query2 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($key) . "' WHERE (`name` = 'admin_token' AND `group` = 'pterodactyl')";
-        $query3 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($clientkey) . "' WHERE (`name` = 'user_token' AND `group` = 'pterodactyl')";
-
-        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
-        if ($db->connect_error) {
-            wh_log($db->connect_error, 'error');
-            header('LOCATION: index.php?step=5&message=Could not connect to the Database');
-            exit();
-        }
-
-        if ($db->query($query1) && $db->query($query2) && $db->query($query3)) {
+        try {
+            run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
+            run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
+            run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
             wh_log('Database updated', 'debug');
             header('LOCATION: index.php?step=6');
-        } else {
-            wh_log($db->error, 'error');
-            header('LOCATION: index.php?step=5&message=Something went wrong when communicating with the Database!');
+        } catch (\Throwable $th) {
+            wh_log("Setting Pterodactyl information failed.", 'error');
+            header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
         }
     }
 }
 
 if (isset($_POST['createUser'])) {
-    wh_log('Creating User', 'debug');
+    wh_log('Getting Pterodactyl User', 'debug');
     $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
     if ($db->connect_error) {
         wh_log($db->connect_error, 'error');
@@ -236,19 +226,26 @@
     $pass = $_POST['pass'];
     $repass = $_POST['repass'];
 
-    $key = $db->query('SELECT `payload` FROM `' . getenv('DB_DATABASE') . "`.`settings` WHERE `name` = 'admin_token' AND `group` = 'pterodactyl'")->fetch_assoc();
-    $key = removeQuotes($key['payload']);
-    $pterobaseurl = $db->query('SELECT `payload` FROM `' . getenv('DB_DATABASE') . "`.`settings` WHERE `name` = 'panel_url' AND `group` = 'pterodactyl'")->fetch_assoc();
+    try {
+        $panel_url = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
+        $admin_token = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
+        wh_log('Database updated', 'debug');
+        header('LOCATION: index.php?step=6');
+    } catch (\Throwable $th) {
+        wh_log("Getting Pterodactyl information failed.", 'error');
+        header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+    }
+
+    $panel_api_url = $panel_url . '/api/application/users/' . $pteroID;
 
-    $pteroURL = removeQuotes($pterobaseurl['payload']) . '/api/application/users/' . $pteroID;
     $ch = curl_init();
 
-    curl_setopt($ch, CURLOPT_URL, $pteroURL);
+    curl_setopt($ch, CURLOPT_URL, $panel_api_url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer ' . $key,
+        'Authorization: Bearer ' . $admin_token,
     ]);
     $response = curl_exec($ch);
     $result = json_decode($response, true);
@@ -267,15 +264,14 @@
     $name = $result['attributes']['username'];
     $pass = password_hash($pass, PASSWORD_DEFAULT);
 
-    $pteroURL = removeQuotes($pterobaseurl['payload']) . '/api/application/users/' . $pteroID;
     $ch = curl_init();
 
-    curl_setopt($ch, CURLOPT_URL, $pteroURL);
+    curl_setopt($ch, CURLOPT_URL, $panel_api_url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer ' . $key,
+        'Authorization: Bearer ' . $admin_token,
     ]);
     curl_setopt($ch, CURLOPT_POSTFIELDS, [
         'email' => $mail,
diff --git a/public/install/index.php b/public/install/index.php
index 6afd2e70c..8d63f71d9 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -76,29 +76,36 @@ function cardStart($title, $subtitle = null)
 
             <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
 
-            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> php
-                version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)</li>
+            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+            </li>
 
-            <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> mysql
-                version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)</li>
+            <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
+            </li>
 
-            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check"> Missing
-                php-extentions: <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-                                foreach (checkExtensions() as $ext) {
-                                    echo $ext . ', ';
-                                }
-
-                                echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?></li>
+            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+                Missing php-extentions:
+                <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+                foreach (checkExtensions() as $ext) {
+                    echo $ext . ', ';
+                }
+                echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
+            </li>
 
 
             <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
                     version: <?php echo getZipVersion(); ?> </li> -->
 
-            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Git
-                version: <?php echo getGitVersion(); ?> </li>
+            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                Git version:
+                <?php echo getGitVersion(); ?>
+            </li>
 
-            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Tar
-                version: <?php echo getTarVersion(); ?> </li>
+            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                Tar version:
+                <?php echo getTarVersion(); ?>
+            </li>
         </ul>
 
         </div>
@@ -143,7 +150,7 @@ function cardStart($title, $subtitle = null)
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
                             <label for="databaseuser">Database User</label>
-                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="controlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">
@@ -156,7 +163,7 @@ function cardStart($title, $subtitle = null)
                     <div class="form-group">
                         <div class="flex flex-col">
                             <label for="database">Database</label>
-                            <input x-model="database" id="database" name="database" type="text" required value="controlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
 
@@ -213,8 +220,8 @@ function cardStart($title, $subtitle = null)
                         </div>
                         <div class="form-group">
                             <div class="flex flex-col">
-                                <label for="name">Host Name</label>
-                                <input id="name" name="name" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <label for="name">Dashboard Name</label>
+                                <input id="name" name="name" type="text" required value="CtrlPanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                             </div>
                         </div>
 
@@ -248,8 +255,9 @@ function cardStart($title, $subtitle = null)
                         <div class="form-group">
                             <div class="flex flex-col mb-3">
                                 <label for="method">Your E-Mail Method</label>
-                                <input id="method" name="method" type="text" required value="smtp" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-
+                                <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                    <option value="smtp" selected>SMTP</option>
+                                </select>
                             </div>
                         </div>
                         <div class="form-group">
@@ -284,7 +292,11 @@ function cardStart($title, $subtitle = null)
                         <div class="form-group">
                             <div class="flex flex-col">
                                 <label for="encryption">Your Mail encryption method</label>
-                                <input id="encryption" name="encryption" type="text" required value="tls" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                    <option value="tls" selected>TLS</option>
+                                    <option value="ssl">SSL</option>
+                                    <option value="null">None</option>
+                                </select>
                             </div>
                         </div>
 
@@ -431,4 +443,4 @@ function cardStart($title, $subtitle = null)
         ?>
 </body>
 
-</html>
+</html>
\ No newline at end of file

From 487fbe0427de5f607f7f99856dbfc43e4dad3cd7 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 22 May 2024 11:25:39 +0200
Subject: [PATCH 310/514] Should fix ticket 429 too many requests

---
 .gitignore                                 |  3 +++
 app/Http/Controllers/TicketsController.php | 11 ++++++++++-
 routes/web.php                             |  4 ++--
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index f72249a83..0d6b6034b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,6 @@ Homestead.yaml
 public/install/logs.txt
 install.lock
 public/install/logs/installer.log
+
+/.idea
+cpggdatabase.sql
diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index de59bf883..d55516fca 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -17,6 +17,7 @@
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Notification;
+use Illuminate\Support\Facades\RateLimiter;
 use Illuminate\Support\Str;
 
 class TicketsController extends Controller
@@ -35,6 +36,9 @@ public function index(LocaleSettings $locale_settings, TicketSettings $ticketSet
 
     public function store(Request $request, TicketSettings $ticket_settings)
     {
+        if (RateLimiter::tooManyAttempts('ticket-send:'.Auth::user()->id, $perMinute = 1)) {
+            return redirect()->back()->with('error', __('Please wait before creating a new Ticket'));
+        }
         $this->validate(
             $request,
             [
@@ -67,6 +71,7 @@ public function store(Request $request, TicketSettings $ticket_settings)
 
 
         $user->notify(new CreateNotification($ticket));
+        RateLimiter::hit('ticket-send:'.Auth::user()->id);
 
         return redirect()->route('ticket.index')->with('success', __('A ticket has been opened, ID: #') . $ticket->ticket_id);
     }
@@ -89,6 +94,9 @@ public function show($ticket_id, PterodactylSettings $ptero_settings)
 
     public function reply(Request $request)
     {
+        if (RateLimiter::tooManyAttempts('ticket-reply:'.Auth::user()->id, $perMinute = 1)) {
+            return redirect()->back()->with('error', __('Please wait before answering a Ticket'));
+        }
         //check in blacklist
         $check = TicketBlacklist::where('user_id', Auth::user()->id)->first();
         if ($check && $check->status == 'True') {
@@ -101,6 +109,7 @@ public function reply(Request $request)
             return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
         }
         $ticket->status = 'Client Reply';
+        $ticket->updated_at = now();
         $ticket->update();
         $ticketcomment = TicketComment::create([
             'ticket_id' => $request->input('ticket_id'),
@@ -115,7 +124,7 @@ public function reply(Request $request)
         foreach($staffNotify as $staff){
             Notification::send($staff, new AdminReplyNotification($ticket, $user, $newmessage));
         }
-
+        RateLimiter::hit('ticket-reply:'.Auth::user()->id);
         return redirect()->back()->with('success', __('Your comment has been submitted'));
     }
 
diff --git a/routes/web.php b/routes/web.php
index c575ea981..f5078e3c1 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -119,9 +119,9 @@
     Route::get('ticket', [TicketsController::class, 'index'])->name('ticket.index');
     Route::get('ticket/datatable', [TicketsController::class, 'datatable'])->name('ticket.datatable');
     Route::get('ticket/new', [TicketsController::class, 'create'])->name('ticket.new');
-    Route::post('ticket/new', [TicketsController::class, 'store'])->middleware(['throttle:ticket-new'])->name('ticket.new.store');
+    Route::post('ticket/new', [TicketsController::class, 'store'])->name('ticket.new.store');
     Route::get('ticket/show/{ticket_id}', [TicketsController::class, 'show'])->name('ticket.show');
-    Route::post('ticket/reply', [TicketsController::class, 'reply'])->middleware(['throttle:ticket-reply'])->name('ticket.reply');
+    Route::post('ticket/reply', [TicketsController::class, 'reply'])->name('ticket.reply');
     Route::post('ticket/status/{ticket_id}', [TicketsController::class, 'changeStatus'])->name('ticket.changeStatus');
 
 

From eeabc162876f82a283fca40f35538aad273c2323 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Wed, 22 May 2024 14:24:33 +0200
Subject: [PATCH 311/514] FIX: recaptcha error wen creating a tickets

---
 app/Http/Controllers/TicketsController.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index d55516fca..c2c9d14d4 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -34,7 +34,7 @@ public function index(LocaleSettings $locale_settings, TicketSettings $ticketSet
         ]);
     }
 
-    public function store(Request $request, TicketSettings $ticket_settings)
+    public function store(Request $request, TicketSettings $ticket_settings, GeneralSettings $generalSettings)
     {
         if (RateLimiter::tooManyAttempts('ticket-send:'.Auth::user()->id, $perMinute = 1)) {
             return redirect()->back()->with('error', __('Please wait before creating a new Ticket'));
@@ -46,7 +46,7 @@ public function store(Request $request, TicketSettings $ticket_settings)
                 'ticketcategory' => 'required',
                 'priority' => 'required',
                 'message' => 'required',
-                'g-recaptcha-response' => ['required', 'recaptcha'],
+                'g-recaptcha-response' => [$generalSettings->recaptcha_enabled ? 'required' : null, 'recaptcha'],
             ]
         );
         $ticket = new Ticket(

From 130a3b308b80fb06548ac2c65464e3a4ff0248b6 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Wed, 22 May 2024 14:26:18 +0200
Subject: [PATCH 312/514] [Feature] Addon implemented

---
 app/Http/Controllers/ProductController.php    | 31 +++++++---
 app/Http/Controllers/ServerController.php     | 59 +++++++++++++-----
 lang/en.json                                  |  2 +-
 routes/web.php                                |  2 +-
 themes/default/views/servers/create.blade.php | 61 ++++++++-----------
 5 files changed, 95 insertions(+), 60 deletions(-)

diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php
index 5f3d94dc1..ae9c1548c 100644
--- a/app/Http/Controllers/ProductController.php
+++ b/app/Http/Controllers/ProductController.php
@@ -14,7 +14,7 @@
 use Illuminate\Support\Collection;
 
 class ProductController extends Controller
-{   
+{
     private $pterodactyl;
 
     public function __construct(PterodactylSettings $ptero_settings)
@@ -97,30 +97,41 @@ public function getLocationsBasedOnEgg(Request $request, Egg $egg)
     }
 
     /**
-     * @param  Node  $node
+     * @param  Int $location
      * @param  Egg  $egg
      * @return Collection|JsonResponse
      */
-    public function getProductsBasedOnNode(Egg $egg, Node $node)
+    public function getProductsBasedOnLocation(Egg $egg, Int $location)
     {
-        if (is_null($egg->id) || is_null($node->id)) {
-            return response()->json('node and egg id is required', '400');
+        if (is_null($egg->id) || is_null($location)) {
+            return response()->json('location and egg id is required', '400');
         }
 
+        // Get all nodes in this location
+        $nodes = Node::query()
+            ->where('location_id', '=', $location)
+            ->get();
+
         $products = Product::query()
             ->where('disabled', '=', false)
-            ->whereHas('nodes', function (Builder $builder) use ($node) {
-                $builder->where('id', '=', $node->id);
+            ->whereHas('nodes', function (Builder $builder) use ($nodes) {
+                $builder->whereIn('id', $nodes->map(function ($node) {
+                    return $node->id;
+                }));
             })
             ->whereHas('eggs', function (Builder $builder) use ($egg) {
                 $builder->where('id', '=', $egg->id);
             })
             ->get();
 
-        $pteroNode = $this->pterodactyl->getNode($node->id);
+        // Instead of the old node check, we will check if the product fits in any given node in the location
         foreach ($products as $key => $product) {
-            if ($product->memory > ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['memory'] || $product->disk > ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['disk']) {
-                $product->doesNotFit = true;
+            $product->doesNotFit = false;
+            foreach ($nodes as $node) {
+                $pteroNode = $this->pterodactyl->getNode($node->id);
+                if ($product->memory > ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['memory'] || $product->disk > ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['disk']) {
+                    $product->doesNotFit = true;
+                }
             }
         }
 
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 0c18a5084..a6cd1b9a8 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -141,13 +141,10 @@ private function validateConfigurationRules(UserSettings $user_settings, ServerS
             $product = Product::findOrFail(FacadesRequest::input('product'));
 
             // Get node resource allocation info
-            $node = $product->nodes()->findOrFail(FacadesRequest::input('node'));
-            $nodeName = $node->name;
-
-            // Check if node has enough memory and disk space
-            $checkResponse = $this->pterodactyl->checkNodeResources($node, $product->memory, $product->disk);
-            if ($checkResponse == false) {
-                return redirect()->route('servers.index')->with('error', __("The node '" . $nodeName . "' doesn't have the required memory or disk left to allocate this product."));
+            $location = FacadesRequest::input('location');
+            $availableNode = $this->getAvailableNode($location, $product);
+            if (!$availableNode) {
+                return redirect()->route('servers.index')->with('error', __("The chosen location doesn't have the required memory or disk left to allocate this product."));
             }
 
             // Min. Credits
@@ -179,7 +176,7 @@ private function validateConfigurationRules(UserSettings $user_settings, ServerS
     /** Store a newly created resource in storage. */
     public function store(Request $request, UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $generalSettings)
     {
-        /** @var Node $node */
+        /** @var Location $location */
         /** @var Egg $egg */
         /** @var Product $product */
         $validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings, $generalSettings);
@@ -190,15 +187,23 @@ public function store(Request $request, UserSettings $user_settings, ServerSetti
 
         $request->validate([
             'name' => 'required|max:191',
-            'node' => 'required|exists:nodes,id',
+            'location' => 'required|exists:locations,id',
             'egg' => 'required|exists:eggs,id',
             'product' => 'required|exists:products,id',
         ]);
 
-        //get required resources
+        // Get the product and egg
         $product = Product::query()->findOrFail($request->input('product'));
         $egg = $product->eggs()->findOrFail($request->input('egg'));
-        $node = $product->nodes()->findOrFail($request->input('node'));
+
+        // Get an available node
+        $location = $request->input('location');
+        $availableNode = $this->getAvailableNode($location, $product);
+        $node = Node::query()->find($availableNode);
+
+        if(!$node) {
+            return redirect()->route('servers.index')->with('error', __("No nodes satisfying the requirements for automatic deployment on this location were found."));
+        }
 
         $server = $request->user()->servers()->create([
             'name' => $request->input('name'),
@@ -316,7 +321,7 @@ public function show(Server $server, ServerSettings $server_settings, GeneralSet
             })
             ->get();
 
-        // Set the each product eggs array to just contain the eggs name
+        // Set each product eggs array to just contain the eggs name
         foreach ($products as $product) {
             $product->eggs = $product->eggs->pluck('name')->toArray();
             if ($product->memory - $currentProduct->memory > ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['memory'] || $product->disk - $currentProduct->disk > ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['disk']) {
@@ -356,8 +361,8 @@ public function upgrade(Server $server, Request $request)
         // Check if node has enough memory and disk space
         $requireMemory = $newProduct->memory - $oldProduct->memory;
         $requiredisk = $newProduct->disk - $oldProduct->disk;
-        $checkResponse = $this->pterodactyl->checkNodeResources($node, $requireMemory, $requiredisk);
-        if ($checkResponse == false) {
+        $nodeFree = $this->pterodactyl->checkNodeResources($node, $requireMemory, $requiredisk);
+        if (!$nodeFree) {
             return redirect()->route('servers.index')->with('error', __("The node '" . $nodeName . "' doesn't have the required memory or disk left to upgrade the server."));
         }
 
@@ -412,4 +417,30 @@ public function upgrade(Server $server, Request $request)
             return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('Not Enough Balance for Upgrade'));
         }
     }
+
+    /**
+     * @param string $location
+     * @param Product $product
+     * @return int | null Node ID
+     */
+    private function getAvailableNode(string $location, Product $product)
+    {
+        $collection = Node::query()->where('location_id', $location)->get();
+
+        // loop through nodes and check if the node has enough resources
+        foreach ($collection as $node) {
+            // Check if the node has enough memory and disk space
+            $freeNode = $this->pterodactyl->checkNodeResources($node, $product->memory, $product->disk);
+            // Remove the node from the collection if it doesn't have enough resources
+            if (!$freeNode) {
+                $collection->forget($node['id']);
+            }
+        }
+
+        if($collection->isEmpty()) {
+            return null;
+        }
+
+        return $collection->first()['id'];
+    }
 }
diff --git a/lang/en.json b/lang/en.json
index 633a4ec2c..91da6df34 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -71,7 +71,7 @@
     "Change Status": "Change Status",
     "Profile updated": "Profile updated",
     "Server limit reached!": "Server limit reached!",
-    "The node '\" . $nodeName . \"' doesn't have the required memory or disk left to allocate this product.": "The node '\" . $nodeName . \"' doesn't have the required memory or disk left to allocate this product.",
+    "The chosen location doesn't have the required memory or disk left to allocate this product.": "The chosen location doesn't have the required memory or disk left to allocate this product.",
     "You are required to verify your email address before you can create a server.": "You are required to verify your email address before you can create a server.",
     "You are required to link your discord account before you can create a server.": "You are required to link your discord account before you can create a server.",
     "Server created": "Server created",
diff --git a/routes/web.php b/routes/web.php
index c575ea981..444d9485b 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -95,7 +95,7 @@
     //routes made for server create page to fetch product info
     Route::get('/products/nodes/egg/{egg?}', [FrontProductController::class, 'getNodesBasedOnEgg'])->name('products.nodes.egg');
     Route::get('/products/locations/egg/{egg?}', [FrontProductController::class, 'getLocationsBasedOnEgg'])->name('products.locations.egg');
-    Route::get('/products/products/{egg?}/{node?}', [FrontProductController::class, 'getProductsBasedOnNode'])->name('products.products.node');
+    Route::get('/products/products/{egg?}/{location?}', [FrontProductController::class, 'getProductsBasedOnLocation'])->name('products.products.location');
 
     //payments
     Route::get('checkout/{shopProduct}', [PaymentController::class, 'checkOut'])->name('checkout');
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 588da5a40..4dfadea55 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -133,32 +133,25 @@ class="custom-select">
                                 </div>
                             </div>
 
-                            <div class="form-group">
-                                <label for="node">{{ __('Node') }}</label>
-                                <select name="node" required id="node" x-model="selectedNode"
-                                    :disabled="!fetchedLocations" @change="fetchProducts();" class="custom-select">
-                                    <option x-text="getNodeInputText()" disabled selected hidden value="null">
+                              <div class="form-group">
+                                <label for="location">{{ __('Location') }}</label>
+                                <select name="location" required id="location" x-model="selectedLocation" :disabled="!fetchedLocations"
+                                        @change="fetchProducts();" class="custom-select">
+                                  <option x-text="getLocationInputText()" disabled selected hidden value="null">
+                                  </option>
+
+                                  <template x-for="location in locations" :key="location.id">
+                                    <option x-text="location.name" :value="location.id">
                                     </option>
-
-                                    <template x-for="location in locations" :key="location.id">
-                                        <optgroup :label="location.name">
-
-                                            <template x-for="node in location.nodes" :key="node.id">
-                                                <option x-text="node.name" :value="node.id">
-
-                                                </option>
-                                            </template>
-                                        </optgroup>
-                                    </template>
-
+                                  </template>
                                 </select>
-                            </div>
+                              </div>
                         </div>
                     </div>
                 </div>
 
                 <div class="w-100"></div>
-                <div class="col" x-show="selectedNode != null">
+                <div class="col" x-show="selectedLocation != null">
                     <div class="row mt-4 justify-content-center">
                         <template x-for="product in products" :key="product.id">
                             <div class="card  col-xl-3 col-lg-3 col-md-4 col-sm-10 mr-2 ml-2 ">
@@ -248,7 +241,7 @@ class="custom-select">
                                                 product.doesNotFit == true ||
                                                 submitClicked ? 'disabled' : ''"
                                             class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
-                                            x-text="product.doesNotFit == true ? '{{ __('Server cant fit on this Node') }}' : (product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ $credits_display_name }}!' : '{{ __('Create server') }}')">
+                                            x-text="product.doesNotFit == true ? '{{ __('Server cant fit on this Location') }}' : (product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ $credits_display_name }}!' : '{{ __('Create server') }}')">
                                         </button>
                                     </div>
 
@@ -278,13 +271,13 @@ function serverApp() {
                 name: null,
                 selectedNest: null,
                 selectedEgg: null,
-                selectedNode: null,
+                selectedLocation: null,
                 selectedProduct: null,
 
                 //selected objects based on input
                 selectedNestObject: {},
                 selectedEggObject: {},
-                selectedNodeObject: {},
+                selectedLocationObject: {},
                 selectedProductObject: {},
 
                 //values
@@ -309,7 +302,7 @@ function serverApp() {
                     this.locations = [];
                     this.products = [];
                     this.selectedEgg = 'null';
-                    this.selectedNode = 'null';
+                    this.selectedLocation = 'null';
                     this.selectedProduct = 'null';
 
                     this.eggs = this.eggsSave.filter(egg => egg.nest_id == this.selectedNest)
@@ -343,7 +336,7 @@ function serverApp() {
                     this.fetchedProducts = false;
                     this.locations = [];
                     this.products = [];
-                    this.selectedNode = 'null';
+                    this.selectedLocation = 'null';
                     this.selectedProduct = 'null';
 
                     let response = await axios.get(`{{ route('products.locations.egg') }}/${this.selectedEgg}`)
@@ -354,7 +347,7 @@ function serverApp() {
 
                     //automatically select the first entry if there is only 1
                     if (this.locations.length === 1 && this.locations[0]?.nodes?.length === 1) {
-                        this.selectedNode = this.locations[0]?.nodes[0]?.id;
+                        this.selectedLocation = this.locations[0]?.id;
                         await this.fetchProducts();
                         return;
                     }
@@ -366,7 +359,7 @@ function serverApp() {
                 /**
                  * @description fetch all available products based on the selected node
                  * @note called whenever a node is selected
-                 * @see selectedNode
+                 * @see selectedLocation
                  */
                 async fetchProducts() {
                     this.loading = true;
@@ -375,7 +368,7 @@ function serverApp() {
                     this.selectedProduct = 'null';
 
                     let response = await axios.get(
-                            `{{ route('products.products.node') }}/${this.selectedEgg}/${this.selectedNode}`)
+                            `{{ route('products.products.location') }}/${this.selectedEgg}/${this.selectedLocation}`)
                         .catch(console.error)
 
                     this.fetchedProducts = true;
@@ -410,10 +403,10 @@ function serverApp() {
                     this.selectedNestObject = this.nests.find(nest => nest.id == this.selectedNest) ?? {}
                     this.selectedEggObject = this.eggs.find(egg => egg.id == this.selectedEgg) ?? {}
 
-                    this.selectedNodeObject = {};
+                    this.selectedLocationObject = {};
                     this.locations.forEach(location => {
-                        if (!this.selectedNodeObject?.id) {
-                            this.selectedNodeObject = location.nodes.find(node => node.id == this.selectedNode) ??
+                        if (!this.selectedLocationObject?.id) {
+                            this.selectedLocationObject = location.nodes.find(node => node.id == this.selectedLocation) ??
                                 {};
                         }
                     })
@@ -429,17 +422,17 @@ function serverApp() {
                 isFormValid() {
                     if (Object.keys(this.selectedNestObject).length === 0) return false;
                     if (Object.keys(this.selectedEggObject).length === 0) return false;
-                    if (Object.keys(this.selectedNodeObject).length === 0) return false;
+                    if (Object.keys(this.selectedLocationObject).length === 0) return false;
                     if (Object.keys(this.selectedProductObject).length === 0) return false;
                     return !!this.name;
                 },
 
-                getNodeInputText() {
+                getLocationInputText() {
                     if (this.fetchedLocations) {
                         if (this.locations.length > 0) {
-                            return '{{ __('Please select a node ...') }}';
+                            return '{{ __('Please select a location ...') }}';
                         }
-                        return '{{ __('No nodes found matching current configuration') }}'
+                        return '{{ __('No location found matching current configuration') }}'
                     }
                     return '{{ __('---') }}';
                 },

From ca3d1b00a0acb52e7ba7f9f1e2cfb576f5c1ae00 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Wed, 22 May 2024 15:02:28 +0200
Subject: [PATCH 313/514] [Feat] Language additions [Bug] ControlPanel
 leftovers changed to CtrlPanel

---
 .github/ISSUE_TEMPLATE/bug.yml                   |  6 +++---
 .github/SECURITY.md                              |  4 ++--
 app/Http/Controllers/ServerController.php        |  2 +-
 app/Traits/Invoiceable.php                       |  2 +-
 docker/README.md                                 |  6 +++---
 docker/docker-compose.yml                        | 16 ++++++++--------
 lang/bg.json                                     |  2 +-
 lang/bs.json                                     |  2 +-
 lang/cs.json                                     |  2 +-
 lang/de.json                                     |  2 +-
 lang/en.json                                     |  4 ++--
 lang/es.json                                     |  2 +-
 lang/fr.json                                     |  2 +-
 lang/he.json                                     |  2 +-
 lang/hi.json                                     |  2 +-
 lang/hu.json                                     |  2 +-
 lang/it.json                                     |  2 +-
 lang/nl.json                                     |  2 +-
 lang/pl.json                                     |  2 +-
 lang/pt.json                                     |  2 +-
 lang/ro.json                                     |  2 +-
 lang/ru.json                                     |  2 +-
 lang/sh.json                                     |  2 +-
 lang/sk.json                                     |  2 +-
 lang/sr.json                                     |  2 +-
 lang/sv.json                                     |  2 +-
 lang/tr.json                                     |  2 +-
 lang/zh.json                                     |  2 +-
 package-lock.json                                |  2 +-
 phpunit.xml                                      |  2 +-
 public/install/forms.php                         |  2 +-
 public/install/functions.php                     |  2 +-
 public/install/index.php                         |  4 ++--
 themes/BlueInfinity/views/layouts/app.blade.php  |  2 +-
 themes/BlueInfinity/views/layouts/main.blade.php |  4 ++--
 .../default/views/admin/settings/index.blade.php |  6 +++---
 themes/default/views/auth/login.blade.php        |  2 +-
 themes/default/views/layouts/app.blade.php       |  2 +-
 themes/default/views/layouts/main.blade.php      |  4 ++--
 39 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index f9e8e9ec3..a5e0e3666 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -31,10 +31,10 @@ body:
     validations:
       required: false
   - type: textarea
-    id: controlpanel-logs
+    id: ctrlpanel-logs
     attributes:
-      label: Controlpanel Logs
-      description: Please copy and paste your laravel-log output. You may also provide a link to it using the following command `tail -n 100 /var/www/controlpanel/storage/logs/laravel.log | nc pteropaste.com 99`
+      label: CtrlPanel Logs
+      description: Please copy and paste your laravel-log output. You may also provide a link to it using the following command `tail -n 100 /var/www/ctrlpanel/storage/logs/laravel.log | nc pteropaste.com 99`
       render: Shell
   - type: textarea
     id: additional-info
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index 278e81e71..05a6da9bf 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -12,6 +12,6 @@ At this time, we only accept vulnerability reports through GitHub Advisories. We
 
 ## Supported Versions
 
-### ControlPanel Versions
+### CtrlPanel Versions
 
-We strongly recommend using or upgrading to the latest version of ControlPanel to ensure you have access to the latest security fixes and enhancements.
+We strongly recommend using or upgrading to the latest version of CtrlPanel to ensure you have access to the latest security fixes and enhancements.
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index a6cd1b9a8..935097bcc 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -398,7 +398,7 @@ public function upgrade(Server $server, Request $request)
 
             // Remove the allocation property from the server object as it is not a column in the database
             unset($server->allocation);
-            // Update the server on controlpanel
+            // Update the server on CtrlPanel
             $server->update([
                 'product_id' => $newProduct->id,
                 'updated_at' => now(),
diff --git a/app/Traits/Invoiceable.php b/app/Traits/Invoiceable.php
index 182333a58..ef212bd0e 100644
--- a/app/Traits/Invoiceable.php
+++ b/app/Traits/Invoiceable.php
@@ -54,7 +54,7 @@ public function createInvoice(Payment $payment, ShopProduct $shopProduct, Invoic
 
 
         $invoice = DailyInvoice::make()
-            ->template('controlpanel')
+            ->template('CtrlPanel')
             ->name(__("Invoice"))
             ->buyer($customer)
             ->seller($seller)
diff --git a/docker/README.md b/docker/README.md
index 1581bd17a..d76483b7c 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -3,9 +3,9 @@
 cd into the project directory and run the following command: `sh bin/startdocker.sh`
 This should start building the images and start the containers.
 
-After that you need to go into the controlpanel_php container and run some commands:
+After that you need to go into the ctrlpanel_php container and run some commands:
 
-Type `docker exec -it controlpanel_php ash` to go into the container and run the following commands:
+Type `docker exec -it ctrlpanel_php ash` to go into the container and run the following commands:
 
 ```shell
 composer install
@@ -17,7 +17,7 @@ php artisan migrate --seed --force
 
 ## Setting up testing environment
 
-Create the .env.testing file to your needs. Then once done you need to go into your phpmyadmin to create a new database named __controlpanel_test__.
+Create the .env.testing file to your needs. Then once done you need to go into your phpmyadmin to create a new database named __ctrlpanel_test__.
 Visit http://127.0.0.1:8080/ and create your database.
 
 Now you're ready to run the following commands which switches to the testing config, migrates the test database and seeds it.
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 56c9e24de..d41e258bc 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -8,7 +8,7 @@ services:
     build:
       context: ../
       dockerfile: docker/nginx/Dockerfile
-    container_name: controlpanel_nginx
+    container_name: ctrlpanel_nginx
     ports:
       - 80:80
     volumes:
@@ -21,14 +21,14 @@ services:
 
   mysql:
     image: mysql
-    container_name: controlpanel_mysql
+    container_name: ctrlpanel_mysql
     restart: unless-stopped
     tty: true
     ports:
       - "3306:3306"
     environment:
-      MYSQL_DATABASE: controlpanel
-      MYSQL_USER: controlpanel
+      MYSQL_DATABASE: ctrlpanel
+      MYSQL_USER: ctrlpanel
       MYSQL_PASSWORD: root
       MYSQL_ROOT_PASSWORD: root
     volumes:
@@ -40,7 +40,7 @@ services:
     build:
       context: ../
       dockerfile: docker/php/Dockerfile
-    container_name: controlpanel_php
+    container_name: ctrlpanel_php
     volumes:
       - "../:/var/www/html"
     networks:
@@ -48,13 +48,13 @@ services:
 
   phpmyadmin:
     image: phpmyadmin/phpmyadmin
-    container_name: controlpanel_phpmyadmin
+    container_name: ctrlpanel_phpmyadmin
     depends_on:
       - mysql
     ports:
       - '8080:80'
     environment:
-      - PMA_HOST=controlpanel_mysql
+      - PMA_HOST=ctrlpanel_mysql
       - PMA_USER=root
       - PMA_PASSWORD=root
       - PMA_ARBITRARY=1
@@ -62,4 +62,4 @@ services:
       - laravel
 
 volumes:
-  mysql:
\ No newline at end of file
+  mysql:
diff --git a/lang/bg.json b/lang/bg.json
index a5c070c57..1618b1ccd 100644
--- a/lang/bg.json
+++ b/lang/bg.json
@@ -126,7 +126,7 @@
     "Support server": "Сървър за поддръжка",
     "Documentation": "Документация",
     "Github": "GitHub",
-    "Support ControlPanel": "Подкрепете Control Panel",
+    "Support CtrlPanel": "Подкрепете CtrlPanel",
     "Servers": "Сървъри",
     "Total": "Общо",
     "Payments": "Плащания",
diff --git a/lang/bs.json b/lang/bs.json
index fe4f110bb..79615b407 100644
--- a/lang/bs.json
+++ b/lang/bs.json
@@ -112,7 +112,7 @@
     "Support server": "Support server",
     "Documentation": "Documentation",
     "Github": "Github",
-    "Support ControlPanel": "Support ControlPanel",
+    "Support CtrlPanel": "Support CtrlPanel",
     "Servers": "Servers",
     "Total": "Total",
     "Payments": "Payments",
diff --git a/lang/cs.json b/lang/cs.json
index a0074d402..146670294 100644
--- a/lang/cs.json
+++ b/lang/cs.json
@@ -126,7 +126,7 @@
     "Support server": "Server podpory",
     "Documentation": "Dokumentace",
     "Github": "GitHub",
-    "Support ControlPanel": "Podpořit ControlPanel",
+    "Support CtrlPanel": "Podpořit CtrlPanel",
     "Servers": "Servery",
     "Total": "Celkem",
     "Payments": "Platby",
diff --git a/lang/de.json b/lang/de.json
index e9ab272d9..2460899a3 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -126,7 +126,7 @@
     "Support server": "Discord Server",
     "Documentation": "Dokumentation",
     "Github": "Github",
-    "Support ControlPanel": "Unterstütze CtrlPanel.gg",
+    "Support CtrlPanel": "Unterstütze CtrlPanel.gg",
     "Servers": "Server",
     "Total": "Gesamt",
     "Payments": "Zahlungen",
diff --git a/lang/en.json b/lang/en.json
index 91da6df34..da51ad810 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -145,7 +145,7 @@
     "Support server": "Support server",
     "Documentation": "Documentation",
     "Github": "Github",
-    "Support ControlPanel": "Support ControlPanel",
+    "Support CtrlPanel": "Support CtrlPanel",
     "Servers": "Servers",
     "Total": "Total",
     "Payments": "Payments",
@@ -166,7 +166,7 @@
     "You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.": "You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.",
     "You can do that in settings.": "You can do that in settings.",
     "Note": "Note",
-    "If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel. Try clicking the button below.": "If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel. Try clicking the button below.",
+    "If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on CtrlPanel. Try clicking the button below.": "If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on CtrlPanel. Try clicking the button below.",
     "Sync servers": "Sync servers",
     "Node": "Node",
     "Server count": "Server count",
diff --git a/lang/es.json b/lang/es.json
index 50ecfb4a4..f4c3121a0 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -126,7 +126,7 @@
     "Support server": "Servidor de Ayuda",
     "Documentation": "Documentación",
     "Github": "GitHub",
-    "Support ControlPanel": "Apoya ControlPanel",
+    "Support CtrlPanel": "Apoya CtrlPanel",
     "Servers": "Servidores",
     "Total": "Total",
     "Payments": "Pagos",
diff --git a/lang/fr.json b/lang/fr.json
index 16e7150f3..8811187d7 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -126,7 +126,7 @@
     "Support server": "Serveur de support",
     "Documentation": "Documentation",
     "Github": "Github",
-    "Support ControlPanel": "ControlPanel Support",
+    "Support CtrlPanel": "CtrlPanel Support",
     "Servers": "Serveurs",
     "Total": "Total",
     "Payments": "Paiments",
diff --git a/lang/he.json b/lang/he.json
index 4d09b0397..04af79956 100644
--- a/lang/he.json
+++ b/lang/he.json
@@ -126,7 +126,7 @@
     "Support server": "שרת תמיכה",
     "Documentation": "מדריך",
     "Github": "Github/גיטאהב",
-    "Support ControlPanel": "תמיכת ControlPanel",
+    "Support CtrlPanel": "תמיכת CtrlPanel",
     "Servers": "שרתים",
     "Total": "בסך הכל",
     "Payments": "תשלומים",
diff --git a/lang/hi.json b/lang/hi.json
index c36b7d014..5b310de06 100644
--- a/lang/hi.json
+++ b/lang/hi.json
@@ -126,7 +126,7 @@
     "Support server": "समर्थन सर्वर",
     "Documentation": "प्रलेखन",
     "Github": "गिटहब",
-    "Support ControlPanel": "समर्थन नियंत्रण पैनल",
+    "Support CtrlPanel": "CtrlPanel का समर्थन करें",
     "Servers": "सर्वरस",
     "Total": "कुल",
     "Payments": "भुगतान",
diff --git a/lang/hu.json b/lang/hu.json
index af3ac9622..2479fdb5b 100644
--- a/lang/hu.json
+++ b/lang/hu.json
@@ -126,7 +126,7 @@
     "Support server": "Szerver támogatása",
     "Documentation": "Dokumentáció",
     "Github": "Github",
-    "Support ControlPanel": "ControlPanel támogatása",
+    "Support CtrlPanel": "CtrlPanel támogatása",
     "Servers": "Szerverek",
     "Total": "Összesen",
     "Payments": "Fizetések",
diff --git a/lang/it.json b/lang/it.json
index 1fce8de29..12f1c29f1 100644
--- a/lang/it.json
+++ b/lang/it.json
@@ -126,7 +126,7 @@
     "Support server": "Server di supporto",
     "Documentation": "Documentazione",
     "Github": "GitHub",
-    "Support ControlPanel": "Supporta ControlPanel",
+    "Support CtrlPanel": "Supporta CtrlPanel",
     "Servers": "Servers",
     "Total": "Totale",
     "Payments": "Pagamenti",
diff --git a/lang/nl.json b/lang/nl.json
index 6db2f669d..8b1add000 100644
--- a/lang/nl.json
+++ b/lang/nl.json
@@ -126,7 +126,7 @@
     "Support server": "Ondersteuningsserver",
     "Documentation": "Documentatie",
     "Github": "Github",
-    "Support ControlPanel": "Ondersteuning ControlPanel",
+    "Support CtrlPanel": "Ondersteuning CtrlPanel",
     "Servers": "Servers",
     "Total": "Totaal",
     "Payments": "Betalingen",
diff --git a/lang/pl.json b/lang/pl.json
index d14b00803..05e68bac1 100644
--- a/lang/pl.json
+++ b/lang/pl.json
@@ -126,7 +126,7 @@
     "Support server": "Serwer pomocy",
     "Documentation": "Dokumentacja",
     "Github": "Github",
-    "Support ControlPanel": "Wesprzyj ControlPanel",
+    "Support CtrlPanel": "Wesprzyj CtrlPanel",
     "Servers": "Serwery",
     "Total": "Razem",
     "Payments": "Płatności",
diff --git a/lang/pt.json b/lang/pt.json
index 9083b97d4..e07ec430b 100644
--- a/lang/pt.json
+++ b/lang/pt.json
@@ -126,7 +126,7 @@
     "Support server": "Servidor de suporte",
     "Documentation": "Documentação",
     "Github": "Github",
-    "Support ControlPanel": "Suporte para ControlPanel",
+    "Support CtrlPanel": "Suporte para CtrlPanel",
     "Servers": "Servidores",
     "Total": "Total",
     "Payments": "Pagamentos",
diff --git a/lang/ro.json b/lang/ro.json
index d9a949671..9aeb0f05b 100644
--- a/lang/ro.json
+++ b/lang/ro.json
@@ -126,7 +126,7 @@
     "Support server": "Support server",
     "Documentation": "Documentation",
     "Github": "Github",
-    "Support ControlPanel": "Support ControlPanel",
+    "Support CtrlPanel": "Support CtrlPanel",
     "Servers": "Servers",
     "Total": "Total",
     "Payments": "Payments",
diff --git a/lang/ru.json b/lang/ru.json
index ec254e371..a9bfeb9f5 100644
--- a/lang/ru.json
+++ b/lang/ru.json
@@ -126,7 +126,7 @@
     "Support server": "Сервер поддержки",
     "Documentation": "Документация",
     "Github": "GitHub",
-    "Support ControlPanel": "Поддержка панели управления",
+    "Support CtrlPanel": "Поддержка CtrlPanel",
     "Servers": "Серверы",
     "Total": "Всего",
     "Payments": "Оплаты",
diff --git a/lang/sh.json b/lang/sh.json
index c65182bb1..1809b0c01 100644
--- a/lang/sh.json
+++ b/lang/sh.json
@@ -112,7 +112,7 @@
     "Support server": "Support server",
     "Documentation": "Documentation",
     "Github": "Github",
-    "Support ControlPanel": "Support ControlPanel",
+    "Support CtrlPanel": "Support CtrlPanel",
     "Servers": "Servers",
     "Total": "Total",
     "Payments": "Payments",
diff --git a/lang/sk.json b/lang/sk.json
index 2db59f349..99fa908e3 100644
--- a/lang/sk.json
+++ b/lang/sk.json
@@ -126,7 +126,7 @@
     "Support server": "Server podpory",
     "Documentation": "Dokumentácia",
     "Github": "Github",
-    "Support ControlPanel": "Podporiť ControlPanel",
+    "Support CtrlPanel": "Podporiť CtrlPanel",
     "Servers": "Servery",
     "Total": "Celkom",
     "Payments": "Platby",
diff --git a/lang/sr.json b/lang/sr.json
index 50cab9924..65ecd37cc 100644
--- a/lang/sr.json
+++ b/lang/sr.json
@@ -126,7 +126,7 @@
     "Support server": "Server za podršku",
     "Documentation": "Dokumentacija",
     "Github": "GitHub",
-    "Support ControlPanel": "Podrži ControlPanel",
+    "Support CtrlPanel": "Podrži CtrlPanel",
     "Servers": "Serveri",
     "Total": "Ukupno",
     "Payments": "Plaćanja",
diff --git a/lang/sv.json b/lang/sv.json
index 552f0def3..d26a47107 100644
--- a/lang/sv.json
+++ b/lang/sv.json
@@ -126,7 +126,7 @@
     "Support server": "Stödservern",
     "Documentation": "Dokumentation",
     "Github": "Github",
-    "Support ControlPanel": "Support ControlPanel",
+    "Support CtrlPanel": "Support CtrlPanel",
     "Servers": "Servers",
     "Total": "Total",
     "Payments": "Payments",
diff --git a/lang/tr.json b/lang/tr.json
index f05ebe60e..1a31d925a 100644
--- a/lang/tr.json
+++ b/lang/tr.json
@@ -126,7 +126,7 @@
     "Support server": "Destek sunucusu",
     "Documentation": "Dökümantasyon",
     "Github": "GitHub",
-    "Support ControlPanel": "ContrılPanel'i destekle",
+    "Support CtrlPanel": "CtrlPanel'i destekle",
     "Servers": "Sunucular",
     "Total": "Toplam",
     "Payments": "Ödemeler",
diff --git a/lang/zh.json b/lang/zh.json
index 58e00e356..c18dad757 100644
--- a/lang/zh.json
+++ b/lang/zh.json
@@ -126,7 +126,7 @@
     "Support server": "支持服务器",
     "Documentation": "文档",
     "Github": "Github",
-    "Support ControlPanel": "支持我们",
+    "Support CtrlPanel": "支持我们",
     "Servers": "服务器",
     "Total": "总数",
     "Payments": "支付费用",
diff --git a/package-lock.json b/package-lock.json
index 89d691a53..95a8ff2b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
 {
-    "name": "controlpanel",
+    "name": "CtrlPanel",
     "lockfileVersion": 2,
     "requires": true,
     "packages": {
diff --git a/phpunit.xml b/phpunit.xml
index fc15f97bc..1c2c01844 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -22,7 +22,7 @@
         <env name="BCRYPT_ROUNDS" value="4"/>
         <env name="CACHE_DRIVER" value="array"/>
         <env name="DB_CONNECTION" value="mysql"/>
-        <env name="DB_DATABASE" value="controlpanel_test"/>
+        <env name="DB_DATABASE" value="ctrlpanel_test"/>
         <env name="MAIL_MAILER" value="array"/>
         <env name="QUEUE_CONNECTION" value="sync"/>
         <env name="SESSION_DRIVER" value="array"/>
diff --git a/public/install/forms.php b/public/install/forms.php
index 96f1dfa17..3ca18c010 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -87,7 +87,7 @@
         header('LOCATION: index.php?step=3');
     } catch (\Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
-        header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/ctrlpanel/storage/logs !");
     }
 }
 
diff --git a/public/install/functions.php b/public/install/functions.php
index a5f2b0454..5e8b847aa 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -262,7 +262,7 @@ function wh_log(string $message, string $level = 'info', array $context = []): v
     $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG);
     $stream->setFormatter($formatter);
 
-    $log = new Logger('ControlPanel');
+    $log = new Logger('CtrlPanel');
     $log->pushHandler($stream);
 
     switch (strtolower($level)) {
diff --git a/public/install/index.php b/public/install/index.php
index 6afd2e70c..ee36cc4dd 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -143,7 +143,7 @@ function cardStart($title, $subtitle = null)
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
                             <label for="databaseuser">Database User</label>
-                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="controlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">
@@ -156,7 +156,7 @@ function cardStart($title, $subtitle = null)
                     <div class="form-group">
                         <div class="flex flex-col">
                             <label for="database">Database</label>
-                            <input x-model="database" id="database" name="database" type="text" required value="controlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
 
diff --git a/themes/BlueInfinity/views/layouts/app.blade.php b/themes/BlueInfinity/views/layouts/app.blade.php
index 376f1d920..e8c5650d8 100644
--- a/themes/BlueInfinity/views/layouts/app.blade.php
+++ b/themes/BlueInfinity/views/layouts/app.blade.php
@@ -6,7 +6,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta content="{{ config('SETTINGS::SYSTEM:SEO_TITLE') }}" property="og:title">
     <meta content="{{ config('SETTINGS::SYSTEM:SEO_DESCRIPTION') }}" property="og:description">
-    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}' property="og:image">
+    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/ctrlpanel_logo.png') }}' property="og:image">
 
     <!-- CSRF Token -->
     <meta name="csrf-token" content="{{ csrf_token() }}">
diff --git a/themes/BlueInfinity/views/layouts/main.blade.php b/themes/BlueInfinity/views/layouts/main.blade.php
index b6549a7a0..785b42780 100644
--- a/themes/BlueInfinity/views/layouts/main.blade.php
+++ b/themes/BlueInfinity/views/layouts/main.blade.php
@@ -11,7 +11,7 @@
     <meta content="{{ $website_settings->seo_title }}" property="og:title">
     <meta content="{{ $website_settings->seo_description }}" property="og:description">
     <meta
-        content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}'
+        content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/ctrlpanel_logo.png') }}'
         property="og:image">
     <title>{{ config('app.name', 'Laravel') }}</title>
     <link rel="icon"
@@ -201,7 +201,7 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
         <!-- Brand Logo -->
         <a href="{{ route('home') }}" class="brand-link">
             <img width="64" height="64"
-                 src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
+                 src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/ctrlpanel_logo.png') }}"
                  alt="{{ config('app.name', 'Laravel') }} Logo" class="brand-image img-circle"
                  style="opacity: .8">
             <span class="brand-text font-weight-light">{{ config('app.name', 'CtrlPanel.gg') }}</span>
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 799e426de..4d07a9e31 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -120,7 +120,7 @@ class="nav-icon fas {{ $options['category_icon'] ?? 'fas fa-cog' }}"></i>
                                         <div class="row">
                                             <div class="ml-5 card" style="width: 18rem;">
                                                 <span class="text-center h3">{{ __('FavIcon') }} </span>
-                                              <img src="{{ Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('images/controlpanel_logo.png') }}"
+                                              <img src="{{ Storage::disk('public')->exists('favicon.ico') ? asset('storage/favicon.ico') : asset('images/ctrlpanel_logo.png') }}"
                                                    style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                    class="card-img-top" alt="...">
                                                 <div class="card-body">
@@ -132,7 +132,7 @@ class="card-img-top" alt="...">
 
                                             <div class="ml-5 card" style="width: 18rem;">
                                                 <span class="text-center h3">{{ __('Icon') }} </span>
-                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
+                                                <img src="{{ Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/ctrlpanel_logo.png') }}"
                                                     style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                     class="card-img-top" alt="...">
                                                 <div class="card-body">
@@ -144,7 +144,7 @@ class="form-control" name="icon" id="icon">
 
                                             <div class="ml-5 card" style="width: 18rem;">
                                                 <span class="text-center h3">{{ __('Login-page Logo') }} </span>
-                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
+                                                <img src="{{ Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/ctrlpanel_logo.png') }}"
                                                     style="width:5vw;display: block; margin-left: auto;margin-right: auto"
                                                     class="card-img-top" alt="...">
                                                 <div class="card-body">
diff --git a/themes/default/views/auth/login.blade.php b/themes/default/views/auth/login.blade.php
index c570550d9..fe743dd35 100644
--- a/themes/default/views/auth/login.blade.php
+++ b/themes/default/views/auth/login.blade.php
@@ -10,7 +10,7 @@
                     <a href="{{ route('welcome') }}" class="h1 mb-2"><b
                             class="mr-1">{{ config('app.name', 'Laravel') }}</b></a>
                     @if ($website_settings->enable_login_logo)
-                        <img src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}"
+                        <img src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/ctrlpanel_logo.png') }}"
                             alt="{{ config('app.name', 'CtrlPanel.gg') }} Logo" style="opacity: .8; max-width:100%; height: 150px; margin-top: 10px;">
                     @endif
                 </div>
diff --git a/themes/default/views/layouts/app.blade.php b/themes/default/views/layouts/app.blade.php
index 240eb2466..3f6b504f5 100644
--- a/themes/default/views/layouts/app.blade.php
+++ b/themes/default/views/layouts/app.blade.php
@@ -7,7 +7,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta content="{{ $website_settings->seo_title }}" property="og:title">
     <meta content="{{ $website_settings->seo_description }}" property="og:description">
-    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('/logo.png') : asset('images/controlpanel_logo.png') }}' property="og:image">
+    <meta content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('/logo.png') : asset('images/ctrlpanel_logo.png') }}' property="og:image">
 
     <!-- CSRF Token -->
     <meta name="csrf-token" content="{{ csrf_token() }}">
diff --git a/themes/default/views/layouts/main.blade.php b/themes/default/views/layouts/main.blade.php
index 9631ef64d..66c79d6e7 100644
--- a/themes/default/views/layouts/main.blade.php
+++ b/themes/default/views/layouts/main.blade.php
@@ -11,7 +11,7 @@
     <meta content="{{ $website_settings->seo_title }}" property="og:title">
     <meta content="{{ $website_settings->seo_description }}" property="og:description">
     <meta
-        content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/controlpanel_logo.png') }}'
+        content='{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('logo.png') ? asset('storage/logo.png') : asset('images/ctrlpanel_logo.png') }}'
         property="og:image">
     <title>{{ config('app.name', 'Laravel') }}</title>
     <link rel="icon"
@@ -201,7 +201,7 @@ class="dropdown-item dropdown-footer">{{ __('Mark all as read') }}</a>
             <!-- Brand Logo -->
             <a href="{{ route('home') }}" class="brand-link">
                 <img width="64" height="64"
-                    src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/controlpanel_logo.png') }}"
+                    src="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('icon.png') ? asset('storage/icon.png') : asset('images/ctrlpanel_logo.png') }}"
                     alt="{{ config('app.name', 'Laravel') }} Logo" class="brand-image img-circle"
                     style="opacity: .8">
                 <span class="brand-text font-weight-light">{{ config('app.name', 'CtrlPanel.gg') }}</span>

From 920279cc37954b457b945613a805d7d5fca23aae Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Wed, 22 May 2024 13:18:21 +0000
Subject: [PATCH 314/514] Buy more button, if user does not have enough credits

---
 app/Http/Controllers/ServerController.php     | 3 ++-
 lang/en.json                                  | 3 ++-
 themes/default/views/servers/create.blade.php | 9 +++++++++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 0c18a5084..c52dc9316 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -122,7 +122,8 @@ public function create(UserSettings $user_settings, ServerSettings $server_setti
             'user' => Auth::user(),
             'server_creation_enabled' => $server_settings->creation_enabled,
             'min_credits_to_make_server' => $user_settings->min_credits_to_make_server,
-            'credits_display_name' => $general_settings->credits_display_name
+            'credits_display_name' => $general_settings->credits_display_name,
+            'store_enabled' => $general_settings->store_enabled
         ]);
     }
 
diff --git a/lang/en.json b/lang/en.json
index 633a4ec2c..25f16da8b 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -655,5 +655,6 @@
     "You can not see your Referral Code": "You can not see your Referral Code",
     "SERVER NAME": "SERVER NAME",
     "STORAGE": "STORAGE",
-    "Cancel": "Cancel"
+    "Cancel": "Cancel",
+    "Buy more": "Buy more"
 }
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 588da5a40..417dae942 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -250,6 +250,15 @@ class="custom-select">
                                             class="btn btn-primary btn-block mt-2" @click="setProduct(product.id);"
                                             x-text="product.doesNotFit == true ? '{{ __('Server cant fit on this Node') }}' : (product.minimum_credits > user.credits || product.price > user.credits ? '{{ __('Not enough') }} {{ $credits_display_name }}!' : '{{ __('Create server') }}')">
                                         </button>
+                                        @if (env('APP_ENV') == 'local' || $store_enabled)
+                                        <template x-if="product.price > user.credits">
+                                            <a href="{{ route('store.index') }}">
+                                                <button type="button" class="btn btn-warning btn-block mt-2">
+                                                    {{ __('Buy more') }} {{ $credits_display_name }}
+                                                </button>
+                                            </a>
+                                        </template>
+                                        @endif
                                     </div>
 
                                 </div>

From f92552f7fdc7e08d7eb74cfbc8a3c1682c212e75 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Wed, 22 May 2024 15:30:28 +0200
Subject: [PATCH 315/514] [Feat] Remove unused image [Bug] ControlPanel
 leftovers changed to CtrlPanel

---
 app/Traits/Invoiceable.php                     |   2 +-
 public/images/controlpanel.png                 | Bin 143251 -> 0 bytes
 ...ontrolpanel_logo.png => ctrlpanel_logo.png} | Bin
 ...trolpanel.blade.php => ctrlpanel.blade.php} |   0
 4 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 public/images/controlpanel.png
 rename public/images/{controlpanel_logo.png => ctrlpanel_logo.png} (100%)
 rename themes/default/views/vendor/invoices/templates/{controlpanel.blade.php => ctrlpanel.blade.php} (100%)

diff --git a/app/Traits/Invoiceable.php b/app/Traits/Invoiceable.php
index ef212bd0e..3ee77c90e 100644
--- a/app/Traits/Invoiceable.php
+++ b/app/Traits/Invoiceable.php
@@ -54,7 +54,7 @@ public function createInvoice(Payment $payment, ShopProduct $shopProduct, Invoic
 
 
         $invoice = DailyInvoice::make()
-            ->template('CtrlPanel')
+            ->template('ctrlpanel')
             ->name(__("Invoice"))
             ->buyer($customer)
             ->seller($seller)
diff --git a/public/images/controlpanel.png b/public/images/controlpanel.png
deleted file mode 100644
index 63a4d3bf288f418e5377f7c6454fba2d88972a6a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 143251
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
S_-r!+5O})!xvX<aXaWGNAuNsn

diff --git a/public/images/controlpanel_logo.png b/public/images/ctrlpanel_logo.png
similarity index 100%
rename from public/images/controlpanel_logo.png
rename to public/images/ctrlpanel_logo.png
diff --git a/themes/default/views/vendor/invoices/templates/controlpanel.blade.php b/themes/default/views/vendor/invoices/templates/ctrlpanel.blade.php
similarity index 100%
rename from themes/default/views/vendor/invoices/templates/controlpanel.blade.php
rename to themes/default/views/vendor/invoices/templates/ctrlpanel.blade.php

From da622b82c36175ebb8b4c96baaa5868418e72c72 Mon Sep 17 00:00:00 2001
From: kenshin133 <bufmouse13@gmail.com>
Date: Wed, 22 May 2024 10:36:32 -0400
Subject: [PATCH 316/514] fixed product description showing up instead of name
 in two locations

This seems to be referenced two places, admin/servers and admin/users/1

I could not find any other effects of this change but do feel free to double check my work.

themes/default/views/admin/servers/table.blade.php
And
themes/default/views/admin/users/show.blade.php
and perhaps
themes/default/views/admin/users/edit.blade.php

have
data: 'resources', name: 'product.name',

In them, another fix would be to alter this to data: 'product.name' but the proposed change seems like the right one.
---
 app/Http/Controllers/Admin/ServerController.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index 97ee15535..b2775bb1c 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -228,7 +228,7 @@ public function dataTable(Request $request)
                 return '<a href="' . route('admin.users.show', $server->user->id) . '">' . $server->user->name . '</a>';
             })
             ->addColumn('resources', function (Server $server) {
-                return $server->product->description;
+                return $server->product->name;
             })
             ->addColumn('actions', function (Server $server) {
                 $suspendColor = $server->isSuspended() ? 'btn-success' : 'btn-warning';

From a2da2d12e3edbde3876579ee7c5a44c7d2443ad7 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Wed, 22 May 2024 21:27:06 +0200
Subject: [PATCH 317/514] [Feature]: Location description label on server
 create (optional setting) [Fix]: Node Description grabs name??

---
 app/Http/Controllers/ServerController.php     |  6 ++++--
 app/Models/Pterodactyl/Location.php           |  2 +-
 app/Settings/ServerSettings.php               |  7 +++++++
 themes/default/views/servers/create.blade.php | 14 +++++++++++---
 4 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 935097bcc..4d7553f52 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -122,7 +122,8 @@ public function create(UserSettings $user_settings, ServerSettings $server_setti
             'user' => Auth::user(),
             'server_creation_enabled' => $server_settings->creation_enabled,
             'min_credits_to_make_server' => $user_settings->min_credits_to_make_server,
-            'credits_display_name' => $general_settings->credits_display_name
+            'credits_display_name' => $general_settings->credits_display_name,
+            'location_description_enabled' => $server_settings->location_description_enabled,
         ]);
     }
 
@@ -333,7 +334,8 @@ public function show(Server $server, ServerSettings $server_settings, GeneralSet
             'server' => $server,
             'products' => $products,
             'server_enable_upgrade' => $server_settings->enable_upgrade,
-            'credits_display_name' => $general_settings->credits_display_name
+            'credits_display_name' => $general_settings->credits_display_name,
+            'location_description_enabled' => $server_settings->location_description_enabled,
         ]);
     }
 
diff --git a/app/Models/Pterodactyl/Location.php b/app/Models/Pterodactyl/Location.php
index 8d4bf7c10..ddb1f7155 100644
--- a/app/Models/Pterodactyl/Location.php
+++ b/app/Models/Pterodactyl/Location.php
@@ -53,7 +53,7 @@ public static function syncLocations()
                 ],
                 [
                     'name' => $location['name'],
-                    'description' => $location['name'],
+                    'description' => $location['description'],
                 ]
             );
         }
diff --git a/app/Settings/ServerSettings.php b/app/Settings/ServerSettings.php
index 3a82ac3bc..8ed4547d1 100644
--- a/app/Settings/ServerSettings.php
+++ b/app/Settings/ServerSettings.php
@@ -9,6 +9,7 @@ class ServerSettings extends Settings
     public int $allocation_limit;
     public bool $creation_enabled;
     public bool $enable_upgrade;
+    public bool $location_description_enabled;
 
     public static function group(): string
     {
@@ -25,6 +26,7 @@ public static function getValidations()
             'allocation_limit' => 'required|integer|min:0',
             'creation_enabled' => 'nullable|string',
             'enable_upgrade' => 'nullable|string',
+            'location_description_enabled' => 'nullable|string',
         ];
     }
 
@@ -52,6 +54,11 @@ public static function getOptionInputData()
                 'type' => 'boolean',
                 'description' => 'Enable the server upgrade feature.',
             ],
+            'location_description_enabled' => [
+                'label' => 'Enable Location Description',
+                'type' => 'boolean',
+                'description' => 'Enable the location description field on the server creation page.',
+            ],
         ];
     }
 }
diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index 4dfadea55..b614ab180 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -135,11 +135,15 @@ class="custom-select">
 
                               <div class="form-group">
                                 <label for="location">{{ __('Location') }}</label>
+                                @if($location_description_enabled)
+                                  <i x-show="locationDescription != null" data-toggle="popover" data-trigger="click"
+                                     x-bind:data-content="locationDescription"
+                                     class="fas fa-info-circle"></i>
+                                @endif
                                 <select name="location" required id="location" x-model="selectedLocation" :disabled="!fetchedLocations"
                                         @change="fetchProducts();" class="custom-select">
                                   <option x-text="getLocationInputText()" disabled selected hidden value="null">
                                   </option>
-
                                   <template x-for="location in locations" :key="location.id">
                                     <option x-text="location.name" :value="location.id">
                                     </option>
@@ -273,6 +277,7 @@ function serverApp() {
                 selectedEgg: null,
                 selectedLocation: null,
                 selectedProduct: null,
+                locationDescription: null,
 
                 //selected objects based on input
                 selectedNestObject: {},
@@ -304,6 +309,7 @@ function serverApp() {
                     this.selectedEgg = 'null';
                     this.selectedLocation = 'null';
                     this.selectedProduct = 'null';
+                    this.locationDescription = 'null';
 
                     this.eggs = this.eggsSave.filter(egg => egg.nest_id == this.selectedNest)
 
@@ -338,6 +344,7 @@ function serverApp() {
                     this.products = [];
                     this.selectedLocation = 'null';
                     this.selectedProduct = 'null';
+                    this.locationDescription = null;
 
                     let response = await axios.get(`{{ route('products.locations.egg') }}/${this.selectedEgg}`)
                         .catch(console.error)
@@ -348,6 +355,7 @@ function serverApp() {
                     //automatically select the first entry if there is only 1
                     if (this.locations.length === 1 && this.locations[0]?.nodes?.length === 1) {
                         this.selectedLocation = this.locations[0]?.id;
+
                         await this.fetchProducts();
                         return;
                     }
@@ -365,7 +373,7 @@ function serverApp() {
                     this.loading = true;
                     this.fetchedProducts = false;
                     this.products = [];
-                    this.selectedProduct = 'null';
+                    this.selectedProduct = null;
 
                     let response = await axios.get(
                             `{{ route('products.products.location') }}/${this.selectedEgg}/${this.selectedLocation}`)
@@ -389,7 +397,7 @@ function serverApp() {
                         }
                     })
 
-
+                    this.locationDescription = this.locations.find(location => location.id == this.selectedLocation).description ?? null;
                     this.loading = false;
                     this.updateSelectedObjects()
                 },

From 66b1056d110b4bd946af0d47b92a5bc9f1f6ebc8 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Wed, 22 May 2024 23:12:08 +0200
Subject: [PATCH 318/514] [Feature]: Additional error message when nodes are
 full

---
 themes/default/views/servers/create.blade.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/themes/default/views/servers/create.blade.php b/themes/default/views/servers/create.blade.php
index b614ab180..56c775e97 100644
--- a/themes/default/views/servers/create.blade.php
+++ b/themes/default/views/servers/create.blade.php
@@ -150,6 +150,9 @@ class="fas fa-info-circle"></i>
                                   </template>
                                 </select>
                               </div>
+                              <div class="alert alert-danger p-2 m-2" x-show="selectedProduct != null && locations.length == 0">
+                                {{ __('There seem to be no nodes available for this specification. Admins have been notified. Please try again later of contact us.') }}
+                              </div>
                         </div>
                     </div>
                 </div>

From 3359204b2ddc9f2105c5dc0c2d0f7388d2607358 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Thu, 23 May 2024 00:26:08 +0200
Subject: [PATCH 319/514] [Feature]: Rate-Limit verification emails

---
 app/Models/User.php | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/app/Models/User.php b/app/Models/User.php
index 246cb0c5a..3da03cba6 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -14,6 +14,7 @@
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
 use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\RateLimiter;
 use Spatie\Activitylog\LogOptions;
 use Spatie\Activitylog\Traits\CausesActivity;
 use Spatie\Activitylog\Traits\LogsActivity;
@@ -188,7 +189,19 @@ public function discordUser()
 
     public function sendEmailVerificationNotification()
     {
-        $this->notify(new QueuedVerifyEmail);
+        // Rate limit the email verification notification to 1 attempt per 30 minutes
+        $executed = RateLimiter::attempt(
+            key: 'verify-mail'. $this->id,
+            maxAttempts: 1,
+            callback: function() {
+                $this->notify(new QueuedVerifyEmail);
+            },
+            decaySeconds: 1800
+        );
+
+        if (! $executed) {
+            return response()->json(['message' => 'Too many requests, try again in: ' . RateLimiter::availableIn('send-message:'. $this->id) . ' seconds'], 429);
+        }
     }
 
     /**

From 150c24d078b0de079f69056b7990e621f97d5d3b Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 23 May 2024 00:49:42 +0200
Subject: [PATCH 320/514] FIX: tickets works now

---
 app/Http/Controllers/TicketsController.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index c2c9d14d4..5eb7f7e0b 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -19,6 +19,7 @@
 use Illuminate\Support\Facades\Notification;
 use Illuminate\Support\Facades\RateLimiter;
 use Illuminate\Support\Str;
+use App\Settings\GeneralSettings;
 
 class TicketsController extends Controller
 {

From 35643b208002a5321a2588ae280345b5cd32ac19 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Thu, 23 May 2024 01:30:16 +0200
Subject: [PATCH 321/514] [Feature]: Send mail to admin (first user ID) when
 nodes are full

---
 app/Http/Controllers/ProductController.php | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php
index ae9c1548c..5f3a41cbc 100644
--- a/app/Http/Controllers/ProductController.php
+++ b/app/Http/Controllers/ProductController.php
@@ -7,11 +7,16 @@
 use App\Models\Pterodactyl\Location;
 use App\Models\Pterodactyl\Node;
 use App\Models\Product;
+use App\Models\User;
+use App\Notifications\DynamicNotification;
 use App\Settings\PterodactylSettings;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
+use Illuminate\Notifications\Messages\MailMessage;
 use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Notification;
+use Illuminate\Support\Facades\RateLimiter;
 
 class ProductController extends Controller
 {
@@ -93,6 +98,19 @@ public function getLocationsBasedOnEgg(Request $request, Egg $egg)
             }
         });
 
+        if($locations->isEmpty()){
+            // Rate limit the node full notification to 1 attempt per 30 minutes
+            RateLimiter::attempt(
+                key: 'nodes-full-warning',
+                maxAttempts: 1,
+                callback: function() {
+                    $user = User::find(1); // Get the first user, should be the admin
+                    Notification::send($user,new DynamicNotification(['mail'], [], mail: (new MailMessage)->subject('Attention! All of the nodes are full!')->greeting('Attention!')->line('All nodes are full, please add more nodes')));
+                },
+                decaySeconds: 1800
+            );
+        }
+
         return $locations;
     }
 

From bf260528a0512a85ea1aecd23d9caa525082069b Mon Sep 17 00:00:00 2001
From: Jens <34610614+AGuyNamedJens@users.noreply.github.com>
Date: Thu, 23 May 2024 01:46:38 +0200
Subject: [PATCH 322/514] Update User.php

---
 app/Models/User.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Models/User.php b/app/Models/User.php
index 3da03cba6..9577fa808 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -200,7 +200,7 @@ public function sendEmailVerificationNotification()
         );
 
         if (! $executed) {
-            return response()->json(['message' => 'Too many requests, try again in: ' . RateLimiter::availableIn('send-message:'. $this->id) . ' seconds'], 429);
+            return response()->json(['message' => 'Too many requests, try again in: ' . RateLimiter::availableIn('verify-mail:'. $this->id) . ' seconds'], 429);
         }
     }
 

From f760cb689ca0907c011ee61115e2fd8118e83cfc Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Thu, 23 May 2024 01:54:22 +0200
Subject: [PATCH 323/514] [Feature]: Send mail to admin users(?) needs testing

---
 app/Http/Controllers/ProductController.php | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php
index 5f3a41cbc..4e7e09e56 100644
--- a/app/Http/Controllers/ProductController.php
+++ b/app/Http/Controllers/ProductController.php
@@ -104,10 +104,12 @@ public function getLocationsBasedOnEgg(Request $request, Egg $egg)
                 key: 'nodes-full-warning',
                 maxAttempts: 1,
                 callback: function() {
-                    $user = User::find(1); // Get the first user, should be the admin
-                    Notification::send($user,new DynamicNotification(['mail'], [], mail: (new MailMessage)->subject('Attention! All of the nodes are full!')->greeting('Attention!')->line('All nodes are full, please add more nodes')));
+                    // get admin role and check users
+                    $users = User::query()->where('role', '=', '1')->get();
+                    Notification::send($users,new DynamicNotification(['mail'],[],
+                   mail: (new MailMessage)->subject('Attention! All of the nodes are full!')->greeting('Attention!')->line('All nodes are full, please add more nodes')));
                 },
-                decaySeconds: 1800
+                decaySeconds: 5
             );
         }
 

From 924abc0b79431b0aeed2bb3ad474d4938e53c0e1 Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Thu, 23 May 2024 00:26:18 -0300
Subject: [PATCH 324/514] Add use MercadoPagoSettings and  update
 $notificationId

now I noticed that the use of MercadoPagoSettings was missing, The notificationId was changed to the correct values to be expected
---
 .../PaymentGateways/MercadoPago/MercadoPagoExtension.php       | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index ffd545d18..279f1572e 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -18,6 +18,7 @@
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Http;
 use App\Notifications\ConfirmPaymentNotification;
+use App\Extensions\PaymentGateways\MercadoPago\MercadoPagoSettings;
 
 /**
  * Summary of MercadoPagoExtension
@@ -104,7 +105,7 @@ static function Webhook(Request $request): JsonResponse
             return response()->json(['success' => true]);
         } else {
             try {
-                $notificationId = $request->input('data.id') ?? $request->input('id') ?? $request->input('payment_id') ?? 'unknown';
+                $notificationId = $laravelRequest->input('data_id') || $laravelRequest->input('data.id') || "unknown";
                 if ($notificationId == 'unknown') {
                     return response()->json(['success' => false]);
                 } else if ($notificationId == '123456') {

From 2b8c40b852336d25884f6d10ad286b94bf21115d Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Thu, 23 May 2024 00:28:42 -0300
Subject: [PATCH 325/514] Update MercadoPagoExtension.php

Sorry, incorrect variable name laravelRequest,
---
 .../PaymentGateways/MercadoPago/MercadoPagoExtension.php        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index 279f1572e..5bb1805f6 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -105,7 +105,7 @@ static function Webhook(Request $request): JsonResponse
             return response()->json(['success' => true]);
         } else {
             try {
-                $notificationId = $laravelRequest->input('data_id') || $laravelRequest->input('data.id') || "unknown";
+                $notificationId = $request->input('data_id') || $request->input('data.id') || "unknown";
                 if ($notificationId == 'unknown') {
                     return response()->json(['success' => false]);
                 } else if ($notificationId == '123456') {

From 02444770707a6cc4df31b647aef5a8b56cc2943a Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Thu, 23 May 2024 23:52:14 +0200
Subject: [PATCH 326/514] [Bug]: Fix ForgotPasswordController breaking

---
 app/Http/Controllers/Auth/ForgotPasswordController.php | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php
index 79f1e99fd..6c3f34aef 100644
--- a/app/Http/Controllers/Auth/ForgotPasswordController.php
+++ b/app/Http/Controllers/Auth/ForgotPasswordController.php
@@ -32,13 +32,15 @@ public function __construct()
         $this->middleware('guest');
     }
 
-    protected function validateEmail(Request $request, GeneralSettings $general_settings)
+    protected function validateEmail(Request $request)
     {
         $this->validate($request, [
             'email' => ['required', 'string', 'email', 'max:255'],
         ]);
 
-        if ($general_settings->recaptcha_enabled) {
+        $recaptcha_enabled = app(GeneralSettings::class)->recaptcha_enabled;
+
+        if ($recaptcha_enabled) {
             $this->validate($request, [
                 'g-recaptcha-response' => 'required|recaptcha',
             ]);

From 4bf534ad50682c6fbd5c2226660b858fe43abed4 Mon Sep 17 00:00:00 2001
From: MrWeez <64205495+MrWeez@users.noreply.github.com>
Date: Fri, 24 May 2024 10:38:31 +0300
Subject: [PATCH 327/514] Fix error 500 on the checkout page, small code
 refactor and total display fix (#963)

* fix: replaced number_format by round because this caused error 500 on checkout

* refactor: code has been made more readable

* fix: incorrect display of total on checkout
---
 app/Models/ShopProduct.php                    | 10 +++++++---
 themes/default/views/store/checkout.blade.php |  2 +-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/app/Models/ShopProduct.php b/app/Models/ShopProduct.php
index 12b870a28..8e8a2260b 100644
--- a/app/Models/ShopProduct.php
+++ b/app/Models/ShopProduct.php
@@ -80,7 +80,9 @@ public function getTaxPercent()
 
     public function getPriceAfterDiscount()
     {
-        return number_format($this->price - ($this->price * PartnerDiscount::getDiscount() / 100), 2);
+        $discountRate = PartnerDiscount::getDiscount() / 100;
+        $discountedPrice = $this->price * (1 - $discountRate);
+        return round($discountedPrice, 2);
     }
 
     /**
@@ -90,7 +92,8 @@ public function getPriceAfterDiscount()
      */
     public function getTaxValue()
     {
-        return number_format($this->getPriceAfterDiscount() * $this->getTaxPercent() / 100, 2);
+        $taxValue = $this->getPriceAfterDiscount() * $this->getTaxPercent() / 100;
+        return round($taxValue, 2);
     }
 
     /**
@@ -100,6 +103,7 @@ public function getTaxValue()
      */
     public function getTotalPrice()
     {
-        return number_format($this->getPriceAfterDiscount() + $this->getTaxValue(), 2);
+        $total = $this->getPriceAfterDiscount() + $this->getTaxValue();
+        return round($total, 2);
     }
 }
diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php
index b0f91f0de..6a0d28b2c 100644
--- a/themes/default/views/store/checkout.blade.php
+++ b/themes/default/views/store/checkout.blade.php
@@ -237,7 +237,7 @@ function couponForm() {
                 payment_method: '',
                 coupon_code: '',
                 submitted: false,
-                totalPrice: {{ $discountedprice }},
+                totalPrice: {{ $total }},
                 couponDiscountedValue: 0,
 
 

From 17d2aad0c98ab57a296ec9280e388f5dc143e932 Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Fri, 24 May 2024 10:05:28 +0200
Subject: [PATCH 328/514] [bug]: Fix descriptions overflowing (adjusted to
 Pterodactyl's Description) [Feature]: Location description label on server
 create (optional setting)

---
 ...41233_update_description_servers_table.php | 32 +++++++++++++++++++
 ...551_update_description_locations_table.php | 32 +++++++++++++++++++
 ..._22_152306_add_location_settings_table.php | 16 ++++++++++
 3 files changed, 80 insertions(+)
 create mode 100644 database/migrations/2024_05_22_141233_update_description_servers_table.php
 create mode 100644 database/migrations/2024_05_22_143551_update_description_locations_table.php
 create mode 100644 database/settings/2024_05_22_152306_add_location_settings_table.php

diff --git a/database/migrations/2024_05_22_141233_update_description_servers_table.php b/database/migrations/2024_05_22_141233_update_description_servers_table.php
new file mode 100644
index 000000000..e0964c529
--- /dev/null
+++ b/database/migrations/2024_05_22_141233_update_description_servers_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->text('description')->nullable()->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('servers', function (Blueprint $table) {
+            $table->string('description')->nullable()->change();
+        });
+    }
+};
diff --git a/database/migrations/2024_05_22_143551_update_description_locations_table.php b/database/migrations/2024_05_22_143551_update_description_locations_table.php
new file mode 100644
index 000000000..e2b70688b
--- /dev/null
+++ b/database/migrations/2024_05_22_143551_update_description_locations_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('locations', function (Blueprint $table) {
+            $table->text('description')->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('locations', function (Blueprint $table) {
+            $table->string('description')->change();
+        });
+    }
+};
diff --git a/database/settings/2024_05_22_152306_add_location_settings_table.php b/database/settings/2024_05_22_152306_add_location_settings_table.php
new file mode 100644
index 000000000..aaa01e040
--- /dev/null
+++ b/database/settings/2024_05_22_152306_add_location_settings_table.php
@@ -0,0 +1,16 @@
+<?php
+
+use Spatie\LaravelSettings\Migrations\SettingsMigration;
+
+return new class extends SettingsMigration
+{
+    public function up(): void
+    {
+        $this->migrator->add('server.location_description_enabled',false);
+    }
+
+    public function down(): void
+    {
+        $this->migrator->delete('server.location_description_enabled');
+    }
+};

From f57ee4674dce3fd6305a59e77fcee8c0daaff291 Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Sat, 25 May 2024 18:42:49 -0300
Subject: [PATCH 329/514] Final organization of resources

I changed a little the way the Webhook responds to the MercadoPago, better filtering requests and expected values, I also added to getRedirectUrl a check necessary for the MercadoPago Webhook to work.
---
 .../MercadoPago/MercadoPagoExtension.php      | 63 ++++++++++++-------
 lang/en.json                                  |  1 +
 2 files changed, 43 insertions(+), 21 deletions(-)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index 5bb1805f6..82a067722 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -39,6 +39,15 @@ public static function getConfig(): array
 
     public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
     {
+        /**
+         * For Mercado Pago to work correctly,
+         * it is necessary to use SSL and the app.url must start with "https://",
+         * this is necessary so that the webhook receives the information and not an error.
+         */
+        if (!str_contains(config('app.url'), 'https://')) {
+            throw new Exception(__('It is not possible to purchase via MercadoPago: APP_URL does not have HTTPS, required by Mercado Pago.'));
+        }
+
         $user = Auth::user();
         $user = User::findOrFail($user->id);
         $url = 'https://api.mercadopago.com/checkout/preferences';
@@ -61,7 +70,6 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                     [
                         'title' => "Order #{$payment->id} - " . $shopProduct->name,
                         'quantity' => 1,
-                        // convert to float
                         'unit_price' => floatval($totalPriceString),
                         'currency_id' => $shopProduct->currency_code,
                     ],
@@ -90,42 +98,50 @@ static function Success(Request $request): void
         $payment = Payment::findOrFail($request->input('payment'));
         $payment->status = PaymentStatus::PROCESSING;
         $payment->save();
-        Redirect::route('home')->with('success', 'Your payment is being processed')->send();
+        Redirect::route('home')->with('success', 'Your payment is being processed!')->send();
         return;
     }
 
     static function Webhook(Request $request): JsonResponse
     {
         $topic = $request->input('topic');
-        if ($topic === 'merchant_order') {
-            // ignore other types IPN 
-            return response()->json(['success' => true]);
-        } else if ($topic === 'payment') {
-            // ignore other types IPN 
+        $action = $request->input('action');
+
+        /**
+         * Mercado Pago sends several requests for information in the webhook,
+         *  but most are for other types of API, and that is why it is filtered here.
+         */
+        if ($topic && ($topic === 'merchant_order' || $topic === 'payment')) {
             return response()->json(['success' => true]);
-        } else {
-            try {
-                $notificationId = $request->input('data_id') || $request->input('data.id') || "unknown";
-                if ($notificationId == 'unknown') {
-                    return response()->json(['success' => false]);
-                } else if ($notificationId == '123456') {
-                    // mercado pago api test
-                    return response()->json(['success' => true]);
-                } else {
+        }
+
+        try {
+            if($action) {
+                $notification = $request['data']['id'];
+
+                // Filter the API for payments
+                if (!$notification || !$action) return response()->json(['success' => false], 400);
+                // Mercado pago test api, for testing webhook request
+                if ($notification == '123456') return response()->json(['success' => true], 200);
+
+                /**
+                 * Check action have payment.*, 
+                 * what is expected for this type of api
+                 */
+                if (str_contains($action, 'payment')) {
                     $url = "https://api.mercadopago.com/v1/payments/" . $notificationId;
                     $settings = new MercadoPagoSettings();
                     $response = Http::withHeaders([
                         'Content-Type' => 'application/json',
                         'Authorization' => 'Bearer ' . $settings->access_token,
                     ])->get($url);
-
                     if ($response->successful()) {
                         $mercado = $response->json();
                         $status = $mercado['status'];
                         $payment = Payment::findOrFail($mercado['metadata']['crtl_panel_payment_id']);
                         $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
                         if ($status == "approved") {
-                            // avoids double additions, if the user enters after the webhook has already added the credits
+                            // Avoid double addition of credits, whether due to double requests from the paid market, or a malicious user
                             if ($payment->status !== PaymentStatus::PAID) {
                                 $user = User::findOrFail($payment->user_id);
                                 $payment->status = PaymentStatus::PAID;
@@ -145,12 +161,17 @@ static function Webhook(Request $request): JsonResponse
                             $payment->save();
                             event(new PaymentEvent($user, $payment, $shopProduct));
                         }
+                        return response()->json(['success' => true]);
+                    } else {
+                        return response()->json(['success' => false]);
                     }
+                } else {
+                    return response()->json(['success' => false]);
                 }
-            } catch (Exception $ex) {
-                Log::error('MercadoPago Webhook(IPN) Payment: ' . $ex->getMessage());
-                return response()->json(['success' => false]);
             }
+        } catch (Exception $ex) {
+            Log::error('MercadoPago Webhook(IPN) Payment: ' . $ex->getMessage());
+            return response()->json(['success' => false]);
         }
         return response()->json(['success' => true]);
     }
diff --git a/lang/en.json b/lang/en.json
index 633a4ec2c..070a6eb1e 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -296,6 +296,7 @@
     "Everyone": "Everyone",
     "Clients": "Clients",
     "Enable Ticketsystem": "Enable Ticketsystem",
+    "It is not possible to purchase via MercadoPago: APP_URL does not have HTTPS, required by Mercado Pago":"It is not possible to purchase via MercadoPago: APP_URL does not have HTTPS, required by Mercado Pago",
     "PayPal Client-ID": "PayPal Client-ID",
     "PayPal Secret-Key": "PayPal Secret-Key",
     "PayPal Sandbox Client-ID": "PayPal Sandbox Client-ID",

From 400434eb18abf1dbe816254d65549ccca800464a Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 09:49:34 +0200
Subject: [PATCH 330/514] ADD: more feature to the main readme

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 291c86cff..48ae18dad 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,8 @@ CtrlPanel offers an easy-to-use and free billing solution for all starting and e
 - Account Management
 - Admin Dashboard and Tools
 - Addon Support
-- and more!
+- Multiple Languages Supported
+- and More!
 
 ## ⛰️ Live Demo
 

From 35a4e35830f54eb83a674178252094a6d5b42e24 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 09:49:52 +0200
Subject: [PATCH 331/514] ADD: discord link to main readme

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 48ae18dad..9c5dcfb90 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ Roadmap: [CtrlPanel Roadmap](https://github.com/orgs/Ctrlpanel-gg/projects/1)
 
 ## 🗣️ Discussion / Ask for Help
 
-For any general or technical questions, join CtrlPanel Discord for finding answers to your question. If you cannot find the information you need, feel free to ask.
+For any general or technical questions, join CtrlPanel [Discord](https://discord.gg/4Y6HjD2uyU) for finding answers to your question. If you cannot find the information you need, feel free to ask.
 
 ## 🤝 Contributing
 

From cb7acf9b5181afaba7a933f606f65baa8fe800ab Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 09:50:16 +0200
Subject: [PATCH 332/514] UPDATE: updated license

---
 LICENSE                          | 682 ++++++++++++++++++++++++++++++-
 contributor_license_agreement.md |  96 +++++
 2 files changed, 757 insertions(+), 21 deletions(-)
 create mode 100644 contributor_license_agreement.md

diff --git a/LICENSE b/LICENSE
index 00e2a0b66..29ebfa545 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,661 @@
-MIT License
-
-Copyright (c) 2021 CtrlPanel.gg
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<https://www.gnu.org/licenses/>.
\ No newline at end of file
diff --git a/contributor_license_agreement.md b/contributor_license_agreement.md
new file mode 100644
index 000000000..05df29748
--- /dev/null
+++ b/contributor_license_agreement.md
@@ -0,0 +1,96 @@
+Thank you for your interest in CtrlPanel-gg ("CtrlPanel Developers"). To clarify the intellectual property license
+granted with Contributions from any person or entity, the CtrlPanel Developers
+must have on file a signed Contributor License Agreement ("CLA")
+from each Contributor, indicating agreement with the license
+terms below. This agreement is for your protection as a Contributor
+as well as the protection of the CtrlPanel Developers and its users. It does not
+change your rights to use your own Contributions for any other purpose.
+
+You accept and agree to the following terms and conditions for Your
+Contributions (present and future) that you submit to the CtrlPanel Developers. In
+return, the CtrlPanel Developers shall not use Your Contributions in a way that
+is contrary to the public benefit or inconsistent with its nonprofit
+status and bylaws in effect at the time of the Contribution. Except
+for the license granted herein to the CtrlPanel Developers and recipients of
+software distributed by the CtrlPanel Developers, You reserve all right, title,
+and interest in and to Your Contributions.
+1. Definitions.
+   "You" (or "Your") shall mean the copyright owner or legal entity
+   authorized by the copyright owner that is making this Agreement
+   with the CtrlPanel Developers. For legal entities, the entity making a
+   Contribution and all other entities that control, are controlled
+   by, or are under common control with that entity are considered to
+   be a single Contributor. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+   "Contribution" shall mean any original work of authorship,
+   including any modifications or additions to an existing work, that
+   is intentionally submitted by You to the CtrlPanel Developers for inclusion
+   in, or documentation of, any of the products owned or managed by
+   the CtrlPanel Developers (the "Work"). For the purposes of this definition,
+   "submitted" means any form of electronic, verbal, or written
+   communication sent to the CtrlPanel Developers or its representatives,
+   including but not limited to communication on electronic mailing
+   lists, source code control systems, and issue tracking systems that
+   are managed by, or on behalf of, the CtrlPanel Developers for the purpose of
+   discussing and improving the Work, but excluding communication that
+   is conspicuously marked or otherwise designated in writing by You
+   as "Not a Contribution."
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this Agreement, You hereby grant to the CtrlPanel Developers and to
+   recipients of software distributed by the CtrlPanel Developers a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare derivative works of,
+   publicly display, publicly perform, sublicense, and distribute Your
+   Contributions and such derivative works.
+3. Grant of Patent License. Subject to the terms and conditions of
+   this Agreement, You hereby grant to the CtrlPanel Developers and to
+   recipients of software distributed by the CtrlPanel Developers a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have
+   made, use, offer to sell, sell, import, and otherwise transfer the
+   Work, where such license applies only to those patent claims
+   licensable by You that are necessarily infringed by Your
+   Contribution(s) alone or by combination of Your Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If any
+   entity institutes patent litigation against You or any other entity
+   (including a cross-claim or counterclaim in a lawsuit) alleging
+   that your Contribution, or the Work to which you have contributed,
+   constitutes direct or contributory patent infringement, then any
+   patent licenses granted to that entity under this Agreement for
+   that Contribution or Work shall terminate as of the date such
+   litigation is filed.
+4. You represent that you are legally entitled to grant the above
+   license. If your employer(s) has rights to intellectual property
+   that you create that includes your Contributions, you represent
+   that you have received permission to make Contributions on behalf
+   of that employer, that your employer has waived such rights for
+   your Contributions to the CtrlPanel Developers, or that your employer has
+   executed a separate Corporate CLA with the CtrlPanel Developers.
+5. You represent that each of Your Contributions is Your original
+   creation (see section 7 for submissions on behalf of others). You
+   represent that Your Contribution submissions include complete
+   details of any third-party license or other restriction (including,
+   but not limited to, related patents and trademarks) of which you
+   are personally aware and which are associated with any part of Your
+   Contributions.
+6. You are not expected to provide support for Your Contributions,
+   except to the extent You desire to provide support. You may provide
+   support for free, for a fee, or not at all. Unless required by
+   applicable law or agreed to in writing, You provide Your
+   Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+   OF ANY KIND, either express or implied, including, without
+   limitation, any warranties or conditions of TITLE, NON-
+   INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+7. Should You wish to submit work that is not Your original creation,
+   You may submit it to the CtrlPanel Developers separately from any
+   Contribution, identifying the complete details of its source and of
+   any license or other restriction (including, but not limited to,
+   related patents, trademarks, and license agreements) of which you
+   are personally aware, and conspicuously marking the work as
+   "Submitted on behalf of a third-party: [named here]".
+8. You agree to notify the CtrlPanel Developers of any facts or circumstances of
+   which you become aware that would make these representations
+   inaccurate in any respect.

From 4a8ba2e5c8f4c2d02d12a19afb97de2817761a10 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:04:52 +0200
Subject: [PATCH 333/514] UPDATE: contributing.md

---
 .github/CONTRIBUTING.md | 32 ++++++++++++++++++--------------
 lang/README.md          | 10 ++++++++++
 2 files changed, 28 insertions(+), 14 deletions(-)
 create mode 100644 lang/README.md

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 72eb32a7b..6f0a54f9e 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -6,29 +6,33 @@ Thank you for considering contributing to this repository! Before making a contr
 
 Check the open issues to see if there's something you can contribute to. If you have an idea or encounter a bug that's not already listed, feel free to create a new issue and wait for feedback from the development team.
 
-## 🤝 Code of Conduct
+## 🤝 Code of Conduct & Contributor License
 
-Please adhere to our [Code of Conduct](https://github.com/Ctrlpanel-gg/panel/blob/main/.github/CODE_OF_CONDUCT.md) in all your interactions with the project.
+Please adhere to our [Code of Conduct](https://github.com/Ctrlpanel-gg/panel/blob/main/.github/CODE_OF_CONDUCT.md) and our [Contributor License](https://github.com/Ctrlpanel-gg/panel/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md) in all your interactions with the project.
 
 ## 🌍 Localization
 
-If you add any strings that are displayed on the frontend, please localize them using the following format:
-```
-"New String" -> {{ __('New String') }}
-```
-After adding localized strings, run the following command to generate localization files:
-```cmd
-php artisan translatable:export en
-```
+Please read our [Localization Guide](https://github.com/Ctrlpanel-gg/panel/blob/main/lang/README.md) on how to manage and add localization to the project.
 
 ## 🚀 Pull Request Process
 
-1. Give your pull request (PR) a clear and descriptive title that summarizes the changes.
-2. The development team will review your code and provide feedback or approve/merge it when appropriate.
-3. Ensure that your PR follows our Code of Conduct and coding style guidelines.
+1. Provide a clear and descriptive title for your pull request (PR) summarizing the changes.
+2. If your PR is not yet finished, correctly mark it as a draft and mention any errors it's correcting.
+3. The development team will review your code and offer feedback or approve/merge it as necessary.
+4. Ensure that your PR adheres to our Code of Conduct and coding style guidelines.
+5. Test your changes thoroughly to ensure they function as expected.
+6. Include relevant documentation updates if applicable.
+7. Address any review comments promptly to expedite the review process.
 
 ### 💻 Coding Style
 
-We follow the PSR12 code standard for PHP.
+We adhere to the PSR12 code standard for PHP.
+
+- Follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) commit norms.
+- Make clear and concise commits.
+- Name your PR branch as [action]/what-you-are-doing.
+- Make clear commits, one per action, and include comments.
+
+⚠️ **Important Note:** The owner of the project has the final decision, and the development team of CtrlPanel reserves the right to close incorrect PRs. PRs that remain inactive or invalid for an extended period may also be subject to closure.
 
 Thank you for your contributions! 🎉
diff --git a/lang/README.md b/lang/README.md
new file mode 100644
index 000000000..89edaeb97
--- /dev/null
+++ b/lang/README.md
@@ -0,0 +1,10 @@
+# 🌍 Localization
+
+If you add any strings that are displayed on the frontend, please localize them using the following format:
+```
+"New String" -> {{ __('New String') }}
+```
+After adding localized strings, run the following command to generate localization files:
+```cmd
+php artisan translatable:export en
+```

From 2c2ec5e776567f27d6dc849b2ee399f9de6a5c8e Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:08:10 +0200
Subject: [PATCH 334/514] UPDATE: updated the bug and feature template to not
 include default title

---
 .github/ISSUE_TEMPLATE/bug.yml     | 1 -
 .github/ISSUE_TEMPLATE/feature.yml | 1 -
 2 files changed, 2 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index f9e8e9ec3..b823ace8a 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -1,6 +1,5 @@
 name: "\U0001F41B Bug report"
 description: Create a report to help us improve
-title: "[Bug] "
 labels: ["bug"]
 body:
   - type: textarea
diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml
index 6d628f97c..e61d14909 100644
--- a/.github/ISSUE_TEMPLATE/feature.yml
+++ b/.github/ISSUE_TEMPLATE/feature.yml
@@ -1,6 +1,5 @@
 name: "\U0001F680 Feature request"
 description: Suggest a feature or idea for this project
-title: "[Feature] "
 labels: ["feature"]
 body:
   - type: textarea

From be595e904744d257789f14f70718d16b65688232 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:08:31 +0200
Subject: [PATCH 335/514] FIX: some error in the github documentations

---
 .github/CONTRIBUTING.md          | 1 -
 .github/PULL_REQUEST_TEMPLATE.md | 2 +-
 .github/SECURITY.md              | 2 ++
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 6f0a54f9e..c00a9e604 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -29,7 +29,6 @@ Please read our [Localization Guide](https://github.com/Ctrlpanel-gg/panel/blob/
 We adhere to the PSR12 code standard for PHP.
 
 - Follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) commit norms.
-- Make clear and concise commits.
 - Name your PR branch as [action]/what-you-are-doing.
 - Make clear commits, one per action, and include comments.
 
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 89224a428..7da279d75 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
 ✨ Thank you for your contribution to our project! Before you submit your pull request, please take a moment to review and complete the following
 
-⚠️ Please modify this template below and if not already done, read our pull request rules, Thanks!
+⚠️ Please modify this template below and if not already done, read our contributing rules in .github folder, Thanks!
 
 Ensure that your pull request meets the following criteria:
 
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index 278e81e71..d53e5a6eb 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -12,6 +12,8 @@ At this time, we only accept vulnerability reports through GitHub Advisories. We
 
 ## Supported Versions
 
+- Latests
+
 ### ControlPanel Versions
 
 We strongly recommend using or upgrading to the latest version of ControlPanel to ensure you have access to the latest security fixes and enhancements.

From e52df329cfb93ed13e8cf3866d88c267bdff887b Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:29:28 +0200
Subject: [PATCH 336/514] FIX: trying to fix a strange issue whit the CLA

---
 .../CONTRIBUTOR_LICENSE_AGREEMENT.md                              | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename contributor_license_agreement.md => .github/CONTRIBUTOR_LICENSE_AGREEMENT.md (100%)

diff --git a/contributor_license_agreement.md b/.github/CONTRIBUTOR_LICENSE_AGREEMENT.md
similarity index 100%
rename from contributor_license_agreement.md
rename to .github/CONTRIBUTOR_LICENSE_AGREEMENT.md

From 487a7f1c8e0cca5faa10e3d4afdae3d9a98ab1d5 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:29:46 +0200
Subject: [PATCH 337/514] FIX: fixed the strange issue whit the CLA

---
 ...BUTOR_LICENSE_AGREEMENT.md => CONTRIBUTOR_LICENSE_AGREEMENT.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename .github/CONTRIBUTOR_LICENSE_AGREEMENT.md => CONTRIBUTOR_LICENSE_AGREEMENT.md (100%)

diff --git a/.github/CONTRIBUTOR_LICENSE_AGREEMENT.md b/CONTRIBUTOR_LICENSE_AGREEMENT.md
similarity index 100%
rename from .github/CONTRIBUTOR_LICENSE_AGREEMENT.md
rename to CONTRIBUTOR_LICENSE_AGREEMENT.md

From 5dc6aabba81ebbde6122d47187f8dd2aa0d0e5b3 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:55:06 +0200
Subject: [PATCH 338/514] UPDATED: updated the development docker to use the
 standalone one whit more tools

---
 docker/development/docker-compose.yml |  44 ++-
 docker/development/nginx/Dockerfile   |  10 -
 docker/development/nginx/default.conf |  20 --
 docker/development/nginx/nginx.conf   |  29 --
 docker/development/php/Dockerfile     |  18 --
 docker/development/php/www.conf       | 439 --------------------------
 6 files changed, 21 insertions(+), 539 deletions(-)
 delete mode 100644 docker/development/nginx/Dockerfile
 delete mode 100644 docker/development/nginx/default.conf
 delete mode 100644 docker/development/nginx/nginx.conf
 delete mode 100644 docker/development/php/Dockerfile
 delete mode 100644 docker/development/php/www.conf

diff --git a/docker/development/docker-compose.yml b/docker/development/docker-compose.yml
index 16c9bf94f..4d31230a7 100644
--- a/docker/development/docker-compose.yml
+++ b/docker/development/docker-compose.yml
@@ -1,21 +1,20 @@
 version: '3'
 
-networks:
-  laravel:
-
+// TODO: add wings and pterodactyl
 services:
-  nginx:
+
+  controlpanel_standalone:
     build:
       context: ../../
-      dockerfile: docker/development/nginx/Dockerfile
-    container_name: controlpanel_nginx
+      dockerfile: ./docker/standalone/Dockerfile
+    container_name: controlpanel_standalone
+    restart: on-failure
     ports:
-      - 80:80
+      - "80:80"
+      - "443:443"
     volumes:
-      - "../../:/var/www/html"
-    depends_on:
-      - php
-      - mysql
+      - './website_files:/var/www/html:rw' # change it to your project
+      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
     networks:
       - laravel
 
@@ -36,16 +35,6 @@ services:
     networks:
       - laravel
 
-  php:
-    build:
-      context: ../../
-      dockerfile: docker/development/php/Dockerfile
-    container_name: controlpanel_php
-    volumes:
-      - "../../:/var/www/html"
-    networks:
-      - laravel
-
   phpmyadmin:
     image: phpmyadmin/phpmyadmin
     container_name: controlpanel_phpmyadmin
@@ -61,5 +50,14 @@ services:
     networks:
       - laravel
 
-volumes:
-  mysql:
\ No newline at end of file
+  redis:
+    image: redis
+    container_name: controlpanel_redis
+    restart: unless-stopped
+    ports:
+      - "6379:6379"
+    networks:
+      - laravel
+
+networks:
+  laravel:
diff --git a/docker/development/nginx/Dockerfile b/docker/development/nginx/Dockerfile
deleted file mode 100644
index deca865f1..000000000
--- a/docker/development/nginx/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM nginx:stable-alpine
-
-RUN addgroup -g 1000 laravel && adduser -G laravel -g laravel -s /bin/sh -D laravel
-
-ADD ./docker/development/nginx/nginx.conf /etc/nginx/
-ADD ./docker/development/nginx/default.conf /etc/nginx/conf.d/
-
-RUN mkdir -p /var/www/html
-
-RUN chown laravel:laravel /var/www/html
diff --git a/docker/development/nginx/default.conf b/docker/development/nginx/default.conf
deleted file mode 100644
index 282633d76..000000000
--- a/docker/development/nginx/default.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-server {
-    listen 80;
-    index index.php index.html;
-    server_name _;
-    root /var/www/html/public;
-
-    location / {
-        try_files $uri $uri/ /index.php?$query_string;
-    }
-
-    location ~ \.php$ {
-        try_files $uri =404;
-        fastcgi_split_path_info ^(.+\.php)(/.+)$;
-        fastcgi_pass php:9000;
-        fastcgi_index index.php;
-        include fastcgi_params;
-        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-        fastcgi_param PATH_INFO $fastcgi_path_info;
-    }
-}
diff --git a/docker/development/nginx/nginx.conf b/docker/development/nginx/nginx.conf
deleted file mode 100644
index 060e50253..000000000
--- a/docker/development/nginx/nginx.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-user laravel;
-worker_processes  auto;
-
-error_log  /var/log/nginx/error.log warn;
-pid        /var/run/nginx.pid;
-
-events {
-    worker_connections  1024;
-}
-
-http {
-    include       /etc/nginx/mime.types;
-    default_type  application/octet-stream;
-
-    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
-                      '$status $body_bytes_sent "$http_referer" '
-                      '"$http_user_agent" "$http_x_forwarded_for"';
-
-    access_log  /var/log/nginx/access.log  main;
-
-    sendfile        on;
-    #tcp_nopush     on;
-
-    keepalive_timeout  65;
-
-    #gzip  on;
-
-    include /etc/nginx/conf.d/*.conf;
-}
diff --git a/docker/development/php/Dockerfile b/docker/development/php/Dockerfile
deleted file mode 100644
index 3ec761ae7..000000000
--- a/docker/development/php/Dockerfile
+++ /dev/null
@@ -1,18 +0,0 @@
-FROM php:8.1-fpm-buster
-RUN apt-get update \
-  && apt-get install -y build-essential zlib1g-dev default-mysql-client curl gnupg procps vim git unzip libzip-dev libpq-dev libicu-dev libonig-dev libpng-dev libjpeg-dev libfreetype6-dev
-
-RUN docker-php-ext-install mysqli pdo pdo_mysql intl zip gd bcmath
-
-ADD ./docker/development/php/www.conf /usr/local/etc/php-fpm.d/
-
-RUN mkdir -p /var/www/html
-
-RUN addgroup --gid 1000 laravel && adduser --ingroup laravel --uid 1000 --shell /bin/sh --disabled-password --gecos "" laravel
-RUN chown laravel:laravel /var/www/html
-
-WORKDIR /var/www/html
-
-USER laravel
-
-COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
diff --git a/docker/development/php/www.conf b/docker/development/php/www.conf
deleted file mode 100644
index eb028e111..000000000
--- a/docker/development/php/www.conf
+++ /dev/null
@@ -1,439 +0,0 @@
-; Start a new pool named 'www'.
-; the variable $pool can be used in any directive and will be replaced by the
-; pool name ('www' here)
-[www]
-
-; Per pool prefix
-; It only applies on the following directives:
-; - 'access.log'
-; - 'slowlog'
-; - 'listen' (unixsocket)
-; - 'chroot'
-; - 'chdir'
-; - 'php_values'
-; - 'php_admin_values'
-; When not set, the global prefix (or NONE) applies instead.
-; Note: This directive can also be relative to the global prefix.
-; Default Value: none
-;prefix = /path/to/pools/$pool
-
-; Unix user/group of processes
-; Note: The user is mandatory. If the group is not set, the default user's group
-;       will be used.
-user = laravel
-group = laravel
-
-; The address on which to accept FastCGI requests.
-; Valid syntaxes are:
-;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
-;                            a specific port;
-;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
-;                            a specific port;
-;   'port'                 - to listen on a TCP socket to all addresses
-;                            (IPv6 and IPv4-mapped) on a specific port;
-;   '/path/to/unix/socket' - to listen on a unix socket.
-; Note: This value is mandatory.
-listen = 127.0.0.1:9000
-
-; Set listen(2) backlog.
-; Default Value: 511 (-1 on FreeBSD and OpenBSD)
-;listen.backlog = 511
-
-; Set permissions for unix socket, if one is used. In Linux, read/write
-; permissions must be set in order to allow connections from a web server. Many
-; BSD-derived systems allow connections regardless of permissions. The owner
-; and group can be specified either by name or by their numeric IDs.
-; Default Values: user and group are set as the running user
-;                 mode is set to 0660
-;listen.owner = www-data
-;listen.group = www-data
-;listen.mode = 0660
-; When POSIX Access Control Lists are supported you can set them using
-; these options, value is a comma separated list of user/group names.
-; When set, listen.owner and listen.group are ignored
-;listen.acl_users =
-;listen.acl_groups =
-
-; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.
-; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
-; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
-; must be separated by a comma. If this value is left blank, connections will be
-; accepted from any ip address.
-; Default Value: any
-;listen.allowed_clients = 127.0.0.1
-
-; Specify the nice(2) priority to apply to the pool processes (only if set)
-; The value can vary from -19 (highest priority) to 20 (lower priority)
-; Note: - It will only work if the FPM master process is launched as root
-;       - The pool processes will inherit the master process priority
-;         unless it specified otherwise
-; Default Value: no set
-; process.priority = -19
-
-; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user
-; or group is differrent than the master process user. It allows to create process
-; core dump and ptrace the process for the pool user.
-; Default Value: no
-; process.dumpable = yes
-
-; Choose how the process manager will control the number of child processes.
-; Possible Values:
-;   static  - a fixed number (pm.max_children) of child processes;
-;   dynamic - the number of child processes are set dynamically based on the
-;             following directives. With this process management, there will be
-;             always at least 1 children.
-;             pm.max_children      - the maximum number of children that can
-;                                    be alive at the same time.
-;             pm.start_servers     - the number of children created on startup.
-;             pm.min_spare_servers - the minimum number of children in 'idle'
-;                                    state (waiting to process). If the number
-;                                    of 'idle' processes is less than this
-;                                    number then some children will be created.
-;             pm.max_spare_servers - the maximum number of children in 'idle'
-;                                    state (waiting to process). If the number
-;                                    of 'idle' processes is greater than this
-;                                    number then some children will be killed.
-;  ondemand - no children are created at startup. Children will be forked when
-;             new requests will connect. The following parameter are used:
-;             pm.max_children           - the maximum number of children that
-;                                         can be alive at the same time.
-;             pm.process_idle_timeout   - The number of seconds after which
-;                                         an idle process will be killed.
-; Note: This value is mandatory.
-pm = dynamic
-
-; The number of child processes to be created when pm is set to 'static' and the
-; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
-; This value sets the limit on the number of simultaneous requests that will be
-; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
-; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
-; CGI. The below defaults are based on a server without much resources. Don't
-; forget to tweak pm.* to fit your needs.
-; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
-; Note: This value is mandatory.
-pm.max_children = 5
-
-; The number of child processes created on startup.
-; Note: Used only when pm is set to 'dynamic'
-; Default Value: (min_spare_servers + max_spare_servers) / 2
-pm.start_servers = 2
-
-; The desired minimum number of idle server processes.
-; Note: Used only when pm is set to 'dynamic'
-; Note: Mandatory when pm is set to 'dynamic'
-pm.min_spare_servers = 1
-
-; The desired maximum number of idle server processes.
-; Note: Used only when pm is set to 'dynamic'
-; Note: Mandatory when pm is set to 'dynamic'
-pm.max_spare_servers = 3
-
-; The number of seconds after which an idle process will be killed.
-; Note: Used only when pm is set to 'ondemand'
-; Default Value: 10s
-;pm.process_idle_timeout = 10s;
-
-; The number of requests each child process should execute before respawning.
-; This can be useful to work around memory leaks in 3rd party libraries. For
-; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
-; Default Value: 0
-;pm.max_requests = 500
-
-; The URI to view the FPM status page. If this value is not set, no URI will be
-; recognized as a status page. It shows the following informations:
-;   pool                 - the name of the pool;
-;   process manager      - static, dynamic or ondemand;
-;   start time           - the date and time FPM has started;
-;   start since          - number of seconds since FPM has started;
-;   accepted conn        - the number of request accepted by the pool;
-;   listen queue         - the number of request in the queue of pending
-;                          connections (see backlog in listen(2));
-;   max listen queue     - the maximum number of requests in the queue
-;                          of pending connections since FPM has started;
-;   listen queue len     - the size of the socket queue of pending connections;
-;   idle processes       - the number of idle processes;
-;   active processes     - the number of active processes;
-;   total processes      - the number of idle + active processes;
-;   max active processes - the maximum number of active processes since FPM
-;                          has started;
-;   max children reached - number of times, the process limit has been reached,
-;                          when pm tries to start more children (works only for
-;                          pm 'dynamic' and 'ondemand');
-; Value are updated in real time.
-; Example output:
-;   pool:                 www
-;   process manager:      static
-;   start time:           01/Jul/2011:17:53:49 +0200
-;   start since:          62636
-;   accepted conn:        190460
-;   listen queue:         0
-;   max listen queue:     1
-;   listen queue len:     42
-;   idle processes:       4
-;   active processes:     11
-;   total processes:      15
-;   max active processes: 12
-;   max children reached: 0
-;
-; By default the status page output is formatted as text/plain. Passing either
-; 'html', 'xml' or 'json' in the query string will return the corresponding
-; output syntax. Example:
-;   http://www.foo.bar/status
-;   http://www.foo.bar/status?json
-;   http://www.foo.bar/status?html
-;   http://www.foo.bar/status?xml
-;
-; By default the status page only outputs short status. Passing 'full' in the
-; query string will also return status for each pool process.
-; Example:
-;   http://www.foo.bar/status?full
-;   http://www.foo.bar/status?json&full
-;   http://www.foo.bar/status?html&full
-;   http://www.foo.bar/status?xml&full
-; The Full status returns for each process:
-;   pid                  - the PID of the process;
-;   state                - the state of the process (Idle, Running, ...);
-;   start time           - the date and time the process has started;
-;   start since          - the number of seconds since the process has started;
-;   requests             - the number of requests the process has served;
-;   request duration     - the duration in µs of the requests;
-;   request method       - the request method (GET, POST, ...);
-;   request URI          - the request URI with the query string;
-;   content length       - the content length of the request (only with POST);
-;   user                 - the user (PHP_AUTH_USER) (or '-' if not set);
-;   script               - the main script called (or '-' if not set);
-;   last request cpu     - the %cpu the last request consumed
-;                          it's always 0 if the process is not in Idle state
-;                          because CPU calculation is done when the request
-;                          processing has terminated;
-;   last request memory  - the max amount of memory the last request consumed
-;                          it's always 0 if the process is not in Idle state
-;                          because memory calculation is done when the request
-;                          processing has terminated;
-; If the process is in Idle state, then informations are related to the
-; last request the process has served. Otherwise informations are related to
-; the current request being served.
-; Example output:
-;   ************************
-;   pid:                  31330
-;   state:                Running
-;   start time:           01/Jul/2011:17:53:49 +0200
-;   start since:          63087
-;   requests:             12808
-;   request duration:     1250261
-;   request method:       GET
-;   request URI:          /test_mem.php?N=10000
-;   content length:       0
-;   user:                 -
-;   script:               /home/fat/web/docs/php/test_mem.php
-;   last request cpu:     0.00
-;   last request memory:  0
-;
-; Note: There is a real-time FPM status monitoring sample web page available
-;       It's available in: /usr/local/share/php/fpm/status.html
-;
-; Note: The value must start with a leading slash (/). The value can be
-;       anything, but it may not be a good idea to use the .php extension or it
-;       may conflict with a real PHP file.
-; Default Value: not set
-;pm.status_path = /status
-
-; The ping URI to call the monitoring page of FPM. If this value is not set, no
-; URI will be recognized as a ping page. This could be used to test from outside
-; that FPM is alive and responding, or to
-; - create a graph of FPM availability (rrd or such);
-; - remove a server from a group if it is not responding (load balancing);
-; - trigger alerts for the operating team (24/7).
-; Note: The value must start with a leading slash (/). The value can be
-;       anything, but it may not be a good idea to use the .php extension or it
-;       may conflict with a real PHP file.
-; Default Value: not set
-;ping.path = /ping
-
-; This directive may be used to customize the response of a ping request. The
-; response is formatted as text/plain with a 200 response code.
-; Default Value: pong
-;ping.response = pong
-
-; The access log file
-; Default: not set
-;access.log = log/$pool.access.log
-
-; The access log format.
-; The following syntax is allowed
-;  %%: the '%' character
-;  %C: %CPU used by the request
-;      it can accept the following format:
-;      - %{user}C for user CPU only
-;      - %{system}C for system CPU only
-;      - %{total}C  for user + system CPU (default)
-;  %d: time taken to serve the request
-;      it can accept the following format:
-;      - %{seconds}d (default)
-;      - %{miliseconds}d
-;      - %{mili}d
-;      - %{microseconds}d
-;      - %{micro}d
-;  %e: an environment variable (same as $_ENV or $_SERVER)
-;      it must be associated with embraces to specify the name of the env
-;      variable. Some exemples:
-;      - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
-;      - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
-;  %f: script filename
-;  %l: content-length of the request (for POST request only)
-;  %m: request method
-;  %M: peak of memory allocated by PHP
-;      it can accept the following format:
-;      - %{bytes}M (default)
-;      - %{kilobytes}M
-;      - %{kilo}M
-;      - %{megabytes}M
-;      - %{mega}M
-;  %n: pool name
-;  %o: output header
-;      it must be associated with embraces to specify the name of the header:
-;      - %{Content-Type}o
-;      - %{X-Powered-By}o
-;      - %{Transfert-Encoding}o
-;      - ....
-;  %p: PID of the child that serviced the request
-;  %P: PID of the parent of the child that serviced the request
-;  %q: the query string
-;  %Q: the '?' character if query string exists
-;  %r: the request URI (without the query string, see %q and %Q)
-;  %R: remote IP address
-;  %s: status (response code)
-;  %t: server time the request was received
-;      it can accept a strftime(3) format:
-;      %d/%b/%Y:%H:%M:%S %z (default)
-;      The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
-;      e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t
-;  %T: time the log has been written (the request has finished)
-;      it can accept a strftime(3) format:
-;      %d/%b/%Y:%H:%M:%S %z (default)
-;      The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
-;      e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t
-;  %u: remote user
-;
-; Default: "%R - %u %t \"%m %r\" %s"
-;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
-
-; The log file for slow requests
-; Default Value: not set
-; Note: slowlog is mandatory if request_slowlog_timeout is set
-;slowlog = log/$pool.log.slow
-
-; The timeout for serving a single request after which a PHP backtrace will be
-; dumped to the 'slowlog' file. A value of '0s' means 'off'.
-; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
-; Default Value: 0
-;request_slowlog_timeout = 0
-
-; Depth of slow log stack trace.
-; Default Value: 20
-;request_slowlog_trace_depth = 20
-
-; The timeout for serving a single request after which the worker process will
-; be killed. This option should be used when the 'max_execution_time' ini option
-; does not stop script execution for some reason. A value of '0' means 'off'.
-; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
-; Default Value: 0
-;request_terminate_timeout = 0
-
-; The timeout set by 'request_terminate_timeout' ini option is not engaged after
-; application calls 'fastcgi_finish_request' or when application has finished and
-; shutdown functions are being called (registered via register_shutdown_function).
-; This option will enable timeout limit to be applied unconditionally
-; even in such cases.
-; Default Value: no
-;request_terminate_timeout_track_finished = no
-
-; Set open file descriptor rlimit.
-; Default Value: system defined value
-;rlimit_files = 1024
-
-; Set max core size rlimit.
-; Possible Values: 'unlimited' or an integer greater or equal to 0
-; Default Value: system defined value
-;rlimit_core = 0
-
-; Chroot to this directory at the start. This value must be defined as an
-; absolute path. When this value is not set, chroot is not used.
-; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
-; of its subdirectories. If the pool prefix is not set, the global prefix
-; will be used instead.
-; Note: chrooting is a great security feature and should be used whenever
-;       possible. However, all PHP paths will be relative to the chroot
-;       (error_log, sessions.save_path, ...).
-; Default Value: not set
-;chroot =
-
-; Chdir to this directory at the start.
-; Note: relative path can be used.
-; Default Value: current directory or / when chroot
-;chdir = /var/www
-
-; Redirect worker stdout and stderr into main error log. If not set, stdout and
-; stderr will be redirected to /dev/null according to FastCGI specs.
-; Note: on highloaded environement, this can cause some delay in the page
-; process time (several ms).
-; Default Value: no
-;catch_workers_output = yes
-
-; Decorate worker output with prefix and suffix containing information about
-; the child that writes to the log and if stdout or stderr is used as well as
-; log level and time. This options is used only if catch_workers_output is yes.
-; Settings to "no" will output data as written to the stdout or stderr.
-; Default value: yes
-;decorate_workers_output = no
-
-; Clear environment in FPM workers
-; Prevents arbitrary environment variables from reaching FPM worker processes
-; by clearing the environment in workers before env vars specified in this
-; pool configuration are added.
-; Setting to "no" will make all environment variables available to PHP code
-; via getenv(), $_ENV and $_SERVER.
-; Default Value: yes
-;clear_env = no
-
-; Limits the extensions of the main script FPM will allow to parse. This can
-; prevent configuration mistakes on the web server side. You should only limit
-; FPM to .php extensions to prevent malicious users to use other extensions to
-; execute php code.
-; Note: set an empty value to allow all extensions.
-; Default Value: .php
-;security.limit_extensions = .php .php3 .php4 .php5 .php7
-
-; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
-; the current environment.
-; Default Value: clean env
-;env[HOSTNAME] = $HOSTNAME
-;env[PATH] = /usr/local/bin:/usr/bin:/bin
-;env[TMP] = /tmp
-;env[TMPDIR] = /tmp
-;env[TEMP] = /tmp
-
-; Additional php.ini defines, specific to this pool of workers. These settings
-; overwrite the values previously defined in the php.ini. The directives are the
-; same as the PHP SAPI:
-;   php_value/php_flag             - you can set classic ini defines which can
-;                                    be overwritten from PHP call 'ini_set'.
-;   php_admin_value/php_admin_flag - these directives won't be overwritten by
-;                                     PHP call 'ini_set'
-; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
-
-; Defining 'extension' will load the corresponding shared extension from
-; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
-; overwrite previously defined php.ini values, but will append the new value
-; instead.
-
-; Note: path INI options can be relative and will be expanded with the prefix
-; (pool, global or /usr/local)
-
-; Default Value: nothing is defined by default except the values in php.ini and
-;                specified at startup with the -d argument
-;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
-;php_flag[display_errors] = off
-;php_admin_value[error_log] = /var/log/fpm-php.www.log
-;php_admin_flag[log_errors] = on
-;php_admin_value[memory_limit] = 32M

From 984330a475a1f93599fb114421531dc5909fcbe7 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 28 May 2024 10:55:26 +0200
Subject: [PATCH 339/514] UPDATE: updated the readme of the developement docker

---
 docker/development/README.md | 42 +++++++++++++-----------------------
 1 file changed, 15 insertions(+), 27 deletions(-)

diff --git a/docker/development/README.md b/docker/development/README.md
index 1838becbc..46f3f9c95 100644
--- a/docker/development/README.md
+++ b/docker/development/README.md
@@ -1,35 +1,23 @@
-⚠ Caution: These instructions have not been updated since before version 1.0 of the project. Therefore, there may be inaccuracies, instability, or non-functional aspects. Proceed with care. (you may want to take a look at the standalone docker instread)
+# 🐳 Docker Development Environment
 
-# Building the development environment
+This development environment utilizes standalone Docker with necessary tools pre-configured.
 
-cd into the project directory and run the following command: `sh bin/startdocker.sh`
-This should start building the images and start the containers.
+## Included Services
+- Redis
+- MySQL
+- Tools like phpMyAdmin
 
-After that you need to go into the controlpanel_php container and run some commands:
+## Not Included Services (for the moment)
+- Pterodactyl
+- Wings
 
-Type `docker exec -it controlpanel_php ash` to go into the container and run the following commands:
+Feel free to modify the Docker Compose file to remove any services you already have.
 
-```shell
-composer install
-cp .env.example .env
-php artisan key:generate --force
-php artisan storage:link
-php artisan migrate --seed --force
-```
+## Setting Up the Testing Environment
 
-## Setting up testing environment
+1. **Manual Setup:** As mentioned in the standalone Docker guide, you will need to manually set up some components.
+2. **Custom Configuration:** Modify the CtrlPanel Docker Compose configuration to use your current project as a base. If you point it to an empty folder, it will clone the repository, and you won't see your changes immediately.
 
-Create the .env.testing file to your needs. Then once done you need to go into your phpmyadmin to create a new database named __controlpanel_test__.
-Visit http://127.0.0.1:8080/ and create your database.
+For detailed setup instructions, refer to the standalone Docker documentation.
 
-Now you're ready to run the following commands which switches to the testing config, migrates the test database and seeds it.
-After that you can switch back to your dev environment again. Clear the config from cache so changes will be instantly available.
-
-```shell
-php artisan key:generate --force --env=testing
-php artisan migrate:fresh --seed --env=testing
-```
-
-Now when running tests with PHPUnit it will use your testing database and not your local development one.
-This is configured in the __phpunit.xml__. You can run your tests by running the command like this. Just type and enter.
-`php artisan test`.
+⚠ Caution: These instructions have not been finished. Therefore, there may be inaccuracies, instability, or non-functional aspects. Proceed with care.

From 4e0370b051ecd82c895a93607bd69b23b4c41623 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 28 May 2024 21:55:01 +0200
Subject: [PATCH 340/514] Fix explode null parameter, Update dev docker compose
 file

---
 .../development/{docker-compose.yml => compose.yaml}  | 11 ++++-------
 .../standalone/{docker-compose.yml => compose.yaml}   |  0
 2 files changed, 4 insertions(+), 7 deletions(-)
 rename docker/development/{docker-compose.yml => compose.yaml} (83%)
 rename docker/standalone/{docker-compose.yml => compose.yaml} (100%)

diff --git a/docker/development/docker-compose.yml b/docker/development/compose.yaml
similarity index 83%
rename from docker/development/docker-compose.yml
rename to docker/development/compose.yaml
index 4d31230a7..e7169377e 100644
--- a/docker/development/docker-compose.yml
+++ b/docker/development/compose.yaml
@@ -1,8 +1,5 @@
-version: '3'
-
-// TODO: add wings and pterodactyl
 services:
-
+  # TODO: add wings and pterodactyl
   controlpanel_standalone:
     build:
       context: ../../
@@ -13,8 +10,8 @@ services:
       - "80:80"
       - "443:443"
     volumes:
-      - './website_files:/var/www/html:rw' # change it to your project
-      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
+      - '../..:/var/www/html:rw'
+      - './nginx_config:/etc/nginx/conf.d/:rw'
     networks:
       - laravel
 
@@ -31,7 +28,7 @@ services:
       MYSQL_PASSWORD: root
       MYSQL_ROOT_PASSWORD: root
     volumes:
-      - "mysql:/var/lib/mysql:delegated"
+      - "./mysql:/var/lib/mysql:delegated"
     networks:
       - laravel
 
diff --git a/docker/standalone/docker-compose.yml b/docker/standalone/compose.yaml
similarity index 100%
rename from docker/standalone/docker-compose.yml
rename to docker/standalone/compose.yaml

From 0596f7c78240e40de66b4f70dab6f539cb75347a Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 28 May 2024 22:03:37 +0200
Subject: [PATCH 341/514] Update gitignore, Fix explode null parameter

---
 .gitignore              | 3 +++
 config/trustedproxy.php | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index ad9d095b8..aebb0fa86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,6 @@ storage/app/public/logo.png
 public/install/logs.txt
 install.lock
 public/install/logs/installer.log
+public/install/logs/laravel.log
+docker/development/nginx_config
+docker/development/mysql
diff --git a/config/trustedproxy.php b/config/trustedproxy.php
index dc46c31ba..f3b88cd52 100644
--- a/config/trustedproxy.php
+++ b/config/trustedproxy.php
@@ -26,7 +26,7 @@
      * subsequently passed through.
      */
     'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ?
-        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)),
+        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', '')),
 
     /*
      * Or, to trust all proxies that connect

From 78479a025d1621290412b90d18a7f52119c9b749 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 28 May 2024 22:43:11 +0200
Subject: [PATCH 342/514] Update dev compose.yml and gitignore

---
 .gitignore                      | 1 -
 docker/development/compose.yaml | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index aebb0fa86..ee0e3762a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,6 +27,5 @@ storage/app/public/logo.png
 public/install/logs.txt
 install.lock
 public/install/logs/installer.log
-public/install/logs/laravel.log
 docker/development/nginx_config
 docker/development/mysql
diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index e7169377e..3fd698db7 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -4,7 +4,7 @@ services:
     build:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile
-    container_name: controlpanel_standalone
+    container_name: controlpanel_development
     restart: on-failure
     ports:
       - "80:80"

From 299416daa3e37251ca816d5e4447041d86377f9e Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 28 May 2024 23:05:17 +0200
Subject: [PATCH 343/514] Revert explode deprecation fix, move gitignore to
 apropriate folder

---
 .gitignore                    | 2 --
 config/trustedproxy.php       | 2 +-
 docker/development/.gitignore | 3 +++
 3 files changed, 4 insertions(+), 3 deletions(-)
 create mode 100755 docker/development/.gitignore

diff --git a/.gitignore b/.gitignore
index ee0e3762a..ad9d095b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,5 +27,3 @@ storage/app/public/logo.png
 public/install/logs.txt
 install.lock
 public/install/logs/installer.log
-docker/development/nginx_config
-docker/development/mysql
diff --git a/config/trustedproxy.php b/config/trustedproxy.php
index f3b88cd52..dc46c31ba 100644
--- a/config/trustedproxy.php
+++ b/config/trustedproxy.php
@@ -26,7 +26,7 @@
      * subsequently passed through.
      */
     'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ?
-        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', '')),
+        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)),
 
     /*
      * Or, to trust all proxies that connect
diff --git a/docker/development/.gitignore b/docker/development/.gitignore
new file mode 100755
index 000000000..aaec72ce4
--- /dev/null
+++ b/docker/development/.gitignore
@@ -0,0 +1,3 @@
+!.gitignore
+mysql
+nginx_config

From 3a7dc46d94a983d5ffab2acc067029e8e1f971c7 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 09:00:40 +0200
Subject: [PATCH 344/514] Add docker build workflow

---
 .github/workflows/docker-build.yml | 93 ++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 .github/workflows/docker-build.yml

diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
new file mode 100644
index 000000000..166fc8abd
--- /dev/null
+++ b/.github/workflows/docker-build.yml
@@ -0,0 +1,93 @@
+name: Build and Push Docker Images
+
+on:
+  push:
+    branches:
+      - main
+      - docker-github-workflow
+    tags:
+      - '*'
+
+jobs:
+  build-and-push-image:
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      packages: write
+
+    env:
+      REGISTRY: ghcr.io
+      IMAGE_NAME: ${{ github.repository }}
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Log in to the Container registry
+        uses: docker/login-action@v3
+        with:
+          registry: ${{ env.REGISTRY }}
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Extract metadata (tags, labels) for Docker
+        id: meta
+        uses: docker/metadata-action@v5
+        with:
+          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+
+      - name: Build and push Docker image
+        uses: docker/build-push-action@v5
+        with:
+          context: .
+          push: true
+          tags: ${{ steps.meta.outputs.tags }}
+          labels: ${{ steps.meta.outputs.labels }}
+
+
+
+#name: Build and Push Docker Images
+#
+#on:
+#  push:
+#    branches:
+#      - main
+#    tags:
+#      - '*'
+#
+#env:
+#  REGISTRY: ghcr.io
+#  IMAGE_NAME: ${{ github.repository }}
+#
+#jobs:
+#  build-and-push-image:
+#    runs-on: ubuntu-latest
+#    permissions:
+#      contents: read
+#      packages: write
+#
+#    steps:
+#      - name: Checkout repository
+#        uses: actions/checkout@v3
+#
+#      - name: Log in to the Container registry
+#        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+#        with:
+#          registry: ${{ env.REGISTRY }}
+#          username: ${{ github.actor }}
+#          password: ${{ secrets.GITHUB_TOKEN }}
+#
+#      - name: Extract metadata (tags, labels) for Docker
+#        id: meta
+#        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+#        with:
+#          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+#
+#      - name: Build and push Docker image
+#        uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+#        with:
+#          context: .
+#          target: ${{ env.IMAGE_NAME }}
+#          push: true
+#          tags: ${{ steps.meta.outputs.tags }}
+#          labels: ${{ steps.meta.outputs.labels }}

From aa5820cfe922c1a087e42591e2d3a0c6fc14bc53 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 09:02:38 +0200
Subject: [PATCH 345/514] Add Dockerfile location to github workflow

---
 .github/workflows/docker-build.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index 166fc8abd..70d0c9c05 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -41,6 +41,7 @@ jobs:
         with:
           context: .
           push: true
+          file: docker/standalone/Dockerfile
           tags: ${{ steps.meta.outputs.tags }}
           labels: ${{ steps.meta.outputs.labels }}
 

From 1968a977bf2f79044298da04d8d653d366f12315 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 09:22:53 +0200
Subject: [PATCH 346/514] Update standalone compose file

---
 .github/workflows/docker-build.yml | 55 +--------------------------
 docker/development/compose.yaml    | 12 +++---
 docker/standalone/compose.yaml     | 61 ++++++++++++++++++++++++++----
 3 files changed, 61 insertions(+), 67 deletions(-)

diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index 70d0c9c05..54016c792 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -1,15 +1,12 @@
-name: Build and Push Docker Images
+name: Build and Push Docker Image
 
 on:
   push:
-    branches:
-      - main
-      - docker-github-workflow
     tags:
       - '*'
 
 jobs:
-  build-and-push-image:
+  build-and-push-docker-image:
     runs-on: ubuntu-latest
     permissions:
       contents: read
@@ -44,51 +41,3 @@ jobs:
           file: docker/standalone/Dockerfile
           tags: ${{ steps.meta.outputs.tags }}
           labels: ${{ steps.meta.outputs.labels }}
-
-
-
-#name: Build and Push Docker Images
-#
-#on:
-#  push:
-#    branches:
-#      - main
-#    tags:
-#      - '*'
-#
-#env:
-#  REGISTRY: ghcr.io
-#  IMAGE_NAME: ${{ github.repository }}
-#
-#jobs:
-#  build-and-push-image:
-#    runs-on: ubuntu-latest
-#    permissions:
-#      contents: read
-#      packages: write
-#
-#    steps:
-#      - name: Checkout repository
-#        uses: actions/checkout@v3
-#
-#      - name: Log in to the Container registry
-#        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
-#        with:
-#          registry: ${{ env.REGISTRY }}
-#          username: ${{ github.actor }}
-#          password: ${{ secrets.GITHUB_TOKEN }}
-#
-#      - name: Extract metadata (tags, labels) for Docker
-#        id: meta
-#        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
-#        with:
-#          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
-#
-#      - name: Build and push Docker image
-#        uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
-#        with:
-#          context: .
-#          target: ${{ env.IMAGE_NAME }}
-#          push: true
-#          tags: ${{ steps.meta.outputs.tags }}
-#          labels: ${{ steps.meta.outputs.labels }}
diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index 3fd698db7..c3010c59f 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -1,6 +1,6 @@
 services:
   # TODO: add wings and pterodactyl
-  controlpanel_standalone:
+  controlpanel_panel:
     build:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile
@@ -13,7 +13,7 @@ services:
       - '../..:/var/www/html:rw'
       - './nginx_config:/etc/nginx/conf.d/:rw'
     networks:
-      - laravel
+      - controlpanel
 
   mysql:
     image: mysql
@@ -30,7 +30,7 @@ services:
     volumes:
       - "./mysql:/var/lib/mysql:delegated"
     networks:
-      - laravel
+      - controlpanel
 
   phpmyadmin:
     image: phpmyadmin/phpmyadmin
@@ -45,7 +45,7 @@ services:
       - PMA_PASSWORD=root
       - PMA_ARBITRARY=1
     networks:
-      - laravel
+      - controlpanel
 
   redis:
     image: redis
@@ -54,7 +54,7 @@ services:
     ports:
       - "6379:6379"
     networks:
-      - laravel
+      - controlpanel
 
 networks:
-  laravel:
+  controlpanel:
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index cd980a2af..11b3dd85d 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -1,15 +1,60 @@
-version: '3'
-
 services:
-  controlpanel_standalone:
-    build:
-      context: ../../
-      dockerfile: ./docker/standalone/Dockerfile
-    container_name: controlpanel_standalone
-    restart: on-failure
+  controlpanel:
+    image: ghcr.io/jameskitt616/panel:latest
+    container_name: controlpanel_panel
+    restart: unless-stopped
+    depends_on:
+      - redis
     ports:
       - "80:80"
       - "443:443"
     volumes:
       - './website_files:/var/www/html:rw' # change it
       - './nginx_config:/etc/nginx/conf.d/:rw' # change it
+    networks:
+      - controlpanel
+
+  mysql:
+    image: mysql
+    container_name: controlpanel_mysql
+    restart: unless-stopped
+    tty: true
+    ports:
+      - "3306:3306"
+    environment:
+      MYSQL_DATABASE: controlpanel
+      MYSQL_USER: controlpaneluser
+      MYSQL_PASSWORD: root # change it
+      MYSQL_ROOT_PASSWORD: root # change it
+    volumes:
+      - "./mysql:/var/lib/mysql:delegated"
+    networks:
+      - controlpanel
+
+  phpmyadmin:
+    image: phpmyadmin/phpmyadmin
+    container_name: controlpanel_phpmyadmin
+    restart: unless-stopped
+    depends_on:
+      - mysql
+    ports:
+      - '8080:80'
+    environment:
+      - PMA_HOST=controlpanel_mysql
+      - PMA_USER=root # change it
+      - PMA_PASSWORD=root # change it
+      - PMA_ARBITRARY=1
+    networks:
+      - controlpanel
+
+  redis:
+    image: redis
+    container_name: controlpanel_redis
+    restart: unless-stopped
+    ports:
+      - "6379:6379"
+    networks:
+      - controlpanel
+
+networks:
+  controlpanel:

From 93fb0b7d5e523900aa25a4a1710d228dd676cffa Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 09:28:06 +0200
Subject: [PATCH 347/514] Change repository owner name

---
 docker/standalone/compose.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 11b3dd85d..ba129fa4d 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -1,6 +1,6 @@
 services:
   controlpanel:
-    image: ghcr.io/jameskitt616/panel:latest
+    image: ghcr.io/ctrlpanel-gg/panel:latest
     container_name: controlpanel_panel
     restart: unless-stopped
     depends_on:

From 9fef8ab964a22bbd55e0e7e63abe96ef5980c11f Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 09:40:44 +0200
Subject: [PATCH 348/514] Update docker readme

---
 docker/standalone/README.md | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index 992b80c82..489c079d5 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -7,8 +7,15 @@ If you're using a different operating system, you can follow the official Docker
 
 Once you have Docker installed, you can run CtrlPanel standalone Docker by executing the following command:
 
+Recommended way via Docker Compose:
+
+Get the Compose file [here](https://github.com/Ctrlpanel-gg/panel/blob/docker-github-workflow/docker/standalone/compose.yaml).
+This also includes all necessaries like a Database, Redis and optionally phpmyadmin to manage the Database.
+
+Running as commandline command:
+
 ```bash
-docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html -v /path/to/nginx_config:/etc/nginx/conf.d/ ctrlpanel/ctrlpanel
+docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html -v /path/to/nginx_config:/etc/nginx/conf.d/ ghcr.io/ctrlpanel-gg/panel:latest
 ```
 
 This command will run the latest CtrlPanel Docker image from Docker Hub and run it.

From 7a40c3837035af57e808bb99b02b83961e029e95 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 09:46:50 +0200
Subject: [PATCH 349/514] Update docker readme with redis instructions

---
 docker/standalone/README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index 489c079d5..200234bf6 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -18,6 +18,8 @@ Running as commandline command:
 docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html -v /path/to/nginx_config:/etc/nginx/conf.d/ ghcr.io/ctrlpanel-gg/panel:latest
 ```
 
+When installing you need to update the `.env` file. Change those two variables to: `MEMCACHED_HOST=redis` and `REDIS_HOST=redis`, to use the Redis server which comes with the docker compose installation.
+
 This command will run the latest CtrlPanel Docker image from Docker Hub and run it.
 
 The control panel will be available at http://localhost/install and will be a completely fresh installation.

From 86de9ecc4cf4f177e4edb05e6917ecff202c640c Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 12:56:20 +0200
Subject: [PATCH 350/514] Update startup script

---
 config/trustedproxy.php              |  2 +-
 docker/development/compose.yaml      |  4 +---
 docker/standalone/compose.yaml       | 10 ++++++----
 docker/standalone/scripts/startup.sh |  1 +
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/config/trustedproxy.php b/config/trustedproxy.php
index dc46c31ba..f3b88cd52 100644
--- a/config/trustedproxy.php
+++ b/config/trustedproxy.php
@@ -26,7 +26,7 @@
      * subsequently passed through.
      */
     'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ?
-        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)),
+        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', '')),
 
     /*
      * Or, to trust all proxies that connect
diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index c3010c59f..0c9e49ff5 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -5,15 +5,13 @@ services:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile
     container_name: controlpanel_development
-    restart: on-failure
+    restart: unless-stopped
     ports:
       - "80:80"
       - "443:443"
     volumes:
       - '../..:/var/www/html:rw'
       - './nginx_config:/etc/nginx/conf.d/:rw'
-    networks:
-      - controlpanel
 
   mysql:
     image: mysql
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index ba129fa4d..51d9a9959 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -9,10 +9,12 @@ services:
       - "80:80"
       - "443:443"
     volumes:
-      - './website_files:/var/www/html:rw' # change it
-      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
-    networks:
-      - controlpanel
+      - './env:/var/www/html/.env:rw'
+      - './logs:/var/www/html/storage/logs:rw'
+#      - './website_files:/var/www/html:rw' # change it
+#      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
+#    networks:
+#      - controlpanel
 
   mysql:
     image: mysql
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 5f36512d9..17a36203f 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -32,6 +32,7 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
     chmod -R 755 /var/www/html
+    chmod -R 644 $LOG_DIR
 fi
 
 # Check and copy default Nginx configuration if not exists

From 47cdd8e17c2739e78fc06944d0fe2abd2de49200 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 13:04:10 +0200
Subject: [PATCH 351/514] Add network to dev compose

---
 docker/development/compose.yaml | 2 ++
 docker/standalone/compose.yaml  | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index 0c9e49ff5..ef2c3c2e1 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -12,6 +12,8 @@ services:
     volumes:
       - '../..:/var/www/html:rw'
       - './nginx_config:/etc/nginx/conf.d/:rw'
+    networks:
+      - controlpanel
 
   mysql:
     image: mysql
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 51d9a9959..960b14bdb 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -13,8 +13,8 @@ services:
       - './logs:/var/www/html/storage/logs:rw'
 #      - './website_files:/var/www/html:rw' # change it
 #      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
-#    networks:
-#      - controlpanel
+    networks:
+      - controlpanel
 
   mysql:
     image: mysql

From 956e6793742bb40ad0f6264d5a8e68821ec39ebc Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 13:08:53 +0200
Subject: [PATCH 352/514] Set database name and user to defaults from installer

---
 docker/development/compose.yaml | 4 ++--
 docker/standalone/compose.yaml  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index ef2c3c2e1..7f5acb0f8 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -23,8 +23,8 @@ services:
     ports:
       - "3306:3306"
     environment:
-      MYSQL_DATABASE: controlpanel
-      MYSQL_USER: controlpanel
+      MYSQL_DATABASE: ctrlpanel
+      MYSQL_USER: ctrlpaneluser
       MYSQL_PASSWORD: root
       MYSQL_ROOT_PASSWORD: root
     volumes:
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 960b14bdb..0551eb61d 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -24,8 +24,8 @@ services:
     ports:
       - "3306:3306"
     environment:
-      MYSQL_DATABASE: controlpanel
-      MYSQL_USER: controlpaneluser
+      MYSQL_DATABASE: ctrlpanel
+      MYSQL_USER: ctrlpaneluser
       MYSQL_PASSWORD: root # change it
       MYSQL_ROOT_PASSWORD: root # change it
     volumes:

From e054cb9a33036e418ce5d36d062647071ae336d1 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 13:29:30 +0200
Subject: [PATCH 353/514] Update permissions

---
 docker/standalone/scripts/startup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 17a36203f..39092d919 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -32,7 +32,7 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
     chmod -R 755 /var/www/html
-    chmod -R 644 $LOG_DIR
+    chmod -R 664 $LOG_DIR
 fi
 
 # Check and copy default Nginx configuration if not exists

From b3862a48e03511dfc3cf9c98dcd700bfdf418980 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 14:07:05 +0200
Subject: [PATCH 354/514] Try to determine if process is running within a
 docker container

---
 public/install/functions.php | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/public/install/functions.php b/public/install/functions.php
index a5f2b0454..046ea1a6f 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -236,14 +236,18 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 
     $path = dirname(__FILE__, 3);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
+    if (file_exists('/.dockerenv')) {
+        $handle = proc_open("cd '$path' && bash -c '$command'", $descriptors, $pipes, $cwd, null, $options);
+    } else {
+        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
+    }
+
     $output = stream_get_contents($pipes[1]);
     $exit_code = proc_close($handle);
 
     if ($exit_code > 0) {
         wh_log('command result: ' . $output, 'error');
         throw new Exception("There was an error after running command `$command`", $exit_code);
-        return $output;
     } else {
         return $output;
     }

From aadd164d55255b342894d9db99501ae7a71b2150 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 14:27:16 +0200
Subject: [PATCH 355/514] Force conecole command without exec -a

---
 public/install/functions.php | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/public/install/functions.php b/public/install/functions.php
index 046ea1a6f..51b4c629e 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -236,11 +236,11 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 
     $path = dirname(__FILE__, 3);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-    if (file_exists('/.dockerenv')) {
+//    if (file_exists('/.dockerenv')) {
         $handle = proc_open("cd '$path' && bash -c '$command'", $descriptors, $pipes, $cwd, null, $options);
-    } else {
-        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
-    }
+//    } else {
+//        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
+//    }
 
     $output = stream_get_contents($pipes[1]);
     $exit_code = proc_close($handle);

From e564a3886062ba9d86312d05c7f8ec19dbf94aca Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 14:44:01 +0200
Subject: [PATCH 356/514] Comment out everything in run_console command

---
 public/install/functions.php | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/public/install/functions.php b/public/install/functions.php
index 51b4c629e..5a964bf3e 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -235,15 +235,20 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
     wh_log('running command: ' . $command, 'debug');
 
     $path = dirname(__FILE__, 3);
-    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
+    wh_log('running command: ' . "cd '$path' && bash -c '$command'", 'debug');
+
+//    $path = dirname(__FILE__, 3);
+//    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
 //    if (file_exists('/.dockerenv')) {
-        $handle = proc_open("cd '$path' && bash -c '$command'", $descriptors, $pipes, $cwd, null, $options);
+//        $handle = proc_open("cd '$path' && bash -c '$command'", $descriptors, $pipes, $cwd, null, $options);
 //    } else {
 //        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
 //    }
 
-    $output = stream_get_contents($pipes[1]);
-    $exit_code = proc_close($handle);
+//    $output = stream_get_contents($pipes[1]);
+//    $exit_code = proc_close($handle);
+    $exit_code = 0;
+    $output = 'yippie';
 
     if ($exit_code > 0) {
         wh_log('command result: ' . $output, 'error');

From b8d6d59d14179abd5a616f3959b5bff6226d39e4 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 14:58:16 +0200
Subject: [PATCH 357/514] Set different permissions

---
 config/logging.php           |  6 +++---
 public/install/functions.php | 13 ++++++-------
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/config/logging.php b/config/logging.php
index 5d4134ffa..a09c721f7 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -61,7 +61,7 @@
             'driver' => 'single',
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
-            'permission' => 0664,
+            'permission' => 0644,
         ],
 
         'daily' => [
@@ -69,7 +69,7 @@
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
             'days' => 14,
-            'permission' => 0664,
+            'permission' => 0644,
         ],
 
         'slack' => [
@@ -118,7 +118,7 @@
 
         'emergency' => [
             'path' => storage_path('logs/laravel.log'),
-            'permission' => 0664,
+            'permission' => 0644,
         ],
     ],
 
diff --git a/public/install/functions.php b/public/install/functions.php
index 5a964bf3e..519a88414 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -237,18 +237,17 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
     $path = dirname(__FILE__, 3);
     wh_log('running command: ' . "cd '$path' && bash -c '$command'", 'debug');
 
-//    $path = dirname(__FILE__, 3);
-//    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
+    $path = dirname(__FILE__, 3);
+    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
 //    if (file_exists('/.dockerenv')) {
+//    if (!file_exists('../../.env')) {
 //        $handle = proc_open("cd '$path' && bash -c '$command'", $descriptors, $pipes, $cwd, null, $options);
 //    } else {
-//        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
+        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
 //    }
 
-//    $output = stream_get_contents($pipes[1]);
-//    $exit_code = proc_close($handle);
-    $exit_code = 0;
-    $output = 'yippie';
+    $output = stream_get_contents($pipes[1]);
+    $exit_code = proc_close($handle);
 
     if ($exit_code > 0) {
         wh_log('command result: ' . $output, 'error');

From c5ad334b2bea7ed5bb466f56994c5729bf8f52b0 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 14:59:26 +0200
Subject: [PATCH 358/514] Set different permissions

---
 docker/standalone/scripts/startup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 39092d919..17a36203f 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -32,7 +32,7 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
     chmod -R 755 /var/www/html
-    chmod -R 664 $LOG_DIR
+    chmod -R 644 $LOG_DIR
 fi
 
 # Check and copy default Nginx configuration if not exists

From 92c16559ddc7905d9c1897ae2fa613687b20f3bc Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 15:12:20 +0200
Subject: [PATCH 359/514] Open up permissions

---
 config/logging.php                   | 6 +++---
 docker/standalone/scripts/startup.sh | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/config/logging.php b/config/logging.php
index a09c721f7..dc1ce25da 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -61,7 +61,7 @@
             'driver' => 'single',
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
-            'permission' => 0644,
+            'permission' => 0777,
         ],
 
         'daily' => [
@@ -69,7 +69,7 @@
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
             'days' => 14,
-            'permission' => 0644,
+            'permission' => 0777,
         ],
 
         'slack' => [
@@ -118,7 +118,7 @@
 
         'emergency' => [
             'path' => storage_path('logs/laravel.log'),
-            'permission' => 0644,
+            'permission' => 0777,
         ],
     ],
 
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 17a36203f..144350ef5 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -32,9 +32,10 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
     chmod -R 755 /var/www/html
-    chmod -R 644 $LOG_DIR
 fi
 
+chmod -R 777 $LOG_DIR
+
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
     log_message "Warning: Nginx configuration not found. Copying default configuration..."

From fec23eec1f1fbe5f9e9268bb40c0ef78d074d351 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 15:26:25 +0200
Subject: [PATCH 360/514] Revert stuff in functions.php

---
 docker/standalone/scripts/startup.sh |  3 ++-
 public/install/functions.php         | 10 +---------
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 144350ef5..b4ab19552 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -34,7 +34,8 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     chmod -R 755 /var/www/html
 fi
 
-chmod -R 777 $LOG_DIR
+#chmod -R 755 /var/www/html
+#chmod -R 777 $LOG_DIR
 
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
diff --git a/public/install/functions.php b/public/install/functions.php
index 519a88414..7b482732f 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -234,17 +234,9 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 {
     wh_log('running command: ' . $command, 'debug');
 
-    $path = dirname(__FILE__, 3);
-    wh_log('running command: ' . "cd '$path' && bash -c '$command'", 'debug');
-
     $path = dirname(__FILE__, 3);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-//    if (file_exists('/.dockerenv')) {
-//    if (!file_exists('../../.env')) {
-//        $handle = proc_open("cd '$path' && bash -c '$command'", $descriptors, $pipes, $cwd, null, $options);
-//    } else {
-        $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
-//    }
+    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
 
     $output = stream_get_contents($pipes[1]);
     $exit_code = proc_close($handle);

From 786bac37ffa79c30a3dbc01a605364facd5aafc9 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 15:38:47 +0200
Subject: [PATCH 361/514] Reset permissions

---
 config/logging.php           | 6 +++---
 public/install/functions.php | 1 -
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/config/logging.php b/config/logging.php
index dc1ce25da..5d4134ffa 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -61,7 +61,7 @@
             'driver' => 'single',
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
-            'permission' => 0777,
+            'permission' => 0664,
         ],
 
         'daily' => [
@@ -69,7 +69,7 @@
             'path' => storage_path('logs/laravel.log'),
             'level' => env('LOG_LEVEL', 'debug'),
             'days' => 14,
-            'permission' => 0777,
+            'permission' => 0664,
         ],
 
         'slack' => [
@@ -118,7 +118,7 @@
 
         'emergency' => [
             'path' => storage_path('logs/laravel.log'),
-            'permission' => 0777,
+            'permission' => 0664,
         ],
     ],
 
diff --git a/public/install/functions.php b/public/install/functions.php
index 7b482732f..912a90180 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -237,7 +237,6 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
     $path = dirname(__FILE__, 3);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
     $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
-
     $output = stream_get_contents($pipes[1]);
     $exit_code = proc_close($handle);
 

From a2e0109e9df3c00882dadcd3c73a27b086d5011c Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 15:42:52 +0200
Subject: [PATCH 362/514] Update permissions in startup.sh

---
 docker/standalone/scripts/startup.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index b4ab19552..dc1585995 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -30,11 +30,11 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
-    chown -R laravel:laravel /var/www/html/
-    chmod -R 755 /var/www/html
+#    chown -R laravel:laravel /var/www/html/
+#    chmod -R 755 /var/www/html
 fi
 
-#chmod -R 755 /var/www/html
+chmod -R 755 /var/www/html
 #chmod -R 777 $LOG_DIR
 
 # Check and copy default Nginx configuration if not exists

From 76463c940bb787d8ef3473e0d533724ac02944fe Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 15:55:45 +0200
Subject: [PATCH 363/514] Add chown to startup.sh

---
 docker/standalone/scripts/startup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index dc1585995..b44b959dc 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -34,8 +34,8 @@ if [ -z "$(ls -A /var/www/html)" ]; then
 #    chmod -R 755 /var/www/html
 fi
 
+chown -R laravel:laravel /var/www/html/
 chmod -R 755 /var/www/html
-#chmod -R 777 $LOG_DIR
 
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then

From dffcb25afe746fe9f24ee03456a32db138f3eeae Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 16:21:05 +0200
Subject: [PATCH 364/514] Add permissions to streamhandler

---
 docker/standalone/Dockerfile         | 3 +++
 docker/standalone/compose.yaml       | 6 +++---
 docker/standalone/scripts/startup.sh | 8 ++++----
 public/install/functions.php         | 2 +-
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index a16bed8cb..9fd5e4770 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -58,5 +58,8 @@ RUN chmod +x /usr/local/bin/startup-script.sh
 # Set the working directory
 WORKDIR /var/www/html
 
+#RUN chmod -R 755 /var/www/html
+#RUN chown -R laravel:laravel /var/www/html
+
 # Start the startup script
 CMD ["/usr/local/bin/startup-script.sh"]
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 0551eb61d..6b00f27df 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -9,9 +9,9 @@ services:
       - "80:80"
       - "443:443"
     volumes:
-      - './env:/var/www/html/.env:rw'
-      - './logs:/var/www/html/storage/logs:rw'
-#      - './website_files:/var/www/html:rw' # change it
+#      - './env:/var/www/html/.env:rw'
+#      - './logs:/var/www/html/storage/logs:rw'
+      - './website_files:/var/www/html:rw' # change it
 #      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
     networks:
       - controlpanel
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index b44b959dc..3bfa5f212 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -30,12 +30,12 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
-#    chown -R laravel:laravel /var/www/html/
-#    chmod -R 755 /var/www/html
+    chown -R laravel:laravel /var/www/html/
+    chmod -R 755 /var/www/html/
 fi
 
-chown -R laravel:laravel /var/www/html/
-chmod -R 755 /var/www/html
+#chown -R laravel:laravel /var/www/html/
+#chmod -R 755 /var/www/html/
 
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
diff --git a/public/install/functions.php b/public/install/functions.php
index 912a90180..e44d2f3c1 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -258,7 +258,7 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 function wh_log(string $message, string $level = 'info', array $context = []): void
 {
     $formatter = new LineFormatter(null, null, true, true);
-    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG);
+    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG, true, 664);
     $stream->setFormatter($formatter);
 
     $log = new Logger('ControlPanel');

From 0a3cc259640ed1156553d3e3846b631ee0ef7c9a Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 16:41:16 +0200
Subject: [PATCH 365/514] Revert StreamHandler permissions

---
 docker/standalone/Dockerfile         | 3 ---
 docker/standalone/scripts/startup.sh | 4 ++--
 public/install/functions.php         | 2 +-
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index 9fd5e4770..a16bed8cb 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -58,8 +58,5 @@ RUN chmod +x /usr/local/bin/startup-script.sh
 # Set the working directory
 WORKDIR /var/www/html
 
-#RUN chmod -R 755 /var/www/html
-#RUN chown -R laravel:laravel /var/www/html
-
 # Start the startup script
 CMD ["/usr/local/bin/startup-script.sh"]
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 3bfa5f212..57e7195da 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -34,8 +34,8 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     chmod -R 755 /var/www/html/
 fi
 
-#chown -R laravel:laravel /var/www/html/
-#chmod -R 755 /var/www/html/
+chown -R laravel:laravel /var/www/html/
+chmod -R 755 /var/www/html/
 
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
diff --git a/public/install/functions.php b/public/install/functions.php
index e44d2f3c1..912a90180 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -258,7 +258,7 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 function wh_log(string $message, string $level = 'info', array $context = []): void
 {
     $formatter = new LineFormatter(null, null, true, true);
-    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG, true, 664);
+    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG);
     $stream->setFormatter($formatter);
 
     $log = new Logger('ControlPanel');

From d6a01b66f1c8d9453be7cd888d5f85decfe945d3 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 16:41:44 +0200
Subject: [PATCH 366/514] Revert trustedpries

---
 config/trustedproxy.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/trustedproxy.php b/config/trustedproxy.php
index f3b88cd52..dc46c31ba 100644
--- a/config/trustedproxy.php
+++ b/config/trustedproxy.php
@@ -26,7 +26,7 @@
      * subsequently passed through.
      */
     'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ?
-        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', '')),
+        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)),
 
     /*
      * Or, to trust all proxies that connect

From f523ea6f2b09035682853b6eb103c5b641f73fc4 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 30 May 2024 17:05:36 +0200
Subject: [PATCH 367/514] Revert permissions in startup.sh

---
 docker/standalone/scripts/startup.sh | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 57e7195da..5f36512d9 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -31,12 +31,9 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
-    chmod -R 755 /var/www/html/
+    chmod -R 755 /var/www/html
 fi
 
-chown -R laravel:laravel /var/www/html/
-chmod -R 755 /var/www/html/
-
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
     log_message "Warning: Nginx configuration not found. Copying default configuration..."

From c285f8f0944d3d1c6e46e1f5f5eb382b08c5de5a Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 1 Jun 2024 09:47:05 +0200
Subject: [PATCH 368/514] Copy .env file in Dockerfile

---
 docker/standalone/Dockerfile | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index a16bed8cb..5880acee2 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -50,6 +50,9 @@ RUN mkdir -p /var/log/nginx && chown -R laravel:laravel /var/log/nginx
 # Expose ports
 EXPOSE 80 443
 
+# Copy .env file for it to be availbe when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
+COPY --chown=laravel:laravel ./.env.example /var/www/html/.env
+
 # Copy startup script
 COPY --chown=laravel:laravel ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh
 # Make startup script executable
@@ -58,5 +61,6 @@ RUN chmod +x /usr/local/bin/startup-script.sh
 # Set the working directory
 WORKDIR /var/www/html
 
+
 # Start the startup script
 CMD ["/usr/local/bin/startup-script.sh"]

From bdffb660ccdf044b13947ce9876c8de97ce12b10 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 1 Jun 2024 10:22:25 +0200
Subject: [PATCH 369/514] copy env file in startup script

---
 docker/standalone/Dockerfile         | 5 ++---
 docker/standalone/scripts/startup.sh | 3 +++
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index 5880acee2..474b7a98e 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -50,8 +50,8 @@ RUN mkdir -p /var/log/nginx && chown -R laravel:laravel /var/log/nginx
 # Expose ports
 EXPOSE 80 443
 
-# Copy .env file for it to be availbe when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
-COPY --chown=laravel:laravel ./.env.example /var/www/html/.env
+# Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
+#COPY --chown=laravel:laravel /var/default/.env.example /var/www/html/.env
 
 # Copy startup script
 COPY --chown=laravel:laravel ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh
@@ -61,6 +61,5 @@ RUN chmod +x /usr/local/bin/startup-script.sh
 # Set the working directory
 WORKDIR /var/www/html
 
-
 # Start the startup script
 CMD ["/usr/local/bin/startup-script.sh"]
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 5f36512d9..fd70d3151 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -34,6 +34,9 @@ if [ -z "$(ls -A /var/www/html)" ]; then
     chmod -R 755 /var/www/html
 fi
 
+# Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
+cp -nr /var/www/html/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files
+
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then
     log_message "Warning: Nginx configuration not found. Copying default configuration..."

From d6d5fd878b689898e46aa9343bd523858ae33912 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 1 Jun 2024 10:26:29 +0200
Subject: [PATCH 370/514] Copy .env.example from different dir

---
 docker/standalone/scripts/startup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index fd70d3151..ee90e2152 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -35,7 +35,7 @@ if [ -z "$(ls -A /var/www/html)" ]; then
 fi
 
 # Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
-cp -nr /var/www/html/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files
+cp -nr /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files
 
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then

From 318781f95426dc718f58940b9d464fb55f0719d8 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 2 Jun 2024 08:45:34 +0200
Subject: [PATCH 371/514] Remove reverse parameter from copy single file

---
 docker/standalone/scripts/startup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index ee90e2152..b90814719 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -35,7 +35,7 @@ if [ -z "$(ls -A /var/www/html)" ]; then
 fi
 
 # Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
-cp -nr /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files
+cp -n /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files
 
 # Check and copy default Nginx configuration if not exists
 if [ ! -f "/etc/nginx/conf.d/default.conf" ]; then

From bba697b713eb218d4b8477e91c298fc5978d8acd Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 2 Jun 2024 09:17:32 +0200
Subject: [PATCH 372/514] Create dir on startup script

---
 docker/standalone/scripts/startup.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index b90814719..c67494bdc 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -25,6 +25,8 @@ log_message() {
     echo "$1"
 }
 
+mkdir /var/www/html/
+
 # Check if project folder is empty.
 if [ -z "$(ls -A /var/www/html)" ]; then
     log_message "Warning: project folder is empty. Copying default files..."

From 9cffe584b0408f3fbfc4704b2e5dfb2d849f805f Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 2 Jun 2024 09:23:09 +0200
Subject: [PATCH 373/514] Run copy of project files every time

---
 docker/standalone/scripts/startup.sh | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index c67494bdc..37af86690 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -25,16 +25,14 @@ log_message() {
     echo "$1"
 }
 
-mkdir /var/www/html/
-
 # Check if project folder is empty.
-if [ -z "$(ls -A /var/www/html)" ]; then
+#if [ -z "$(ls -A /var/www/html)" ]; then
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
     chmod -R 755 /var/www/html
-fi
+#fi
 
 # Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
 cp -n /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files

From a51ff578f43d99cb7ce8cf5c20f725fda8779175 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 2 Jun 2024 09:34:27 +0200
Subject: [PATCH 374/514] ls project dirs to check if they are empty

---
 docker/standalone/scripts/startup.sh | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 37af86690..1055d685a 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -25,14 +25,20 @@ log_message() {
     echo "$1"
 }
 
+log_message "Contents of /var/default:"
+ls -l /var/default
+
 # Check if project folder is empty.
-#if [ -z "$(ls -A /var/www/html)" ]; then
+if [ -z "$(ls -A /var/www/html)" ]; then
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
     chmod -R 755 /var/www/html
-#fi
+fi
+
+log_message "Contents of /var/www/html:"
+ls -l /var/www/html
 
 # Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
 cp -n /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files

From 7c3d70285f0b3c2a0255e58ce2c542df0b761443 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 2 Jun 2024 09:43:10 +0200
Subject: [PATCH 375/514] Show and set permissions for project folder

---
 docker/standalone/scripts/startup.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 1055d685a..99380da14 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -26,19 +26,24 @@ log_message() {
 }
 
 log_message "Contents of /var/default:"
-ls -l /var/default
+ls -la /var/default
+
+log_message "Permissions of /var/www/html:"
+ls -la /var/www/html
 
 # Check if project folder is empty.
 if [ -z "$(ls -A /var/www/html)" ]; then
+    chown -R laravel:laravel /var/www/html/
+    chmod -R 777 /var/www/html/
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
     chown -R laravel:laravel /var/www/html/
-    chmod -R 755 /var/www/html
+    chmod -R 755 /var/www/html/
 fi
 
 log_message "Contents of /var/www/html:"
-ls -l /var/www/html
+ls -la /var/www/html
 
 # Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
 cp -n /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files

From 4c833e2f5cf590c2722d54447225109b05e6b6ce Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 2 Jun 2024 10:31:39 +0200
Subject: [PATCH 376/514] Run copy project files anyways

---
 docker/standalone/scripts/startup.sh | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 99380da14..e909ebcce 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -31,16 +31,24 @@ ls -la /var/default
 log_message "Permissions of /var/www/html:"
 ls -la /var/www/html
 
+chown -R laravel:laravel /var/www/html/
+chmod -R 777 /var/www/html/
+log_message "Warning: project folder is empty. Copying default files..."
+# Copy everything from /var/default to /var/www/html
+cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
+chown -R laravel:laravel /var/www/html/
+chmod -R 755 /var/www/html/
+
 # Check if project folder is empty.
-if [ -z "$(ls -A /var/www/html)" ]; then
-    chown -R laravel:laravel /var/www/html/
-    chmod -R 777 /var/www/html/
-    log_message "Warning: project folder is empty. Copying default files..."
-    # Copy everything from /var/default to /var/www/html
-    cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
-    chown -R laravel:laravel /var/www/html/
-    chmod -R 755 /var/www/html/
-fi
+#if [ -z "$(ls -A /var/www/html)" ]; then
+#    chown -R laravel:laravel /var/www/html/
+#    chmod -R 777 /var/www/html/
+#    log_message "Warning: project folder is empty. Copying default files..."
+#    # Copy everything from /var/default to /var/www/html
+#    cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
+#    chown -R laravel:laravel /var/www/html/
+#    chmod -R 755 /var/www/html/
+#fi
 
 log_message "Contents of /var/www/html:"
 ls -la /var/www/html

From 29665709590283f6dd281309b70762181fd2e1d1 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Tue, 4 Jun 2024 15:23:32 +0200
Subject: [PATCH 377/514] docs: precised how PR should be created in
 contributing.md

---
 .github/CONTRIBUTING.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index c00a9e604..93b4ee75c 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -16,7 +16,7 @@ Please read our [Localization Guide](https://github.com/Ctrlpanel-gg/panel/blob/
 
 ## 🚀 Pull Request Process
 
-1. Provide a clear and descriptive title for your pull request (PR) summarizing the changes.
+1. Provide a clear and descriptive title for your pull request (PR) summarizing the changes in this format : 'commit-norms-action: what-you-are-doing'.
 2. If your PR is not yet finished, correctly mark it as a draft and mention any errors it's correcting.
 3. The development team will review your code and offer feedback or approve/merge it as necessary.
 4. Ensure that your PR adheres to our Code of Conduct and coding style guidelines.
@@ -29,7 +29,7 @@ Please read our [Localization Guide](https://github.com/Ctrlpanel-gg/panel/blob/
 We adhere to the PSR12 code standard for PHP.
 
 - Follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) commit norms.
-- Name your PR branch as [action]/what-you-are-doing.
+- Name your PR branch as [commit-norms-action]/what-you-are-doing.
 - Make clear commits, one per action, and include comments.
 
 ⚠️ **Important Note:** The owner of the project has the final decision, and the development team of CtrlPanel reserves the right to close incorrect PRs. PRs that remain inactive or invalid for an extended period may also be subject to closure.

From 863299b4c08e17292aa91d179a8162757bba61f5 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 22:23:41 +0200
Subject: [PATCH 378/514] Attempt to fix startup script

---
 docker/standalone/README.md          |  7 +++--
 docker/standalone/scripts/startup.sh | 38 +++++++++-------------------
 2 files changed, 15 insertions(+), 30 deletions(-)

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index 200234bf6..5a11a24c2 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -9,8 +9,9 @@ Once you have Docker installed, you can run CtrlPanel standalone Docker by execu
 
 Recommended way via Docker Compose:
 
-Get the Compose file [here](https://github.com/Ctrlpanel-gg/panel/blob/docker-github-workflow/docker/standalone/compose.yaml).
-This also includes all necessaries like a Database, Redis and optionally phpmyadmin to manage the Database.
+1. Copy and configure your docker compose file to your needs `curl -L -o docker-compose.yml https://raw.githubusercontent.com/Ctrlpanel-gg/panel/blob/main/docker/standalone/compose.yaml`.
+2. Create the env file in the same directory as the compose file `touch env_file`.
+3. When installing you need to update the `env_file` file. Change those two variables to: `MEMCACHED_HOST=redis` and `REDIS_HOST=redis`, to use the Redis server which comes with the docker compose installation.
 
 Running as commandline command:
 
@@ -18,8 +19,6 @@ Running as commandline command:
 docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html -v /path/to/nginx_config:/etc/nginx/conf.d/ ghcr.io/ctrlpanel-gg/panel:latest
 ```
 
-When installing you need to update the `.env` file. Change those two variables to: `MEMCACHED_HOST=redis` and `REDIS_HOST=redis`, to use the Redis server which comes with the docker compose installation.
-
 This command will run the latest CtrlPanel Docker image from Docker Hub and run it.
 
 The control panel will be available at http://localhost/install and will be a completely fresh installation.
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index e909ebcce..51e1eb328 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -25,35 +25,21 @@ log_message() {
     echo "$1"
 }
 
-log_message "Contents of /var/default:"
-ls -la /var/default
-
-log_message "Permissions of /var/www/html:"
-ls -la /var/www/html
-
-chown -R laravel:laravel /var/www/html/
-chmod -R 777 /var/www/html/
-log_message "Warning: project folder is empty. Copying default files..."
-# Copy everything from /var/default to /var/www/html
-cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
-chown -R laravel:laravel /var/www/html/
-chmod -R 755 /var/www/html/
+# The issue seems that "index.nginx-debian.html" seems to be in the folder, hence the next check will always fail.
+rm /var/www/html/index.nginx-debian.html
 
 # Check if project folder is empty.
-#if [ -z "$(ls -A /var/www/html)" ]; then
-#    chown -R laravel:laravel /var/www/html/
-#    chmod -R 777 /var/www/html/
-#    log_message "Warning: project folder is empty. Copying default files..."
-#    # Copy everything from /var/default to /var/www/html
-#    cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
-#    chown -R laravel:laravel /var/www/html/
-#    chmod -R 755 /var/www/html/
-#fi
-
-log_message "Contents of /var/www/html:"
-ls -la /var/www/html
+if [ -z "$(ls -A /var/www/html)" ]; then
+    chown -R laravel:laravel /var/www/html/
+    chmod -R 777 /var/www/html/
+    log_message "Warning: project folder is empty. Copying default files..."
+    # Copy everything from /var/default to /var/www/html
+    cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files
+    chown -R laravel:laravel /var/www/html/
+    chmod -R 755 /var/www/html/
+fi
 
-# Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
+# Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder).
 cp -n /var/default/.env.example /var/www/html/.env   # Use -n to avoid overwriting existing files
 
 # Check and copy default Nginx configuration if not exists

From 1cb03f5e85255fc23ddd077ed02a04c3382fc790 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 22:34:21 +0200
Subject: [PATCH 379/514] Add logging to troubleshoot

---
 docker/standalone/scripts/startup.sh | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 51e1eb328..5637a5e7e 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -25,9 +25,15 @@ log_message() {
     echo "$1"
 }
 
+log_message "Permissions of /var/www/html:"
+ls -la /var/www/html
+
 # The issue seems that "index.nginx-debian.html" seems to be in the folder, hence the next check will always fail.
 rm /var/www/html/index.nginx-debian.html
 
+log_message "Permissions of /var/www/html:"
+ls -la /var/www/html
+
 # Check if project folder is empty.
 if [ -z "$(ls -A /var/www/html)" ]; then
     chown -R laravel:laravel /var/www/html/

From 06a67fe8d2fc7582a5b33c64552e30f5568158c3 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 23:43:40 +0200
Subject: [PATCH 380/514] Check for public folder instead of if has contents

---
 docker/standalone/scripts/startup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 5637a5e7e..3811faea5 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -35,7 +35,7 @@ log_message "Permissions of /var/www/html:"
 ls -la /var/www/html
 
 # Check if project folder is empty.
-if [ -z "$(ls -A /var/www/html)" ]; then
+if [ ! -d "/var/www/html/public" ]; then
     chown -R laravel:laravel /var/www/html/
     chmod -R 777 /var/www/html/
     log_message "Warning: project folder is empty. Copying default files..."

From 9188c42693fa7ea9cfcccb45ce148576a3ed2400 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 23:49:33 +0200
Subject: [PATCH 381/514] Remove unnecessary deletion of file

---
 docker/standalone/scripts/startup.sh | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 3811faea5..664702eb2 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -25,16 +25,7 @@ log_message() {
     echo "$1"
 }
 
-log_message "Permissions of /var/www/html:"
-ls -la /var/www/html
-
-# The issue seems that "index.nginx-debian.html" seems to be in the folder, hence the next check will always fail.
-rm /var/www/html/index.nginx-debian.html
-
-log_message "Permissions of /var/www/html:"
-ls -la /var/www/html
-
-# Check if project folder is empty.
+# Check if public folder is exists. If not, copy project.
 if [ ! -d "/var/www/html/public" ]; then
     chown -R laravel:laravel /var/www/html/
     chmod -R 777 /var/www/html/

From ebe730bfef2aefc38f4695d7356e802d7e9f8702 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 23:52:50 +0200
Subject: [PATCH 382/514] Test if permissions are necessary

---
 docker/standalone/Dockerfile         | 3 ---
 docker/standalone/README.md          | 2 +-
 docker/standalone/scripts/startup.sh | 4 ++--
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile
index 474b7a98e..a16bed8cb 100644
--- a/docker/standalone/Dockerfile
+++ b/docker/standalone/Dockerfile
@@ -50,9 +50,6 @@ RUN mkdir -p /var/log/nginx && chown -R laravel:laravel /var/log/nginx
 # Expose ports
 EXPOSE 80 443
 
-# Copy .env file for it to be available when starting the Docker container (to be able to bind-mount it to the host, instead of the entire project folder)
-#COPY --chown=laravel:laravel /var/default/.env.example /var/www/html/.env
-
 # Copy startup script
 COPY --chown=laravel:laravel ./docker/standalone/scripts/startup.sh /usr/local/bin/startup-script.sh
 # Make startup script executable
diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index 5a11a24c2..40c740a38 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -9,7 +9,7 @@ Once you have Docker installed, you can run CtrlPanel standalone Docker by execu
 
 Recommended way via Docker Compose:
 
-1. Copy and configure your docker compose file to your needs `curl -L -o docker-compose.yml https://raw.githubusercontent.com/Ctrlpanel-gg/panel/blob/main/docker/standalone/compose.yaml`.
+1. Copy and configure your docker compose file to your needs `curl -L -o compose.yaml https://raw.githubusercontent.com/Ctrlpanel-gg/panel/blob/main/docker/standalone/compose.yaml`.
 2. Create the env file in the same directory as the compose file `touch env_file`.
 3. When installing you need to update the `env_file` file. Change those two variables to: `MEMCACHED_HOST=redis` and `REDIS_HOST=redis`, to use the Redis server which comes with the docker compose installation.
 
diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 664702eb2..233650626 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -27,8 +27,8 @@ log_message() {
 
 # Check if public folder is exists. If not, copy project.
 if [ ! -d "/var/www/html/public" ]; then
-    chown -R laravel:laravel /var/www/html/
-    chmod -R 777 /var/www/html/
+#    chown -R laravel:laravel /var/www/html/
+#    chmod -R 777 /var/www/html/
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files

From 9e6688dd531b53da561ea8ab8e8026b5bb6b3380 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 23:56:16 +0200
Subject: [PATCH 383/514] Remove unnecessary permissions

---
 docker/standalone/scripts/startup.sh | 2 --
 1 file changed, 2 deletions(-)

diff --git a/docker/standalone/scripts/startup.sh b/docker/standalone/scripts/startup.sh
index 233650626..bf11b5bff 100644
--- a/docker/standalone/scripts/startup.sh
+++ b/docker/standalone/scripts/startup.sh
@@ -27,8 +27,6 @@ log_message() {
 
 # Check if public folder is exists. If not, copy project.
 if [ ! -d "/var/www/html/public" ]; then
-#    chown -R laravel:laravel /var/www/html/
-#    chmod -R 777 /var/www/html/
     log_message "Warning: project folder is empty. Copying default files..."
     # Copy everything from /var/default to /var/www/html
     cp -nr /var/default/. /var/www/html   # Use -n to avoid overwriting existing files

From 44c05b0f6e2e56b2b95bc89baa24264be9ca3a1a Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Fri, 7 Jun 2024 23:58:35 +0200
Subject: [PATCH 384/514] Update compose.yaml with only logs and env file

---
 docker/standalone/compose.yaml | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 6b00f27df..76e64b13b 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -9,10 +9,8 @@ services:
       - "80:80"
       - "443:443"
     volumes:
-#      - './env:/var/www/html/.env:rw'
-#      - './logs:/var/www/html/storage/logs:rw'
-      - './website_files:/var/www/html:rw' # change it
-#      - './nginx_config:/etc/nginx/conf.d/:rw' # change it
+      - './logs:/var/www/html/storage/logs:w'
+      - './env_file:/var/www/html/.env'
     networks:
       - controlpanel
 

From 33096fbea4b156de3fbd6091ce29cca3018621f1 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 8 Jun 2024 08:36:41 +0200
Subject: [PATCH 385/514] Rename controlpanel to ctrlpanel

---
 docker/development/compose.yaml | 22 +++++++++++-----------
 docker/standalone/compose.yaml  | 22 +++++++++++-----------
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index 7f5acb0f8..fd1f09bab 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -1,10 +1,10 @@
 services:
   # TODO: add wings and pterodactyl
-  controlpanel_panel:
+  ctrlpanel_panel:
     build:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile
-    container_name: controlpanel_development
+    container_name: ctrlpanel_development
     restart: unless-stopped
     ports:
       - "80:80"
@@ -13,11 +13,11 @@ services:
       - '../..:/var/www/html:rw'
       - './nginx_config:/etc/nginx/conf.d/:rw'
     networks:
-      - controlpanel
+      - ctrlpanel
 
   mysql:
     image: mysql
-    container_name: controlpanel_mysql
+    container_name: ctrlpanel_mysql
     restart: unless-stopped
     tty: true
     ports:
@@ -30,31 +30,31 @@ services:
     volumes:
       - "./mysql:/var/lib/mysql:delegated"
     networks:
-      - controlpanel
+      - ctrlpanel
 
   phpmyadmin:
     image: phpmyadmin/phpmyadmin
-    container_name: controlpanel_phpmyadmin
+    container_name: ctrlpanel_phpmyadmin
     depends_on:
       - mysql
     ports:
       - '8080:80'
     environment:
-      - PMA_HOST=controlpanel_mysql
+      - PMA_HOST=ctrlpanel_mysql
       - PMA_USER=root
       - PMA_PASSWORD=root
       - PMA_ARBITRARY=1
     networks:
-      - controlpanel
+      - ctrlpanel
 
   redis:
     image: redis
-    container_name: controlpanel_redis
+    container_name: ctrlpanel_redis
     restart: unless-stopped
     ports:
       - "6379:6379"
     networks:
-      - controlpanel
+      - ctrlpanel
 
 networks:
-  controlpanel:
+  ctrlpanel:
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 76e64b13b..496e6c0f8 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -1,7 +1,7 @@
 services:
-  controlpanel:
+  ctrlpanel:
     image: ghcr.io/ctrlpanel-gg/panel:latest
-    container_name: controlpanel_panel
+    container_name: ctrlpanel_panel
     restart: unless-stopped
     depends_on:
       - redis
@@ -12,11 +12,11 @@ services:
       - './logs:/var/www/html/storage/logs:w'
       - './env_file:/var/www/html/.env'
     networks:
-      - controlpanel
+      - ctrlpanel
 
   mysql:
     image: mysql
-    container_name: controlpanel_mysql
+    container_name: ctrlpanel_mysql
     restart: unless-stopped
     tty: true
     ports:
@@ -29,32 +29,32 @@ services:
     volumes:
       - "./mysql:/var/lib/mysql:delegated"
     networks:
-      - controlpanel
+      - ctrlpanel
 
   phpmyadmin:
     image: phpmyadmin/phpmyadmin
-    container_name: controlpanel_phpmyadmin
+    container_name: ctrlpanel_phpmyadmin
     restart: unless-stopped
     depends_on:
       - mysql
     ports:
       - '8080:80'
     environment:
-      - PMA_HOST=controlpanel_mysql
+      - PMA_HOST=ctrlpanel_mysql
       - PMA_USER=root # change it
       - PMA_PASSWORD=root # change it
       - PMA_ARBITRARY=1
     networks:
-      - controlpanel
+      - ctrlpanel
 
   redis:
     image: redis
-    container_name: controlpanel_redis
+    container_name: ctrlpanel_redis
     restart: unless-stopped
     ports:
       - "6379:6379"
     networks:
-      - controlpanel
+      - ctrlpanel
 
 networks:
-  controlpanel:
+  ctrlpanel:

From 6a5f05e4192ddfdaef738e8dae05a52e9482e81f Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 8 Jun 2024 08:40:43 +0200
Subject: [PATCH 386/514] Fix typo

---
 themes/default/views/information/tos-content.blade.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/themes/default/views/information/tos-content.blade.php b/themes/default/views/information/tos-content.blade.php
index e9a42927f..cec69f4ad 100644
--- a/themes/default/views/information/tos-content.blade.php
+++ b/themes/default/views/information/tos-content.blade.php
@@ -18,7 +18,7 @@
 
 <ol>
     <li>AGREEMENT TO TERMS</li>
-    <li>NTELLECTUAL PROPERTY RIGHTS</li>
+    <li>INTELLECTUAL PROPERTY RIGHTS</li>
     <li>USER REPRESENTATIONS</li>
     <li>USER REGISTRATION</li>
     <li>PRODUCTS</li>

From 05dc11ed6f608d01452db8f1d23df55188255acb Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 8 Jun 2024 17:24:16 +0200
Subject: [PATCH 387/514] Update Readme and stanalone compose

---
 docker/standalone/README.md    | 16 ++++++++--------
 docker/standalone/compose.yaml |  1 +
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/docker/standalone/README.md b/docker/standalone/README.md
index 40c740a38..2efaf6bfd 100644
--- a/docker/standalone/README.md
+++ b/docker/standalone/README.md
@@ -7,19 +7,19 @@ If you're using a different operating system, you can follow the official Docker
 
 Once you have Docker installed, you can run CtrlPanel standalone Docker by executing the following command:
 
-Recommended way via Docker Compose:
-
-1. Copy and configure your docker compose file to your needs `curl -L -o compose.yaml https://raw.githubusercontent.com/Ctrlpanel-gg/panel/blob/main/docker/standalone/compose.yaml`.
-2. Create the env file in the same directory as the compose file `touch env_file`.
-3. When installing you need to update the `env_file` file. Change those two variables to: `MEMCACHED_HOST=redis` and `REDIS_HOST=redis`, to use the Redis server which comes with the docker compose installation.
-
 Running as commandline command:
 
 ```bash
-docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html -v /path/to/nginx_config:/etc/nginx/conf.d/ ghcr.io/ctrlpanel-gg/panel:latest
+docker run -p 80:80 -p 443:443 -v /path/to/website_files:/var/www/html ghcr.io/ctrlpanel-gg/panel:latest
 ```
 
-This command will run the latest CtrlPanel Docker image from Docker Hub and run it.
+This command will run the latest CtrlPanel Docker image from GitHub Container Registry and run it.
+
+Recommended way via Docker Compose:
+
+1. Copy and configure your docker compose file to your needs `curl -L -o compose.yaml https://raw.githubusercontent.com/Ctrlpanel-gg/panel/blob/main/docker/standalone/compose.yaml`.
+2. Create the env file in the same directory as the compose file `touch env_file`.
+3. When installing you need to update the `env_file` file. Change those two variables to: `MEMCACHED_HOST=redis` and `REDIS_HOST=redis`, to use the Redis server which comes with the docker compose installation.
 
 The control panel will be available at http://localhost/install and will be a completely fresh installation.
 
diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 496e6c0f8..0f29febae 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -11,6 +11,7 @@ services:
     volumes:
       - './logs:/var/www/html/storage/logs:w'
       - './env_file:/var/www/html/.env'
+      #- './website_files:/var/www/html:rw' # optionally use this, in case you want/need access to all project files, to use like addons/plugins.
     networks:
       - ctrlpanel
 

From d210baa7d26caa591471ddca15de82722b93f092 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 8 Jun 2024 21:12:52 +0200
Subject: [PATCH 388/514] Docker compose default add project files

---
 docker/standalone/compose.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index 0f29febae..f9a3ac71e 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -11,7 +11,7 @@ services:
     volumes:
       - './logs:/var/www/html/storage/logs:w'
       - './env_file:/var/www/html/.env'
-      #- './website_files:/var/www/html:rw' # optionally use this, in case you want/need access to all project files, to use like addons/plugins.
+      - './website_files:/var/www/html:rw' # optionally use remove this bind mount, it's not needed unless you want access to all project files, to modify the project with addons/plugins.
     networks:
       - ctrlpanel
 

From 01ca75fe4af8809e82e7f383c644e4cc9d19db98 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 8 Jun 2024 21:24:17 +0200
Subject: [PATCH 389/514] Fix typo

---
 docker/standalone/compose.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index f9a3ac71e..adb572b37 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -11,7 +11,7 @@ services:
     volumes:
       - './logs:/var/www/html/storage/logs:w'
       - './env_file:/var/www/html/.env'
-      - './website_files:/var/www/html:rw' # optionally use remove this bind mount, it's not needed unless you want access to all project files, to modify the project with addons/plugins.
+      - './website_files:/var/www/html:rw' # optionally remove this bind mount, it's not needed unless you want access to all project files, to modify the project with addons/plugins.
     networks:
       - ctrlpanel
 

From a58aa10fffa298d465118266626ecd5d9389920b Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 8 Jun 2024 22:41:55 +0200
Subject: [PATCH 390/514] Readd nginx config expose

---
 docker/standalone/compose.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index adb572b37..e1c2b7a61 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -12,6 +12,7 @@ services:
       - './logs:/var/www/html/storage/logs:w'
       - './env_file:/var/www/html/.env'
       - './website_files:/var/www/html:rw' # optionally remove this bind mount, it's not needed unless you want access to all project files, to modify the project with addons/plugins.
+      - './nginx_config:/etc/nginx/conf.d/:rw' # optionally remove this bind mount, it's not needed unless you want to modify the project with addons/plugins. (dangerous to edit)
     networks:
       - ctrlpanel
 

From 628f2c6cb81f5d50493a751408c4ccb110b7cd0b Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 9 Jun 2024 16:48:30 +0200
Subject: [PATCH 391/514] Update dev docker service name

---
 docker/development/compose.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/development/compose.yaml b/docker/development/compose.yaml
index fd1f09bab..1e8571a05 100644
--- a/docker/development/compose.yaml
+++ b/docker/development/compose.yaml
@@ -1,6 +1,6 @@
 services:
   # TODO: add wings and pterodactyl
-  ctrlpanel_panel:
+  ctrlpanel_development:
     build:
       context: ../../
       dockerfile: ./docker/standalone/Dockerfile

From bb9bc296946513c73ac10047bbc30689529fcb95 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 9 Jun 2024 16:51:04 +0200
Subject: [PATCH 392/514] Update standalone docker service name

---
 docker/standalone/compose.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docker/standalone/compose.yaml b/docker/standalone/compose.yaml
index e1c2b7a61..b2d3ce2f4 100644
--- a/docker/standalone/compose.yaml
+++ b/docker/standalone/compose.yaml
@@ -1,7 +1,7 @@
 services:
-  ctrlpanel:
+  ctrlpanel_standalone:
     image: ghcr.io/ctrlpanel-gg/panel:latest
-    container_name: ctrlpanel_panel
+    container_name: ctrlpanel_standalone
     restart: unless-stopped
     depends_on:
       - redis

From 392b6011ba021b76e659a57b536fc49621d3fb64 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Sun, 9 Jun 2024 18:38:50 +0200
Subject: [PATCH 393/514] refactor: added warning and deleted useless check in
 installer first step

---
 public/install/functions.php | 30 ------------------------------
 public/install/index.php     | 20 ++++++++++----------
 2 files changed, 10 insertions(+), 40 deletions(-)

diff --git a/public/install/functions.php b/public/install/functions.php
index 01dbcd04d..c23856e86 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -48,36 +48,6 @@ function checkWriteable(): bool
     return is_writable('../../.env');
 }
 
-/**
- * Check if the server runs using HTTPS
- * @return bool Returns true on HTTPS or false on HTTP.
- */
-function checkHTTPS(): bool
-{
-    $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
-    wh_log('https:', 'debug', (array)$isHttps);
-    return $isHttps;
-}
-
-/**
- * Check if MySQL is installed and runs the correct version using a shell command
- * @return mixed|string 'OK' if required version is met, returns MySQL version if not met.
- */
-function getMySQLVersion(): mixed
-{
-    global $requirements;
-
-    wh_log('attempting to get mysql version', 'debug');
-
-    $output = shell_exec('mysql -V') ?? '';
-    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? '0';
-    wh_log('mysql version: ' . $versionoutput, 'debug');
-
-    return intval($versionoutput) > intval($requirements['mysql']) ? 'OK' : $versionoutput;
-}
-
 /**
  * Check if zip is installed using a shell command
  * @return string 'OK' on success and 'not OK' on failure.
diff --git a/public/install/index.php b/public/install/index.php
index 8d63f71d9..37347ce6f 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -72,18 +72,12 @@ function cardStart($title, $subtitle = null)
 
         <ul class="list-none mb-2">
 
-            <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
-
             <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
 
             <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
                 php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
             </li>
 
-            <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
-            </li>
-
             <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
                 Missing php-extentions:
                 <?php echo count(checkExtensions()) == 0 ? 'none' : '';
@@ -93,10 +87,6 @@ function cardStart($title, $subtitle = null)
                 echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
             </li>
 
-
-            <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
-                    version: <?php echo getZipVersion(); ?> </li> -->
-
             <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
                 Git version:
                 <?php echo getGitVersion(); ?>
@@ -106,6 +96,16 @@ function cardStart($title, $subtitle = null)
                 Tar version:
                 <?php echo getTarVersion(); ?>
             </li>
+
+            <li>
+                <p class="text-neutral-400 mb-1">
+                    <br>
+                    <span style="color: #eab308;">Important:</span>
+                    CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
+                    Please make sure you have these installed and running before you continue.
+                </p>
+            </li>
+
         </ul>
 
         </div>

From a6330ad09d36ab9fac8b7b4a053bcb6d878e5e4c Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Sun, 9 Jun 2024 18:43:22 +0200
Subject: [PATCH 394/514] fix: SECURITY.md

---
 .github/SECURITY.md | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index 7aa6d156e..ef6b07aa9 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -11,9 +11,7 @@
 At this time, we only accept vulnerability reports through GitHub Advisories. We kindly ask that you do not submit reports via other third-party bug bounty platforms, as they will be disregarded.
 
 ## Supported Versions
-
-### CtrlPanel Versions
-
 - Latests
 
+### CtrlPanel Versions
 We strongly recommend using or upgrading to the latest version of CtrlPanel to ensure you have access to the latest security fixes and enhancements.

From 010c615fd2e31390d13ea74c7525eacd0959b0b3 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Sun, 9 Jun 2024 18:57:16 +0200
Subject: [PATCH 395/514] docs: updated main readme to change links and modify
 details

---
 README.md | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 9c5dcfb90..5237de3cf 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,11 @@
 
 CtrlPanel offers an easy-to-use and free billing solution for all starting and experienced hosting providers that seamlessly integrates with the Pterodactyl panel. It facilitates account creation, server ordering, and management, while offering addons, multiple payment methods, and customizable themes for a comprehensive solution.
 
-![GitHub tag](https://img.shields.io/github/tag/ControlPanel-gg/dashboard)
+![GitHub tag](https://img.shields.io/github/tag/Ctrlpanel-gg/panel)
 ![Overall Installations](https://img.shields.io/badge/Overall%20Installations-5000%2B-green)
-![GitHub stars](https://img.shields.io/github/stars/ControlPanel-gg/dashboard)
-[![Crowdin](https://badges.crowdin.net/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg)
-![License](https://img.shields.io/github/license/ControlPanel-gg/dashboard)
+![GitHub stars](https://img.shields.io/github/stars/Ctrlpanel-gg/panel) <!--
+this need update --> <!-- [![Crowdin](https://badges.crowdin.net/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg) -->
+![License](https://img.shields.io/github/license/Ctrlpanel-gg/panel)
 ![Discord](https://img.shields.io/discord/787829714483019826)
 
 ![CtrlPanel](https://user-images.githubusercontent.com/67899387/214684708-739c1d21-06e8-4dec-a4f1-81533a46cc7e.png)
@@ -35,13 +35,13 @@ Try it!
 
 Demo Server: [demo.CtrlPanel.gg](https://demo.CtrlPanel.gg)
 
-<!-- It is a temporary live demo; all data will be deleted. -->
+*It is a temporary live demo; all data will be deleted.*
 
 ## 🔧 How to Install
 
 ### 🐳 Docker
 
-Soon...
+*Soon...*
 
 <!-- ```bash
 docker run ...
@@ -57,7 +57,6 @@ Requirements:
 
 - Platform
   - Major Linux distros such as Debian, Ubuntu, CentOS, Fedora, and ArchLinux etc.
-  - Windows 10 (x64), Windows Server ...
 
 Follow the [documentation](https://ctrlpanel.gg/docs/intro) to know how to install.
 

From 07355304b8ff5fbf83d3558b0d835fc47ef2ab29 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 11 Jun 2024 23:05:44 +0200
Subject: [PATCH 396/514] Add redis configuration to installer

---
 public/install/forms.php     |  49 ++--
 public/install/functions.php |   6 +-
 public/install/index.php     | 497 +++++++++++++++++++----------------
 3 files changed, 307 insertions(+), 245 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 9bed6eda2..5439ac891 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -48,22 +48,6 @@
     header('LOCATION: index.php?step=2.5');
 }
 
-if (isset($_POST['checkGeneral'])) {
-    wh_log('setting app settings', 'debug');
-    $appname = '"' . $_POST['name'] . '"';
-    $appurl = $_POST['url'];
-
-    if (substr($appurl, -1) === '/') {
-        $appurl = substr_replace($appurl, '', -1);
-    }
-
-    setenv('APP_NAME', $appname);
-    setenv('APP_URL', $appurl);
-
-    wh_log('App settings set', 'debug');
-    header('LOCATION: index.php?step=4');
-}
-
 if (isset($_POST['feedDB'])) {
     wh_log('Feeding the Database', 'debug');
     $logs = '';
@@ -84,13 +68,44 @@
         wh_log($logs, 'debug');
 
         wh_log('Feeding the Database successful', 'debug');
-        header('LOCATION: index.php?step=3');
+        header('LOCATION: index.php?step=2.6');
     } catch (\Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
         header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
     }
 }
 
+if (isset($_POST['redisSetup'])) {
+    wh_log('Setting up Redis', 'debug');
+    $redisHost = $_POST['redishost'];
+    $redisPort = $_POST['redisport'];
+    $redisPassword = $_POST['redispassword'];
+
+    setenv('MEMCACHED_HOST', $redisHost);
+    setenv('REDIS_HOST', $redisHost);
+    setenv('REDIS_PORT', $redisPort);
+    setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
+
+    wh_log('Redis settings set', 'debug');
+    header('LOCATION: index.php?step=3');
+}
+
+if (isset($_POST['checkGeneral'])) {
+    wh_log('setting app settings', 'debug');
+    $appname = '"' . $_POST['name'] . '"';
+    $appurl = $_POST['url'];
+
+    if (substr($appurl, -1) === '/') {
+        $appurl = substr_replace($appurl, '', -1);
+    }
+
+    setenv('APP_NAME', $appname);
+    setenv('APP_URL', $appurl);
+
+    wh_log('App settings set', 'debug');
+    header('LOCATION: index.php?step=4');
+}
+
 if (isset($_POST['checkSMTP'])) {
     wh_log('Checking SMTP Settings', 'debug');
     try {
diff --git a/public/install/functions.php b/public/install/functions.php
index 01dbcd04d..ea1a1af60 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -243,7 +243,6 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
     if ($exit_code > 0) {
         wh_log('command result: ' . $output, 'error');
         throw new Exception("There was an error after running command `$command`", $exit_code);
-        return $output;
     } else {
         return $output;
     }
@@ -303,3 +302,8 @@ function generateRandomString(int $length = 8): string
 
     return $randomString;
 }
+
+function determineIfRunningInDocker(): bool
+{
+    return file_exists('/.dockerenv');
+}
diff --git a/public/install/index.php b/public/install/index.php
index 8d63f71d9..3c1483d44 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -63,66 +63,148 @@ function cardStart($title, $subtitle = null)
 
 <body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
 
-    <?php
+<?php
 
-    // Getting started
-    if (!isset($_GET['step']) || $_GET['step'] == 1) {
+// Getting started
+if (!isset($_GET['step']) || $_GET['step'] == 1) {
     ?>
-        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
+    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
 
-        <ul class="list-none mb-2">
+    <ul class="list-none mb-2">
 
-            <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
+        <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
 
-            <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+        <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
 
-            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-            </li>
+        <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+        </li>
 
-            <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
-            </li>
+        <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
+        </li>
 
-            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-                Missing php-extentions:
-                <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-                foreach (checkExtensions() as $ext) {
-                    echo $ext . ', ';
-                }
-                echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
-            </li>
+        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+            Missing php-extentions:
+            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+            foreach (checkExtensions() as $ext) {
+                echo $ext . ', ';
+            }
+            echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
+        </li>
 
 
-            <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
+        <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
                     version: <?php echo getZipVersion(); ?> </li> -->
 
-            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                Git version:
-                <?php echo getGitVersion(); ?>
-            </li>
+        <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            Git version:
+            <?php echo getGitVersion(); ?>
+        </li>
+
+        <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            Tar version:
+            <?php echo getTarVersion(); ?>
+        </li>
+    </ul>
+
+    </div>
+    <a href="?step=2" class="w-full flex justify-center">
+        <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">Lets
+            go</button>
+    </a>
+
+    <?php
+}
+
+// DB Config
+if (isset($_GET['step']) && $_GET['step'] == 2) {
+
+    echo cardStart($title = "Database Configuration"); ?>
+
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
+
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databasedriver">Database Driver</label>
+                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required value="mysql" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databasehost">Database Host</label>
+                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="<?php echo (determineIfRunningInDocker() ? 'mysql' : '127.0.0.1')?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseport">Database Port</label>
+                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required value="3306" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseuser">Database User</label>
+                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseuserpass">Database User Password</label>
+                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text" required class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
+                    </div>
+                </div>
+
+                <div class="form-group">
+                    <div class="flex flex-col">
+                        <label for="database">Database</label>
+                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    </div>
+                </div>
+
+            </div>
 
-            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                Tar version:
-                <?php echo getTarVersion(); ?>
-            </li>
-        </ul>
+        </div>
 
         </div>
-        <a href="?step=2" class="w-full flex justify-center">
-            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">Lets
-                go</button>
-        </a>
+        <div class="w-full flex justify-center">
+            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">Submit</button>
+        </div>
+    </form>
+    </div>
+
+    <?php
+}
 
+// DB Migration & APP_KEY Generation
+if (isset($_GET['step']) && $_GET['step'] == 2.5) { ?>
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+
+    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?> <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
+
+        </div>
+        <div class="w-full flex justify-center">
+            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">Submit</button>
+        </div>
+    </form>
     <?php
     }
 
-    // DB Config
-    if (isset($_GET['step']) && $_GET['step'] == 2) {
+    // Redis Config
+    if (isset($_GET['step']) && $_GET['step'] == 2.6) {
 
-        echo cardStart($title = "Database Configuration"); ?>
+        echo cardStart($title = "Redis Configuration"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="redisSetup">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -131,71 +213,32 @@ function cardStart($title, $subtitle = null)
                 <div class="col-md-12">
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
-                            <label for="databasedriver">Database Driver</label>
-                            <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required value="mysql" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databasehost">Database Host</label>
-                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="127.0.0.1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseport">Database Port</label>
-                            <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required value="3306" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <label for="redishost">Redis Host</label>
+                            <input x-model="redishost" id="redishost" name="redishost" type="text" required value="<?php echo (determineIfRunningInDocker() ? 'redis' : '127.0.0.1')?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
-                            <label for="databaseuser">Database User</label>
-                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <label for="redisport">Redis Port</label>
+                            <input x-model="redisport" id="redisport" name="redisport" type="number" required value="6379" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
-                            <label for="databaseuserpass">Database User Password</label>
-                            <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text" required class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
+                            <label for="redispassword">Redis Password (optionally, only if configured)</label>
+                            <input x-model="redispassword" id="redispassword" name="redispassword" type="text" placeholder="usually can be left blank" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="database">Database</label>
-                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
                 </div>
-
             </div>
 
             </div>
-            <div class="w-full flex justify-center ">
-                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">Submit</button>
+            <div class="w-full flex justify-center">
+                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="redisSetup">Submit</button>
             </div>
         </form>
         </div>
 
-    <?php
-    }
-
-    // DB Migration & APP_KEY Generation
-    if (isset($_GET['step']) && $_GET['step'] == 2.5) { ?>
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
-
-            <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?> <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
-
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
-
-                </div>
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">Submit</button>
-                </div>
-            </form>
         <?php
     }
 
@@ -204,38 +247,38 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "Dashboard Configuration"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
 
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="database">Dashboard URL</label>
-                                <input id="url" name="url" type="text" required value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="database">Dashboard URL</label>
+                            <input id="url" name="url" type="text" required value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col">
-                                <label for="name">Dashboard Name</label>
-                                <input id="name" name="name" type="text" required value="CtrlPanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="name">Dashboard Name</label>
+                            <input id="name" name="name" type="text" required value="CtrlPanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
-
                     </div>
-                </div>
 
                 </div>
+            </div>
 
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">Submit</button>
-                </div>
-            </form>
             </div>
 
+            <div class="w-full flex justify-center">
+                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">Submit</button>
+            </div>
+        </form>
+        </div>
+
 
         <?php
     }
@@ -245,79 +288,79 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
-
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="method">Your E-Mail Method</label>
-                                <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                    <option value="smtp" selected>SMTP</option>
-                                </select>
-                            </div>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
+
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="method">Your E-Mail Method</label>
+                            <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <option value="smtp" selected>SMTP</option>
+                            </select>
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="host">Your Mailer-Host</label>
-                                <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="host">Your Mailer-Host</label>
+                            <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="port">Your Mail Port</label>
-                                <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="port">Your Mail Port</label>
+                            <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="user">Your Mail User</label>
-                                <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="user">Your Mail User</label>
+                            <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
 
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="pass">Your Mail-User Password</label>
-                                <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="pass">Your Mail-User Password</label>
+                            <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
-                        <div class="form-group">
-                            <div class="flex flex-col">
-                                <label for="encryption">Your Mail encryption method</label>
-                                <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                    <option value="tls" selected>TLS</option>
-                                    <option value="ssl">SSL</option>
-                                    <option value="null">None</option>
-                                </select>
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="encryption">Your Mail encryption method</label>
+                            <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <option value="tls" selected>TLS</option>
+                                <option value="ssl">SSL</option>
+                                <option value="null">None</option>
+                            </select>
                         </div>
-
                     </div>
 
+                </div>
 
 
-                </div>
 
-                </div>
+            </div>
 
-                <div class="flex w-full justify-around mt-4 gap-8 px-8">
-                    <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
+            </div>
 
-                    <a href="?step=5" class="w-full">
-                        <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
-                            For Now</button>
-                    </a>
-                </div>
-            </form>
+            <div class="flex w-full justify-around mt-4 gap-8 px-8">
+                <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
+
+                <a href="?step=5" class="w-full">
+                    <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
+                        For Now</button>
+                </a>
             </div>
+        </form>
+        </div>
 
 
         <?php
@@ -328,47 +371,47 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
 
-                                <label for="url">Pterodactyl URL</label>
-                                <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                            <label for="url">Pterodactyl URL</label>
+                            <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="key">Application API Key</label>
-                                <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br /> The key needs all
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="key">Application API Key</label>
+                            <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br /> The key needs all
                                     Read & Write permissions! </span>
-                            </div>
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col">
-                                <label for="clientkey">Admin User Client API Key</label>
-                                <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br /> Your Account
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="clientkey">Admin User Client API Key</label>
+                            <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br /> Your Account
                                     needs to be an Admin!</span>
-                            </div>
                         </div>
-
-
                     </div>
 
+
                 </div>
-                </div>
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">Submit</button>
-                </div>
-            </form>
+
+            </div>
             </div>
+            <div class="w-full flex justify-center">
+                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">Submit</button>
+            </div>
+        </form>
+        </div>
 
 
         <?php
@@ -379,45 +422,45 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
 
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
 
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="pteroID">Pterodactyl User ID </label>
-                        <input id="pteroID" name="pteroID" type="text" required value="1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
-                    </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="pteroID">Pterodactyl User ID </label>
+                    <input id="pteroID" name="pteroID" type="text" required value="1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
                 </div>
+            </div>
 
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="pass">Password</label>
-                        <input id="pass" name="pass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col">
-                        <label for="repass">Confirm Password</label>
-                        <input id="repass" name="repass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="pass">Password</label>
+                    <input id="pass" name="pass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
                 </div>
-
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="repass">Confirm Password</label>
+                    <input id="repass" name="repass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                 </div>
+            </div>
 
+            </div>
 
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">Submit</button>
-                </div>
 
-            </form>
+            <div class="w-full flex justify-center">
+                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">Submit</button>
             </div>
 
+        </form>
+        </div>
+
 
         <?php
     }
@@ -431,16 +474,16 @@ function cardStart($title, $subtitle = null)
         echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
         ?>
 
-            <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center ">
-                <button class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">Lets
-                    Go!</button>
-            </a>
+        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
+            <button class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">Lets
+                Go!</button>
+        </a>
 
-            </div>
-            </div>
+        </div>
+        </div>
         <?php
     }
-        ?>
+    ?>
 </body>
 
-</html>
\ No newline at end of file
+</html>

From 8d0690d2b318576c731b251d4bf99beb3ce6f88c Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 11 Jun 2024 23:08:20 +0200
Subject: [PATCH 397/514] Revert unnecessary changes in index.php

---
 public/install/index.php | 472 +++++++++++++++++++--------------------
 1 file changed, 236 insertions(+), 236 deletions(-)

diff --git a/public/install/index.php b/public/install/index.php
index 3c1483d44..9add8d5ac 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -63,140 +63,140 @@ function cardStart($title, $subtitle = null)
 
 <body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
 
-<?php
+    <?php
 
-// Getting started
-if (!isset($_GET['step']) || $_GET['step'] == 1) {
+    // Getting started
+    if (!isset($_GET['step']) || $_GET['step'] == 1) {
     ?>
-    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
+        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
 
-    <ul class="list-none mb-2">
+        <ul class="list-none mb-2">
 
-        <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
+            <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
 
-        <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+            <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
 
-        <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-        </li>
+            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+            </li>
 
-        <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
-        </li>
+            <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
+            </li>
 
-        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-            Missing php-extentions:
-            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-            foreach (checkExtensions() as $ext) {
-                echo $ext . ', ';
-            }
-            echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
-        </li>
+            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+                Missing php-extentions:
+                <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+                foreach (checkExtensions() as $ext) {
+                    echo $ext . ', ';
+                }
+                echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
+            </li>
 
 
-        <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
+            <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
                     version: <?php echo getZipVersion(); ?> </li> -->
 
-        <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Git version:
-            <?php echo getGitVersion(); ?>
-        </li>
+            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                Git version:
+                <?php echo getGitVersion(); ?>
+            </li>
 
-        <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Tar version:
-            <?php echo getTarVersion(); ?>
-        </li>
-    </ul>
+            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                Tar version:
+                <?php echo getTarVersion(); ?>
+            </li>
+        </ul>
 
-    </div>
-    <a href="?step=2" class="w-full flex justify-center">
-        <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">Lets
-            go</button>
-    </a>
+        </div>
+        <a href="?step=2" class="w-full flex justify-center">
+            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">Lets
+                go</button>
+        </a>
 
     <?php
-}
+    }
 
-// DB Config
-if (isset($_GET['step']) && $_GET['step'] == 2) {
+    // DB Config
+    if (isset($_GET['step']) && $_GET['step'] == 2) {
 
-    echo cardStart($title = "Database Configuration"); ?>
+        echo cardStart($title = "Database Configuration"); ?>
 
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasedriver">Database Driver</label>
-                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required value="mysql" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databasedriver">Database Driver</label>
+                            <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required value="mysql" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasehost">Database Host</label>
-                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="<?php echo (determineIfRunningInDocker() ? 'mysql' : '127.0.0.1')?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databasehost">Database Host</label>
+                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="127.0.0.1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseport">Database Port</label>
-                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required value="3306" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databaseport">Database Port</label>
+                            <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required value="3306" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuser">Database User</label>
-                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databaseuser">Database User</label>
+                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuserpass">Database User Password</label>
-                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text" required class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databaseuserpass">Database User Password</label>
+                            <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text" required class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
+                        </div>
                     </div>
-                </div>
 
-                <div class="form-group">
-                    <div class="flex flex-col">
-                        <label for="database">Database</label>
-                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="database">Database</label>
+                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
+
                 </div>
 
             </div>
 
+            </div>
+            <div class="w-full flex justify-center ">
+                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">Submit</button>
+            </div>
+        </form>
         </div>
 
-        </div>
-        <div class="w-full flex justify-center">
-            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">Submit</button>
-        </div>
-    </form>
-    </div>
-
     <?php
-}
+    }
 
-// DB Migration & APP_KEY Generation
-if (isset($_GET['step']) && $_GET['step'] == 2.5) { ?>
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+    // DB Migration & APP_KEY Generation
+    if (isset($_GET['step']) && $_GET['step'] == 2.5) { ?>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
 
-    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?> <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+            <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?> <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
 
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
+                <?php if (isset($_GET['message'])) {
+                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+                } ?>
 
-        </div>
-        <div class="w-full flex justify-center">
-            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">Submit</button>
-        </div>
-    </form>
-    <?php
+                </div>
+                <div class="w-full flex justify-center ">
+                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">Submit</button>
+                </div>
+            </form>
+        <?php
     }
 
     // Redis Config
@@ -247,37 +247,37 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "Dashboard Configuration"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
+            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
 
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+                <?php if (isset($_GET['message'])) {
+                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+                } ?>
 
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="database">Dashboard URL</label>
-                            <input id="url" name="url" type="text" required value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                <div class="row">
+                    <div class="col-md-12">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="database">Dashboard URL</label>
+                                <input id="url" name="url" type="text" required value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="name">Dashboard Name</label>
-                            <input id="name" name="name" type="text" required value="CtrlPanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <div class="form-group">
+                            <div class="flex flex-col">
+                                <label for="name">Dashboard Name</label>
+                                <input id="name" name="name" type="text" required value="CtrlPanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
 
+                    </div>
                 </div>
-            </div>
 
-            </div>
+                </div>
 
-            <div class="w-full flex justify-center">
-                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">Submit</button>
+                <div class="w-full flex justify-center ">
+                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">Submit</button>
+                </div>
+            </form>
             </div>
-        </form>
-        </div>
 
 
         <?php
@@ -288,79 +288,79 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="method">Your E-Mail Method</label>
-                            <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <option value="smtp" selected>SMTP</option>
-                            </select>
+            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
+                <?php if (isset($_GET['message'])) {
+                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+                } ?>
+
+                <div class="row">
+                    <div class="col-md-12">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="method">Your E-Mail Method</label>
+                                <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                    <option value="smtp" selected>SMTP</option>
+                                </select>
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="host">Your Mailer-Host</label>
-                            <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="host">Your Mailer-Host</label>
+                                <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
 
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="port">Your Mail Port</label>
-                            <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="port">Your Mail Port</label>
+                                <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
 
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="user">Your Mail User</label>
-                            <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="user">Your Mail User</label>
+                                <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
 
 
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="pass">Your Mail-User Password</label>
-                            <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="pass">Your Mail-User Password</label>
+                                <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
 
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="encryption">Your Mail encryption method</label>
-                            <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <option value="tls" selected>TLS</option>
-                                <option value="ssl">SSL</option>
-                                <option value="null">None</option>
-                            </select>
+                        <div class="form-group">
+                            <div class="flex flex-col">
+                                <label for="encryption">Your Mail encryption method</label>
+                                <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                    <option value="tls" selected>TLS</option>
+                                    <option value="ssl">SSL</option>
+                                    <option value="null">None</option>
+                                </select>
+                            </div>
                         </div>
-                    </div>
 
-                </div>
+                    </div>
 
 
 
-            </div>
+                </div>
 
-            </div>
+                </div>
 
-            <div class="flex w-full justify-around mt-4 gap-8 px-8">
-                <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
+                <div class="flex w-full justify-around mt-4 gap-8 px-8">
+                    <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
 
-                <a href="?step=5" class="w-full">
-                    <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
-                        For Now</button>
-                </a>
+                    <a href="?step=5" class="w-full">
+                        <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
+                            For Now</button>
+                    </a>
+                </div>
+            </form>
             </div>
-        </form>
-        </div>
 
 
         <?php
@@ -371,47 +371,47 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
+                <?php if (isset($_GET['message'])) {
+                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+                } ?>
 
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
+                <div class="row">
+                    <div class="col-md-12">
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
 
-                            <label for="url">Pterodactyl URL</label>
-                            <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <label for="url">Pterodactyl URL</label>
+                                <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="key">Application API Key</label>
-                            <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br /> The key needs all
+                        <div class="form-group">
+                            <div class="flex flex-col mb-3">
+                                <label for="key">Application API Key</label>
+                                <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br /> The key needs all
                                     Read & Write permissions! </span>
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="clientkey">Admin User Client API Key</label>
-                            <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br /> Your Account
+                        <div class="form-group">
+                            <div class="flex flex-col">
+                                <label for="clientkey">Admin User Client API Key</label>
+                                <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br /> Your Account
                                     needs to be an Admin!</span>
+                            </div>
                         </div>
-                    </div>
 
 
-                </div>
+                    </div>
 
+                </div>
+                </div>
+                <div class="w-full flex justify-center ">
+                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">Submit</button>
+                </div>
+            </form>
             </div>
-            </div>
-            <div class="w-full flex justify-center">
-                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">Submit</button>
-            </div>
-        </form>
-        </div>
 
 
         <?php
@@ -422,44 +422,44 @@ function cardStart($title, $subtitle = null)
 
         echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
+            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
 
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+                <?php if (isset($_GET['message'])) {
+                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+                } ?>
 
 
-            <div class="form-group">
-                <div class="flex flex-col mb-3">
-                    <label for="pteroID">Pterodactyl User ID </label>
-                    <input id="pteroID" name="pteroID" type="text" required value="1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="pteroID">Pterodactyl User ID </label>
+                        <input id="pteroID" name="pteroID" type="text" required value="1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
+                    </div>
                 </div>
-            </div>
 
-            <div class="form-group">
-                <div class="flex flex-col mb-3">
-                    <label for="pass">Password</label>
-                    <input id="pass" name="pass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="pass">Password</label>
+                        <input id="pass" name="pass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
+                    </div>
                 </div>
-            </div>
-            <div class="form-group">
-                <div class="flex flex-col">
-                    <label for="repass">Confirm Password</label>
-                    <input id="repass" name="repass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                <div class="form-group">
+                    <div class="flex flex-col">
+                        <label for="repass">Confirm Password</label>
+                        <input id="repass" name="repass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    </div>
                 </div>
-            </div>
 
-            </div>
+                </div>
 
 
-            <div class="w-full flex justify-center">
-                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">Submit</button>
-            </div>
+                <div class="w-full flex justify-center ">
+                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">Submit</button>
+                </div>
 
-        </form>
-        </div>
+            </form>
+            </div>
 
 
         <?php
@@ -474,16 +474,16 @@ function cardStart($title, $subtitle = null)
         echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
         ?>
 
-        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
-            <button class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">Lets
-                Go!</button>
-        </a>
+            <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center ">
+                <button class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">Lets
+                    Go!</button>
+            </a>
 
-        </div>
-        </div>
+            </div>
+            </div>
         <?php
     }
-    ?>
+        ?>
 </body>
 
 </html>

From fd6f0fdc6b0841398d148771b7d1598777a2c28f Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 11 Jun 2024 23:09:22 +0200
Subject: [PATCH 398/514] Revert unnecessary changes in functions.php

---
 public/install/functions.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/public/install/functions.php b/public/install/functions.php
index ea1a1af60..ab1fb2601 100644
--- a/public/install/functions.php
+++ b/public/install/functions.php
@@ -243,6 +243,7 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
     if ($exit_code > 0) {
         wh_log('command result: ' . $output, 'error');
         throw new Exception("There was an error after running command `$command`", $exit_code);
+        return $output;
     } else {
         return $output;
     }

From d89a805e37731e10c261f7ed61034be2e5999fed Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 11 Jun 2024 23:10:49 +0200
Subject: [PATCH 399/514] Add docker check for mysql host

---
 public/install/index.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/install/index.php b/public/install/index.php
index 9add8d5ac..e01f47e3a 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -138,7 +138,7 @@ function cardStart($title, $subtitle = null)
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
                             <label for="databasehost">Database Host</label>
-                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="127.0.0.1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="<?php echo (determineIfRunningInDocker() ? 'mysql' : '127.0.0.1')?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">

From 03af8b3ed1ef1b644d710bc29b89f5324b7dd744 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 11 Jun 2024 23:50:42 +0200
Subject: [PATCH 400/514] Verify that redis config is valid and working

---
 public/install/forms.php | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 5439ac891..9d0b83e40 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -5,6 +5,7 @@
 
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\PHPMailer;
+use Predis\Client;
 
 require 'phpmailer/Exception.php';
 require 'phpmailer/PHPMailer.php';
@@ -69,7 +70,7 @@
 
         wh_log('Feeding the Database successful', 'debug');
         header('LOCATION: index.php?step=2.6');
-    } catch (\Throwable $th) {
+    } catch (Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
         header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
     }
@@ -81,13 +82,27 @@
     $redisPort = $_POST['redisport'];
     $redisPassword = $_POST['redispassword'];
 
-    setenv('MEMCACHED_HOST', $redisHost);
-    setenv('REDIS_HOST', $redisHost);
-    setenv('REDIS_PORT', $redisPort);
-    setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
+    $redisClient = new Client([
+        'host'     => $redisHost,
+        'port'     => $redisPort,
+        'password' => $redisPassword,
+        'timeout'  => 1.0,
+    ]);
 
-    wh_log('Redis settings set', 'debug');
-    header('LOCATION: index.php?step=3');
+    try {
+        $redisClient->ping();
+
+        setenv('MEMCACHED_HOST', $redisHost);
+        setenv('REDIS_HOST', $redisHost);
+        setenv('REDIS_PORT', $redisPort);
+        setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
+
+        wh_log('Redis connection successful. Settings updated.', 'debug');
+        header('LOCATION: index.php?step=3');
+    } catch (Throwable $th) {
+        wh_log('Redis connection failed. Settings updated.', 'debug');
+        header("LOCATION: index.php?step=2.6&message=Please check your credentials!<br>" . $th->getMessage());
+    }
 }
 
 if (isset($_POST['checkGeneral'])) {
@@ -221,7 +236,7 @@
             run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
             wh_log('Database updated', 'debug');
             header('LOCATION: index.php?step=6');
-        } catch (\Throwable $th) {
+        } catch (Throwable $th) {
             wh_log("Setting Pterodactyl information failed.", 'error');
             header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
         }
@@ -246,7 +261,7 @@
         $admin_token = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
         wh_log('Database updated', 'debug');
         header('LOCATION: index.php?step=6');
-    } catch (\Throwable $th) {
+    } catch (Throwable $th) {
         wh_log("Getting Pterodactyl information failed.", 'error');
         header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
     }

From c508b783ea772eb5178234f8da1f2fa05ecc5132 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Wed, 12 Jun 2024 10:50:05 +0200
Subject: [PATCH 401/514] Fix some error handling on installer

---
 composer.json            |   2 +
 public/install/forms.php | 139 ++++++++++++++++++++++-----------------
 public/install/index.php |  16 ++---
 3 files changed, 90 insertions(+), 67 deletions(-)

diff --git a/composer.json b/composer.json
index b316eec10..f36209e19 100644
--- a/composer.json
+++ b/composer.json
@@ -10,6 +10,8 @@
     "require": {
         "php": "^8.1",
         "ext-intl": "*",
+        "ext-mysqli": "*",
+        "ext-curl": "*",
         "biscolab/laravel-recaptcha": "^5.4",
         "doctrine/dbal": "^3.5.3",
         "guzzlehttp/guzzle": "^7.5",
diff --git a/public/install/forms.php b/public/install/forms.php
index 9d0b83e40..8cbd84e26 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -69,7 +69,7 @@
         wh_log($logs, 'debug');
 
         wh_log('Feeding the Database successful', 'debug');
-        header('LOCATION: index.php?step=2.6');
+        header('LOCATION: index.php?step=3');
     } catch (Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
         header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
@@ -98,10 +98,10 @@
         setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
 
         wh_log('Redis connection successful. Settings updated.', 'debug');
-        header('LOCATION: index.php?step=3');
+        header('LOCATION: index.php?step=4');
     } catch (Throwable $th) {
         wh_log('Redis connection failed. Settings updated.', 'debug');
-        header("LOCATION: index.php?step=2.6&message=Please check your credentials!<br>" . $th->getMessage());
+        header("LOCATION: index.php?step=3&message=Please check your credentials!<br>" . $th->getMessage());
     }
 }
 
@@ -118,7 +118,7 @@
     setenv('APP_URL', $appurl);
 
     wh_log('App settings set', 'debug');
-    header('LOCATION: index.php?step=4');
+    header('LOCATION: index.php?step=5');
 }
 
 if (isset($_POST['checkSMTP'])) {
@@ -150,7 +150,7 @@
         $mail->send();
     } catch (Exception $e) {
         wh_log($mail->ErrorInfo, 'error');
-        header('LOCATION: index.php?step=4&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
+        header('LOCATION: index.php?step=5&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
         exit();
     }
 
@@ -159,7 +159,7 @@
     $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
     if ($db->connect_error) {
         wh_log($db->connect_error, 'error');
-        header('LOCATION: index.php?step=4&message=Could not connect to the Database: ');
+        header('LOCATION: index.php?step=5&message=Could not connect to the Database: ');
         exit();
     }
     $values = [
@@ -177,7 +177,7 @@
     }
 
     wh_log('Database updated', 'debug');
-    header('LOCATION: index.php?step=5');
+    header('LOCATION: index.php?step=6');
 }
 
 if (isset($_POST['checkPtero'])) {
@@ -187,10 +187,20 @@
     $key = $_POST['key'];
     $clientkey = $_POST['clientkey'];
 
-    if (substr($url, -1) === '/') {
-        $url = substr_replace($url, '', -1);
+    $parsedUrl = parse_url($url);
+
+    if (!isset($parsedUrl['scheme'])) {
+        header('LOCATION: index.php?step=6&message=Please set an URL Scheme like "https://"!');
+        exit();
     }
 
+    if (!isset($parsedUrl['host'])) {
+        header('LOCATION: index.php?step=6&message=Please set an valid URL host like "https://panel.example.com"!');
+        exit();
+    }
+
+    $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
+
     $callpteroURL = $url . '/api/client/account';
     $call = curl_init();
 
@@ -203,7 +213,7 @@
     ]);
     $callresponse = curl_exec($call);
     $callresult = json_decode($callresponse, true);
-    curl_close($call); // Close the connection
+    curl_close($call);
 
     $pteroURL = $url . '/api/application/users';
     $ch = curl_init();
@@ -217,38 +227,46 @@
     ]);
     $response = curl_exec($ch);
     $result = json_decode($response, true);
-    curl_close($ch); // Close the connection
+    curl_close($ch);
+
+    if (!is_array($result)) {
+        wh_log('No array in response found', 'error');
+        header('LOCATION: index.php?step=6&message=An unknown Error occured, please try again!');
+    }
 
-    if (!is_array($result) and $result['errors'][0] !== null) {
-        header('LOCATION: index.php?step=5&message=Couldn\'t connect to Pterodactyl. Make sure your API key has all read and write permissions!');
+    if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
         wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
+        header('LOCATION: index.php?step=6&message=Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!');
         exit();
-    } elseif (!is_array($callresult) and $callresult['errors'][0] !== null or $callresult['attributes']['admin'] == false) {
-        header('LOCATION: index.php?step=5&message=Your ClientAPI Key is wrong or the account is not an admin!');
+    }
+
+    if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
         wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
+        header('LOCATION: index.php?step=6&message=Your ClientAPI Key is wrong or the account is not an admin!');
+        exit();
+    }
+
+    try {
+        run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
+        run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
+        run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
+        wh_log('Database updated', 'debug');
+        header('LOCATION: index.php?step=7');
+    } catch (Throwable $th) {
+        wh_log("Setting Pterodactyl information failed.", 'error');
+        header("LOCATION: index.php?step=6&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
         exit();
-    } else {
-        wh_log('Pterodactyl Settings are correct', 'debug');
-
-        try {
-            run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
-            run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
-            run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
-            wh_log('Database updated', 'debug');
-            header('LOCATION: index.php?step=6');
-        } catch (Throwable $th) {
-            wh_log("Setting Pterodactyl information failed.", 'error');
-            header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
-        }
     }
 }
 
 if (isset($_POST['createUser'])) {
     wh_log('Getting Pterodactyl User', 'debug');
-    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
-    if ($db->connect_error) {
-        wh_log($db->connect_error, 'error');
-        header('LOCATION: index.php?step=6&message=Could not connect to the Database');
+
+    try {
+        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
+    } catch (Throwable $th) {
+        wh_log($th->getMessage(), 'error');
+        header('LOCATION: index.php?step=7&message=Could not connect to the Database');
         exit();
     }
 
@@ -257,36 +275,36 @@
     $repass = $_POST['repass'];
 
     try {
-        $panel_url = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
-        $admin_token = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
-        wh_log('Database updated', 'debug');
-        header('LOCATION: index.php?step=6');
+        $panelUrl = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
+        $adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
     } catch (Throwable $th) {
         wh_log("Getting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        header("LOCATION: index.php?step=6&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        exit();
     }
 
-    $panel_api_url = $panel_url . '/api/application/users/' . $pteroID;
+    $panelApiUrl = $panelUrl . '/api/application/users/' . $pteroID;
 
     $ch = curl_init();
 
-    curl_setopt($ch, CURLOPT_URL, $panel_api_url);
+    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer ' . $admin_token,
+        'Authorization: Bearer ' . $adminToken,
     ]);
     $response = curl_exec($ch);
     $result = json_decode($response, true);
-    curl_close($ch); // Close the connection
+    curl_close($ch);
 
-    if (!$result['attributes']['email']) {
-        header('LOCATION: index.php?step=6&message=Could not find the user with pterodactyl ID ' . $pteroID);
+    if ($pass !== $repass) {
+        header('LOCATION: index.php?step=7&message=The Passwords did not match!');
         exit();
     }
-    if ($pass !== $repass) {
-        header('LOCATION: index.php?step=6&message=The Passwords did not match!');
+
+    if (array_key_exists('errors', $result)) {
+        header('LOCATION: index.php?step=7&message=Could not find the user with pterodactyl ID ' . $pteroID);
         exit();
     }
 
@@ -296,12 +314,12 @@
 
     $ch = curl_init();
 
-    curl_setopt($ch, CURLOPT_URL, $panel_api_url);
+    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer ' . $admin_token,
+        'Authorization: Bearer ' . $adminToken,
     ]);
     curl_setopt($ch, CURLOPT_POSTFIELDS, [
         'email' => $mail,
@@ -312,22 +330,25 @@
     ]);
     $response = curl_exec($ch);
     $result = json_decode($response, true);
-    curl_close($ch); // Close the connection
-
-    if (!is_array($result) or in_array($result['errors'][0]['code'], $result)) {
-        header('LOCATION: index.php?step=5&message=Couldn\'t connect to Pterodactyl. Make sure your API key has all read and write permissions!');
-        exit();
-    }
+    curl_close($ch);
 
     $random = generateRandomString();
 
     $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
     $query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
-    if ($db->query($query1) && $db->query($query2)) {
-        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID, 'info');
-        header('LOCATION: index.php?step=7');
-    } else {
-        wh_log($db->error, 'error');
-        header('LOCATION: index.php?step=6&message=Something went wrong when communicating with the Database');
+    try {
+        $db->query($query1);
+        $db->query($query2);
+
+        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
+        header('LOCATION: index.php?step=8');
+    } catch (Throwable $th) {
+        wh_log($th->getMessage(), 'error');
+        if (str_contains($th->getMessage(), 'Duplicate entry')) {
+            header('LOCATION: index.php?step=7&message=User already exists in CtrlPanel\'s Database.');
+        } else {
+            header('LOCATION: index.php?step=7&message=Something went wrong when communicating with the Database.');
+        }
+        exit();
     }
 }
diff --git a/public/install/index.php b/public/install/index.php
index e01f47e3a..dc3e0448c 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -200,7 +200,7 @@ function cardStart($title, $subtitle = null)
     }
 
     // Redis Config
-    if (isset($_GET['step']) && $_GET['step'] == 2.6) {
+    if (isset($_GET['step']) && $_GET['step'] == 3) {
 
         echo cardStart($title = "Redis Configuration"); ?>
 
@@ -243,7 +243,7 @@ function cardStart($title, $subtitle = null)
     }
 
     // Dashboard Config
-    if (isset($_GET['step']) && $_GET['step'] == 3) {
+    if (isset($_GET['step']) && $_GET['step'] == 4) {
 
         echo cardStart($title = "Dashboard Configuration"); ?>
 
@@ -284,7 +284,7 @@ function cardStart($title, $subtitle = null)
     }
 
     // Email Config
-    if (isset($_GET['step']) && $_GET['step'] == 4) {
+    if (isset($_GET['step']) && $_GET['step'] == 5) {
 
         echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
 
@@ -297,7 +297,7 @@ function cardStart($title, $subtitle = null)
                     <div class="col-md-12">
                         <div class="form-group">
                             <div class="flex flex-col mb-3">
-                                <label for="method">Your E-Mail Method</label>
+                                <label for="method">E-Mail Protocol</label>
                                 <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                                     <option value="smtp" selected>SMTP</option>
                                 </select>
@@ -354,7 +354,7 @@ function cardStart($title, $subtitle = null)
                 <div class="flex w-full justify-around mt-4 gap-8 px-8">
                     <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
 
-                    <a href="?step=5" class="w-full">
+                    <a href="?step=6" class="w-full">
                         <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
                             For Now</button>
                     </a>
@@ -367,7 +367,7 @@ function cardStart($title, $subtitle = null)
     }
 
     // Pterodactyl Config
-    if (isset($_GET['step']) && $_GET['step'] == 5) {
+    if (isset($_GET['step']) && $_GET['step'] == 6) {
 
         echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
 
@@ -418,7 +418,7 @@ function cardStart($title, $subtitle = null)
     }
 
     // Admin Creation Form
-    if (isset($_GET['step']) && $_GET['step'] == 6) {
+    if (isset($_GET['step']) && $_GET['step'] == 7) {
 
         echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
 
@@ -466,7 +466,7 @@ function cardStart($title, $subtitle = null)
     }
 
     // Install Finished
-    if (isset($_GET['step']) && $_GET['step'] == 7) {
+    if (isset($_GET['step']) && $_GET['step'] == 8) {
         $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
         fwrite($lockfile, 'locked');
         fclose($lockfile);

From 4ccea68f3d724d9200d823b60005a52440bb3f3d Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Wed, 12 Jun 2024 22:21:33 +0200
Subject: [PATCH 402/514] Add set timezone to install script

---
 public/install/forms.php |  72 +++--
 public/install/index.php | 597 ++++++++++++++++++++++-----------------
 2 files changed, 376 insertions(+), 293 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 8cbd84e26..23f910efc 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -13,6 +13,16 @@
 
 include 'functions.php';
 
+if (isset($_POST['timezoneConfig'])) {
+    wh_log('Setting up Timezone', 'debug');
+    $timezone = $_POST['timezone'];
+
+    setenv('APP_TIMEZONE', $timezone);
+
+    wh_log('Timezone set: ' . $timezone, 'debug');
+    header('LOCATION: index.php?step=3');
+}
+
 mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);
 
 if (isset($_POST['checkDB'])) {
@@ -32,7 +42,7 @@
         $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     } catch (mysqli_sql_exception $e) {
         wh_log($e->getMessage(), 'error');
-        header('LOCATION: index.php?step=2&message=' . $e->getMessage());
+        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
         exit();
     }
 
@@ -46,7 +56,7 @@
     }
 
     wh_log('Database connection successful', 'debug');
-    header('LOCATION: index.php?step=2.5');
+    header('LOCATION: index.php?step=3.5');
 }
 
 if (isset($_POST['feedDB'])) {
@@ -69,10 +79,10 @@
         wh_log($logs, 'debug');
 
         wh_log('Feeding the Database successful', 'debug');
-        header('LOCATION: index.php?step=3');
+        header('LOCATION: index.php?step=4');
     } catch (Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
-        header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
     }
 }
 
@@ -98,10 +108,10 @@
         setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
 
         wh_log('Redis connection successful. Settings updated.', 'debug');
-        header('LOCATION: index.php?step=4');
+        header('LOCATION: index.php?step=5');
     } catch (Throwable $th) {
         wh_log('Redis connection failed. Settings updated.', 'debug');
-        header("LOCATION: index.php?step=3&message=Please check your credentials!<br>" . $th->getMessage());
+        header("LOCATION: index.php?step=4&message=Please check your credentials!<br>" . $th->getMessage());
     }
 }
 
@@ -110,15 +120,25 @@
     $appname = '"' . $_POST['name'] . '"';
     $appurl = $_POST['url'];
 
-    if (substr($appurl, -1) === '/') {
-        $appurl = substr_replace($appurl, '', -1);
+    $parsedUrl = parse_url($appurl);
+
+    if (!isset($parsedUrl['scheme'])) {
+        header('LOCATION: index.php?step=5&message=Please set an URL Scheme like "https://"!');
+        exit();
+    }
+
+    if (!isset($parsedUrl['host'])) {
+        header('LOCATION: index.php?step=5&message=Please set an valid URL host like "https://ctrlpanel.example.com"!');
+        exit();
     }
 
+    $appurl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
+
     setenv('APP_NAME', $appname);
     setenv('APP_URL', $appurl);
 
     wh_log('App settings set', 'debug');
-    header('LOCATION: index.php?step=5');
+    header('LOCATION: index.php?step=6');
 }
 
 if (isset($_POST['checkSMTP'])) {
@@ -150,7 +170,7 @@
         $mail->send();
     } catch (Exception $e) {
         wh_log($mail->ErrorInfo, 'error');
-        header('LOCATION: index.php?step=5&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
+        header('LOCATION: index.php?step=6&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
         exit();
     }
 
@@ -159,7 +179,7 @@
     $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
     if ($db->connect_error) {
         wh_log($db->connect_error, 'error');
-        header('LOCATION: index.php?step=5&message=Could not connect to the Database: ');
+        header('LOCATION: index.php?step=6&message=Could not connect to the Database: ');
         exit();
     }
     $values = [
@@ -177,7 +197,7 @@
     }
 
     wh_log('Database updated', 'debug');
-    header('LOCATION: index.php?step=6');
+    header('LOCATION: index.php?step=7');
 }
 
 if (isset($_POST['checkPtero'])) {
@@ -190,12 +210,12 @@
     $parsedUrl = parse_url($url);
 
     if (!isset($parsedUrl['scheme'])) {
-        header('LOCATION: index.php?step=6&message=Please set an URL Scheme like "https://"!');
+        header('LOCATION: index.php?step=7&message=Please set an URL Scheme like "https://"!');
         exit();
     }
 
     if (!isset($parsedUrl['host'])) {
-        header('LOCATION: index.php?step=6&message=Please set an valid URL host like "https://panel.example.com"!');
+        header('LOCATION: index.php?step=7&message=Please set an valid URL host like "https://panel.example.com"!');
         exit();
     }
 
@@ -231,18 +251,18 @@
 
     if (!is_array($result)) {
         wh_log('No array in response found', 'error');
-        header('LOCATION: index.php?step=6&message=An unknown Error occured, please try again!');
+        header('LOCATION: index.php?step=7&message=An unknown Error occured, please try again!');
     }
 
     if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
         wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
-        header('LOCATION: index.php?step=6&message=Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!');
+        header('LOCATION: index.php?step=7&message=Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!');
         exit();
     }
 
     if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
         wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
-        header('LOCATION: index.php?step=6&message=Your ClientAPI Key is wrong or the account is not an admin!');
+        header('LOCATION: index.php?step=7&message=Your ClientAPI Key is wrong or the account is not an admin!');
         exit();
     }
 
@@ -251,10 +271,10 @@
         run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
         run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
         wh_log('Database updated', 'debug');
-        header('LOCATION: index.php?step=7');
+        header('LOCATION: index.php?step=8');
     } catch (Throwable $th) {
         wh_log("Setting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=6&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
         exit();
     }
 }
@@ -266,7 +286,7 @@
         $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
     } catch (Throwable $th) {
         wh_log($th->getMessage(), 'error');
-        header('LOCATION: index.php?step=7&message=Could not connect to the Database');
+        header('LOCATION: index.php?step=8&message=Could not connect to the Database');
         exit();
     }
 
@@ -279,7 +299,7 @@
         $adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
     } catch (Throwable $th) {
         wh_log("Getting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=6&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
         exit();
     }
 
@@ -299,12 +319,12 @@
     curl_close($ch);
 
     if ($pass !== $repass) {
-        header('LOCATION: index.php?step=7&message=The Passwords did not match!');
+        header('LOCATION: index.php?step=8&message=The Passwords did not match!');
         exit();
     }
 
     if (array_key_exists('errors', $result)) {
-        header('LOCATION: index.php?step=7&message=Could not find the user with pterodactyl ID ' . $pteroID);
+        header('LOCATION: index.php?step=8&message=Could not find the user with pterodactyl ID ' . $pteroID);
         exit();
     }
 
@@ -341,13 +361,13 @@
         $db->query($query2);
 
         wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
-        header('LOCATION: index.php?step=8');
+        header('LOCATION: index.php?step=9');
     } catch (Throwable $th) {
         wh_log($th->getMessage(), 'error');
         if (str_contains($th->getMessage(), 'Duplicate entry')) {
-            header('LOCATION: index.php?step=7&message=User already exists in CtrlPanel\'s Database.');
+            header('LOCATION: index.php?step=8&message=User already exists in CtrlPanel\'s Database.');
         } else {
-            header('LOCATION: index.php?step=7&message=Something went wrong when communicating with the Database.');
+            header('LOCATION: index.php?step=8&message=Something went wrong when communicating with the Database.');
         }
         exit();
     }
diff --git a/public/install/index.php b/public/install/index.php
index dc3e0448c..78656d380 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -5,7 +5,7 @@
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
-function cardStart($title, $subtitle = null)
+function cardStart($title, $subtitle = null): string
 {
     return "
     <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
@@ -14,13 +14,12 @@ function cardStart($title, $subtitle = null)
             <h2 class='text-xl text-center mb-2'>$title</h2>"
         . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
 }
-?>
 
-<html>
+?>
 
+<html lang="en">
 <head>
     <title>CtrlPanel.gg installer Script</title>
-
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <link href="/install/styles.css" rel="stylesheet">
     <style>
@@ -63,145 +62,197 @@ function cardStart($title, $subtitle = null)
 
 <body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
 
-    <?php
+<?php
 
-    // Getting started
-    if (!isset($_GET['step']) || $_GET['step'] == 1) {
+// Getting started
+if (!isset($_GET['step']) || $_GET['step'] == 1) {
     ?>
-        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
+    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
 
-        <ul class="list-none mb-2">
+    <ul class="list-none mb-2">
 
-            <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
+        <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
 
-            <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+        <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
 
-            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-            </li>
+        <li class="<?php echo checkPhpVersion() == 'OK' ? 'ok' : 'not-ok'; ?> check">
+            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+        </li>
 
-            <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
-            </li>
+        <li class="<?php echo getMySQLVersion() == 'OK' ? 'ok' : 'not-ok'; ?> check">
+            mysql version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)
+        </li>
 
-            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-                Missing php-extentions:
-                <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-                foreach (checkExtensions() as $ext) {
-                    echo $ext . ', ';
-                }
-                echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
-            </li>
+        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+            Missing php-extentions:
+            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+            foreach (checkExtensions() as $ext) {
+                echo $ext . ', ';
+            }
+            echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?>
+        </li>
 
 
-            <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
-                    version: <?php echo getZipVersion(); ?> </li> -->
+        <!-- <li class="<?php echo getZipVersion() == 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
+                        version: <?php echo getZipVersion(); ?> </li> -->
 
-            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                Git version:
-                <?php echo getGitVersion(); ?>
-            </li>
+        <li class="<?php echo getGitVersion() == 'OK' ? 'ok' : 'not-ok'; ?> check">
+            Git version:
+            <?php echo getGitVersion(); ?>
+        </li>
 
-            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                Tar version:
-                <?php echo getTarVersion(); ?>
-            </li>
-        </ul>
+        <li class="<?php echo getTarVersion() == 'OK' ? 'ok' : 'not-ok'; ?> check">
+            Tar version:
+            <?php echo getTarVersion(); ?>
+        </li>
+    </ul>
 
-        </div>
-        <a href="?step=2" class="w-full flex justify-center">
-            <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">Lets
-                go</button>
-        </a>
+    <a href="?step=2" class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
+            Lets go!
+        </button>
+    </a>
 
     <?php
-    }
+}
 
-    // DB Config
-    if (isset($_GET['step']) && $_GET['step'] == 2) {
+// Timezone Config
+if (isset($_GET['step']) && $_GET['step'] == 2) {
+    echo cardStart($title = "Timezone Configuration"); ?>
 
-        echo cardStart($title = "Database Configuration"); ?>
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="timezoneConfig">
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="timezone">Timezone</label>
+                        <select id="timezone" name="timezone" required
+                                class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <?php
+                            $timezoneIdentifiers = DateTimeZone::listIdentifiers();
+                            foreach ($timezoneIdentifiers as $timezoneIdentifier) {
+                                if ($timezoneIdentifier == 'UTC') {
+                                    continue;
+                                }
+
+                                echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
+                            } ?>
+                        </select>
+                    </div>
+                </div>
+            </div>
+        </div>
 
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databasedriver">Database Driver</label>
-                            <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required value="mysql" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+        <div class="w-full flex justify-center ">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="timezoneConfig">Submit
+            </button>
+        </div>
+    </form>
+    <?php
+}
+
+// DB Config
+if (isset($_GET['step']) && $_GET['step'] == 3) {
+    echo cardStart($title = "Database Configuration"); ?>
+
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
+
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databasedriver">Database Driver</label>
+                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
+                               value="mysql"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databasehost">Database Host</label>
-                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="<?php echo (determineIfRunningInDocker() ? 'mysql' : '127.0.0.1')?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databasehost">Database Host</label>
+                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
+                               value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseport">Database Port</label>
-                            <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required value="3306" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseport">Database Port</label>
+                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
+                               value="3306"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseuser">Database User</label>
-                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="ctrlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseuser">Database User</label>
+                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
+                               value="ctrlpaneluser"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseuserpass">Database User Password</label>
-                            <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text" required class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseuserpass">Database User Password</label>
+                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
+                               required
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
                     </div>
+                </div>
 
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="database">Database</label>
-                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                <div class="form-group">
+                    <div class="flex flex-col">
+                        <label for="database">Database</label>
+                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-
                 </div>
-
             </div>
+        </div>
 
-            </div>
-            <div class="w-full flex justify-center ">
-                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">Submit</button>
-            </div>
-        </form>
+        <div class="w-full flex justify-center ">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="checkDB">Submit
+            </button>
         </div>
+    </form>
 
     <?php
-    }
+}
 
-    // DB Migration & APP_KEY Generation
-    if (isset($_GET['step']) && $_GET['step'] == 2.5) { ?>
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+// DB Migration & APP_KEY Generation
+if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
 
-            <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?> <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?>
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
 
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
 
-                </div>
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">Submit</button>
-                </div>
-            </form>
-        <?php
+        <div class="w-full flex justify-center ">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="feedDB">Submit
+            </button>
+        </div>
+    </form>
+    <?php
     }
 
     // Redis Config
-    if (isset($_GET['step']) && $_GET['step'] == 3) {
-
+    if (isset($_GET['step']) && $_GET['step'] == 4) {
         echo cardStart($title = "Redis Configuration"); ?>
 
         <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="redisSetup">
@@ -214,259 +265,272 @@ function cardStart($title, $subtitle = null)
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
                             <label for="redishost">Redis Host</label>
-                            <input x-model="redishost" id="redishost" name="redishost" type="text" required value="<?php echo (determineIfRunningInDocker() ? 'redis' : '127.0.0.1')?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="redishost" id="redishost" name="redishost" type="text" required
+                                   value="<?php echo(determineIfRunningInDocker() ? 'redis' : '127.0.0.1') ?>"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
                             <label for="redisport">Redis Port</label>
-                            <input x-model="redisport" id="redisport" name="redisport" type="number" required value="6379" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="redisport" id="redisport" name="redisport" type="number" required
+                                   value="6379"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                     <div class="form-group">
                         <div class="flex flex-col mb-3">
                             <label for="redispassword">Redis Password (optionally, only if configured)</label>
-                            <input x-model="redispassword" id="redispassword" name="redispassword" type="text" placeholder="usually can be left blank" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <input x-model="redispassword" id="redispassword" name="redispassword" type="text"
+                                   placeholder="usually can be left blank"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
                     </div>
                 </div>
             </div>
 
-            </div>
             <div class="w-full flex justify-center">
-                <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="redisSetup">Submit</button>
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="redisSetup">Submit
+                </button>
             </div>
         </form>
-        </div>
 
         <?php
     }
 
     // Dashboard Config
-    if (isset($_GET['step']) && $_GET['step'] == 4) {
-
+    if (isset($_GET['step']) && $_GET['step'] == 5) {
         echo cardStart($title = "Dashboard Configuration"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
 
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="database">Dashboard URL</label>
-                                <input id="url" name="url" type="text" required value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="database">Dashboard URL</label>
+                            <input id="url" name="url" type="text" required
+                                   value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col">
-                                <label for="name">Dashboard Name</label>
-                                <input id="name" name="name" type="text" required value="CtrlPanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="name">Dashboard Name</label>
+                            <input id="name" name="name" type="text" required value="CtrlPanel"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
-
                     </div>
-                </div>
 
                 </div>
+            </div>
 
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">Submit</button>
-                </div>
-            </form>
+            <div class="w-full flex justify-center ">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="checkGeneral">Submit
+                </button>
             </div>
+        </form>
 
 
         <?php
     }
 
     // Email Config
-    if (isset($_GET['step']) && $_GET['step'] == 5) {
-
+    if (isset($_GET['step']) && $_GET['step'] == 6) {
         echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
-
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="method">E-Mail Protocol</label>
-                                <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                    <option value="smtp" selected>SMTP</option>
-                                </select>
-                            </div>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
+
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="method">E-Mail Protocol</label>
+                            <select id="method" name="method" required
+                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <option value="smtp" selected>SMTP</option>
+                            </select>
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="host">Your Mailer-Host</label>
-                                <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="host">Your Mailer-Host</label>
+                            <input id="host" name="host" type="text" required value="smtp.google.com"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="port">Your Mail Port</label>
-                                <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="port">Your Mail Port</label>
+                            <input id="port" name="port" type="number" required value="567"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="user">Your Mail User</label>
-                                <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="user">Your Mail User</label>
+                            <input id="user" name="user" type="text" required value="info@mydomain.com"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
 
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="pass">Your Mail-User Password</label>
-                                <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="pass">Your Mail-User Password</label>
+                            <input id="pass" name="pass" type="password" required value=""
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
+                    </div>
 
-                        <div class="form-group">
-                            <div class="flex flex-col">
-                                <label for="encryption">Your Mail encryption method</label>
-                                <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                    <option value="tls" selected>TLS</option>
-                                    <option value="ssl">SSL</option>
-                                    <option value="null">None</option>
-                                </select>
-                            </div>
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="encryption">Your Mail encryption method</label>
+                            <select id="encryption" name="encryption" required
+                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <option value="tls" selected>TLS</option>
+                                <option value="ssl">SSL</option>
+                                <option value="null">None</option>
+                            </select>
                         </div>
-
                     </div>
-
-
-
                 </div>
+            </div>
 
-                </div>
 
-                <div class="flex w-full justify-around mt-4 gap-8 px-8">
-                    <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
+            <div class="flex w-full justify-around mt-4 gap-8 px-8">
+                <button type="submit"
+                        class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                        name="checkSMTP">Submit
+                </button>
 
-                    <a href="?step=6" class="w-full">
-                        <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
-                            For Now</button>
-                    </a>
-                </div>
-            </form>
+                <a href="?step=7" class="w-full">
+                    <button type="button"
+                            class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
+                        Skip For Now
+                    </button>
+                </a>
             </div>
+        </form>
 
 
         <?php
     }
 
     // Pterodactyl Config
-    if (isset($_GET['step']) && $_GET['step'] == 6) {
-
+    if (isset($_GET['step']) && $_GET['step'] == 7) {
         echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
 
-                                <label for="url">Pterodactyl URL</label>
-                                <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            </div>
+                            <label for="url">Pterodactyl URL</label>
+                            <input id="url" name="url" type="text" required placeholder="https://ptero.example.com"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col mb-3">
-                                <label for="key">Application API Key</label>
-                                <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br /> The key needs all
-                                    Read & Write permissions! </span>
-                            </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="key">Application API Key</label>
+                            <input id="key" name="key" type="text" required value=""
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br/> The key needs all
+                                        Read & Write permissions! </span>
                         </div>
-                        <div class="form-group">
-                            <div class="flex flex-col">
-                                <label for="clientkey">Admin User Client API Key</label>
-                                <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br /> Your Account
-                                    needs to be an Admin!</span>
-                            </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="clientkey">Admin User Client API Key</label>
+                            <input id="clientkey" name="clientkey" type="text" required value=""
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br/> Your Account
+                                        needs to be an Admin!</span>
                         </div>
-
-
                     </div>
-
-                </div>
-                </div>
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">Submit</button>
                 </div>
-            </form>
             </div>
+            <div class="w-full flex justify-center ">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="checkPtero">Submit
+                </button>
+            </div>
+        </form>
 
 
         <?php
     }
 
     // Admin Creation Form
-    if (isset($_GET['step']) && $_GET['step'] == 7) {
-
+    if (isset($_GET['step']) && $_GET['step'] == 8) {
         echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
 
-            <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
 
-                <?php if (isset($_GET['message'])) {
-                    echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-                } ?>
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
 
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="pteroID">Pterodactyl User ID </label>
-                        <input id="pteroID" name="pteroID" type="text" required value="1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
-                    </div>
-                </div>
-
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="pass">Password</label>
-                        <input id="pass" name="pass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col">
-                        <label for="repass">Confirm Password</label>
-                        <input id="repass" name="repass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="pteroID">Pterodactyl User ID </label>
+                    <input id="pteroID" name="pteroID" type="text" required value="1"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
                 </div>
+            </div>
 
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="pass">Password</label>
+                    <input id="pass" name="pass" type="password" required value="" minlength="8"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
                 </div>
-
-
-                <div class="w-full flex justify-center ">
-                    <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">Submit</button>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="repass">Confirm Password</label>
+                    <input id="repass" name="repass" type="password" required value="" minlength="8"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                 </div>
+            </div>
 
-            </form>
+            <div class="w-full flex justify-center ">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="createUser">Submit
+                </button>
             </div>
+        </form>
 
 
         <?php
     }
 
     // Install Finished
-    if (isset($_GET['step']) && $_GET['step'] == 8) {
+    if (isset($_GET['step']) && $_GET['step'] == 9) {
         $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
         fwrite($lockfile, 'locked');
         fclose($lockfile);
@@ -474,16 +538,15 @@ function cardStart($title, $subtitle = null)
         echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
         ?>
 
-            <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center ">
-                <button class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">Lets
-                    Go!</button>
-            </a>
+        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center ">
+            <button
+                class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
+                Lets Go!
+            </button>
+        </a>
 
-            </div>
-            </div>
         <?php
     }
-        ?>
+    ?>
 </body>
-
 </html>

From 3136e185db567eda8161ddbb91c408ec27ca5d89 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Wed, 12 Jun 2024 22:41:10 +0200
Subject: [PATCH 403/514] Remove unnecessary variable

---
 public/install/index.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/public/install/index.php b/public/install/index.php
index 1ee6ddc5a..7c7765c8b 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -134,8 +134,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
                         <select id="timezone" name="timezone" required
                                 class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                             <?php
-                            $timezoneIdentifiers = DateTimeZone::listIdentifiers();
-                            foreach ($timezoneIdentifiers as $timezoneIdentifier) {
+                            foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
                                 if ($timezoneIdentifier == 'UTC') {
                                     continue;
                                 }

From effc8acad0a3b0b735fa1befbe209fb50d7f4ece Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Wed, 12 Jun 2024 22:51:35 +0200
Subject: [PATCH 404/514] Remove unnecessary whitespaces

---
 public/install/index.php | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/public/install/index.php b/public/install/index.php
index 7c7765c8b..535411e45 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -135,7 +135,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
                                 class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                             <?php
                             foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
-                                if ($timezoneIdentifier == 'UTC') {
+                                if ($timezoneIdentifier === 'UTC') {
                                     continue;
                                 }
 
@@ -147,7 +147,7 @@ class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
             </div>
         </div>
 
-        <div class="w-full flex justify-center ">
+        <div class="w-full flex justify-center">
             <button
                 class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
                 name="timezoneConfig">Submit
@@ -205,7 +205,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
                         <label for="databaseuserpass">Database User Password</label>
                         <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
                                required
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
                 </div>
 
@@ -219,7 +219,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
             </div>
         </div>
 
-        <div class="w-full flex justify-center ">
+        <div class="w-full flex justify-center">
             <button
                 class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
                 name="checkDB">Submit
@@ -240,7 +240,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
             echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
         } ?>
 
-        <div class="w-full flex justify-center ">
+        <div class="w-full flex justify-center">
             <button
                 class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
                 name="feedDB">Submit
@@ -330,7 +330,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
                 </div>
             </div>
 
-            <div class="w-full flex justify-center ">
+            <div class="w-full flex justify-center">
                 <button
                     class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
                     name="checkGeneral">Submit
@@ -468,7 +468,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
                     </div>
                 </div>
             </div>
-            <div class="w-full flex justify-center ">
+            <div class="w-full flex justify-center">
                 <button
                     class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
                     name="checkPtero">Submit
@@ -516,7 +516,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
                 </div>
             </div>
 
-            <div class="w-full flex justify-center ">
+            <div class="w-full flex justify-center">
                 <button
                     class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
                     name="createUser">Submit
@@ -537,7 +537,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
         echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
         ?>
 
-        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center ">
+        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
             <button
                 class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
                 Lets Go!

From b027456b8b5589d08547046d0b36fb57fab01bf9 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 10:17:53 +0200
Subject: [PATCH 405/514] refactor: renamed install into installer and started
 to split the files

---
 app/Http/Middleware/InstallerLock.php         |  2 +-
 public/{install => installer}/dotenv.php      |  0
 public/{install => installer}/forms.php       |  0
 public/{install => installer}/functions.php   |  0
 public/{install => installer}/index.php       | 22 +++++++++----------
 .../phpmailer/Exception.php                   |  0
 .../phpmailer/PHPMailer.php                   |  0
 .../{install => installer}/phpmailer/SMTP.php |  0
 public/installer/src/forms/admin.php          |  0
 public/installer/src/forms/dashboard.php      |  0
 public/installer/src/forms/database.php       |  0
 public/installer/src/forms/pterodactyl.php    |  0
 public/installer/src/forms/redis.php          |  0
 public/installer/src/forms/smtp.php           |  0
 public/installer/src/forms/timezone.php       |  0
 public/installer/src/functions/database.php   |  0
 .../installer/src/functions/environment.php   |  0
 public/installer/src/functions/logging.php    |  0
 public/installer/src/functions/shell.php      |  0
 public/installer/src/functions/utils.php      |  0
 public/{install => installer}/styles.css      |  0
 .../{install => installer}/tailwind.config.js |  0
 .../tailwind_styles.css                       |  0
 public/installer/view/admin-creation.php      |  0
 .../view/dashboard-configuration.php          |  0
 .../installer/view/database-configuration.php |  0
 public/installer/view/database-migration.php  |  0
 public/installer/view/email-configuration.php |  0
 .../installer/view/installation-complete.php  |  0
 public/installer/view/mandatory-checks.php    |  0
 .../view/pterodactyl-configuration.php        |  0
 public/installer/view/redis-configuration.php |  0
 .../installer/view/timezone-configuration.php |  0
 33 files changed, 12 insertions(+), 12 deletions(-)
 rename public/{install => installer}/dotenv.php (100%)
 rename public/{install => installer}/forms.php (100%)
 rename public/{install => installer}/functions.php (100%)
 rename public/{install => installer}/index.php (97%)
 rename public/{install => installer}/phpmailer/Exception.php (100%)
 rename public/{install => installer}/phpmailer/PHPMailer.php (100%)
 rename public/{install => installer}/phpmailer/SMTP.php (100%)
 create mode 100644 public/installer/src/forms/admin.php
 create mode 100644 public/installer/src/forms/dashboard.php
 create mode 100644 public/installer/src/forms/database.php
 create mode 100644 public/installer/src/forms/pterodactyl.php
 create mode 100644 public/installer/src/forms/redis.php
 create mode 100644 public/installer/src/forms/smtp.php
 create mode 100644 public/installer/src/forms/timezone.php
 create mode 100644 public/installer/src/functions/database.php
 create mode 100644 public/installer/src/functions/environment.php
 create mode 100644 public/installer/src/functions/logging.php
 create mode 100644 public/installer/src/functions/shell.php
 create mode 100644 public/installer/src/functions/utils.php
 rename public/{install => installer}/styles.css (100%)
 rename public/{install => installer}/tailwind.config.js (100%)
 rename public/{install => installer}/tailwind_styles.css (100%)
 create mode 100644 public/installer/view/admin-creation.php
 create mode 100644 public/installer/view/dashboard-configuration.php
 create mode 100644 public/installer/view/database-configuration.php
 create mode 100644 public/installer/view/database-migration.php
 create mode 100644 public/installer/view/email-configuration.php
 create mode 100644 public/installer/view/installation-complete.php
 create mode 100644 public/installer/view/mandatory-checks.php
 create mode 100644 public/installer/view/pterodactyl-configuration.php
 create mode 100644 public/installer/view/redis-configuration.php
 create mode 100644 public/installer/view/timezone-configuration.php

diff --git a/app/Http/Middleware/InstallerLock.php b/app/Http/Middleware/InstallerLock.php
index 9390a598c..f6f09e3b5 100644
--- a/app/Http/Middleware/InstallerLock.php
+++ b/app/Http/Middleware/InstallerLock.php
@@ -17,7 +17,7 @@ class InstallerLock
     public function handle(Request $request, Closure $next)
     {
         if (!file_exists(base_path()."/install.lock")){
-            return redirect('/install');
+            return redirect('/installer');
         }
         return $next($request);
     }
diff --git a/public/install/dotenv.php b/public/installer/dotenv.php
similarity index 100%
rename from public/install/dotenv.php
rename to public/installer/dotenv.php
diff --git a/public/install/forms.php b/public/installer/forms.php
similarity index 100%
rename from public/install/forms.php
rename to public/installer/forms.php
diff --git a/public/install/functions.php b/public/installer/functions.php
similarity index 100%
rename from public/install/functions.php
rename to public/installer/functions.php
diff --git a/public/install/index.php b/public/installer/index.php
similarity index 97%
rename from public/install/index.php
rename to public/installer/index.php
index 535411e45..5d73c2e2a 100644
--- a/public/install/index.php
+++ b/public/installer/index.php
@@ -1,7 +1,7 @@
 <?php
 include 'functions.php';
 
-if (file_exists('../../install.lock')) {
+if (file_exists('../../installer.lock')) {
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
@@ -21,7 +21,7 @@ function cardStart($title, $subtitle = null): string
 <head>
     <title>CtrlPanel.gg installer Script</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link href="/install/styles.css" rel="stylesheet">
+    <link href="/installer/styles.css" rel="stylesheet">
     <style>
         body {
             color-scheme: dark;
@@ -121,7 +121,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
 if (isset($_GET['step']) && $_GET['step'] == 2) {
     echo cardStart($title = "Timezone Configuration"); ?>
 
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="timezoneConfig">
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
         <?php if (isset($_GET['message'])) {
             echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
         } ?>
@@ -161,7 +161,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
 if (isset($_GET['step']) && $_GET['step'] == 3) {
     echo cardStart($title = "Database Configuration"); ?>
 
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
         <?php if (isset($_GET['message'])) {
             echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
         } ?>
@@ -234,7 +234,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
 if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
 
     <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?>
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
 
         <?php if (isset($_GET['message'])) {
             echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
@@ -254,7 +254,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 4) {
         echo cardStart($title = "Redis Configuration"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="redisSetup">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -303,7 +303,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 5) {
         echo cardStart($title = "Dashboard Configuration"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
 
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
@@ -346,7 +346,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 6) {
         echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -433,7 +433,7 @@ class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-60
     if (isset($_GET['step']) && $_GET['step'] == 7) {
         echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -484,7 +484,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 8) {
         echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
 
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
@@ -530,7 +530,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
 
     // Install Finished
     if (isset($_GET['step']) && $_GET['step'] == 9) {
-        $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
+        $lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
         fwrite($lockfile, 'locked');
         fclose($lockfile);
 
diff --git a/public/install/phpmailer/Exception.php b/public/installer/phpmailer/Exception.php
similarity index 100%
rename from public/install/phpmailer/Exception.php
rename to public/installer/phpmailer/Exception.php
diff --git a/public/install/phpmailer/PHPMailer.php b/public/installer/phpmailer/PHPMailer.php
similarity index 100%
rename from public/install/phpmailer/PHPMailer.php
rename to public/installer/phpmailer/PHPMailer.php
diff --git a/public/install/phpmailer/SMTP.php b/public/installer/phpmailer/SMTP.php
similarity index 100%
rename from public/install/phpmailer/SMTP.php
rename to public/installer/phpmailer/SMTP.php
diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/dashboard.php b/public/installer/src/forms/dashboard.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/pterodactyl.php b/public/installer/src/forms/pterodactyl.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/smtp.php b/public/installer/src/forms/smtp.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/timezone.php b/public/installer/src/forms/timezone.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/database.php b/public/installer/src/functions/database.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/shell.php b/public/installer/src/functions/shell.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/install/styles.css b/public/installer/styles.css
similarity index 100%
rename from public/install/styles.css
rename to public/installer/styles.css
diff --git a/public/install/tailwind.config.js b/public/installer/tailwind.config.js
similarity index 100%
rename from public/install/tailwind.config.js
rename to public/installer/tailwind.config.js
diff --git a/public/install/tailwind_styles.css b/public/installer/tailwind_styles.css
similarity index 100%
rename from public/install/tailwind_styles.css
rename to public/installer/tailwind_styles.css
diff --git a/public/installer/view/admin-creation.php b/public/installer/view/admin-creation.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/dashboard-configuration.php b/public/installer/view/dashboard-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/database-configuration.php b/public/installer/view/database-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/database-migration.php b/public/installer/view/database-migration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/email-configuration.php b/public/installer/view/email-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/installation-complete.php b/public/installer/view/installation-complete.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/mandatory-checks.php b/public/installer/view/mandatory-checks.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/pterodactyl-configuration.php b/public/installer/view/pterodactyl-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/redis-configuration.php b/public/installer/view/redis-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/timezone-configuration.php b/public/installer/view/timezone-configuration.php
new file mode 100644
index 000000000..e69de29bb

From 5e2a3d74ef11e5f4f25a1bc2d5d6561651758ea6 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 10:26:48 +0200
Subject: [PATCH 406/514] fix: renamed view to views folder in installer

---
 public/installer/{view => views}/admin-creation.php            | 0
 public/installer/{view => views}/dashboard-configuration.php   | 0
 public/installer/{view => views}/database-configuration.php    | 0
 public/installer/{view => views}/database-migration.php        | 0
 public/installer/{view => views}/email-configuration.php       | 0
 public/installer/{view => views}/installation-complete.php     | 0
 public/installer/{view => views}/mandatory-checks.php          | 0
 public/installer/{view => views}/pterodactyl-configuration.php | 0
 public/installer/{view => views}/redis-configuration.php       | 0
 public/installer/{view => views}/timezone-configuration.php    | 0
 10 files changed, 0 insertions(+), 0 deletions(-)
 rename public/installer/{view => views}/admin-creation.php (100%)
 rename public/installer/{view => views}/dashboard-configuration.php (100%)
 rename public/installer/{view => views}/database-configuration.php (100%)
 rename public/installer/{view => views}/database-migration.php (100%)
 rename public/installer/{view => views}/email-configuration.php (100%)
 rename public/installer/{view => views}/installation-complete.php (100%)
 rename public/installer/{view => views}/mandatory-checks.php (100%)
 rename public/installer/{view => views}/pterodactyl-configuration.php (100%)
 rename public/installer/{view => views}/redis-configuration.php (100%)
 rename public/installer/{view => views}/timezone-configuration.php (100%)

diff --git a/public/installer/view/admin-creation.php b/public/installer/views/admin-creation.php
similarity index 100%
rename from public/installer/view/admin-creation.php
rename to public/installer/views/admin-creation.php
diff --git a/public/installer/view/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
similarity index 100%
rename from public/installer/view/dashboard-configuration.php
rename to public/installer/views/dashboard-configuration.php
diff --git a/public/installer/view/database-configuration.php b/public/installer/views/database-configuration.php
similarity index 100%
rename from public/installer/view/database-configuration.php
rename to public/installer/views/database-configuration.php
diff --git a/public/installer/view/database-migration.php b/public/installer/views/database-migration.php
similarity index 100%
rename from public/installer/view/database-migration.php
rename to public/installer/views/database-migration.php
diff --git a/public/installer/view/email-configuration.php b/public/installer/views/email-configuration.php
similarity index 100%
rename from public/installer/view/email-configuration.php
rename to public/installer/views/email-configuration.php
diff --git a/public/installer/view/installation-complete.php b/public/installer/views/installation-complete.php
similarity index 100%
rename from public/installer/view/installation-complete.php
rename to public/installer/views/installation-complete.php
diff --git a/public/installer/view/mandatory-checks.php b/public/installer/views/mandatory-checks.php
similarity index 100%
rename from public/installer/view/mandatory-checks.php
rename to public/installer/views/mandatory-checks.php
diff --git a/public/installer/view/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
similarity index 100%
rename from public/installer/view/pterodactyl-configuration.php
rename to public/installer/views/pterodactyl-configuration.php
diff --git a/public/installer/view/redis-configuration.php b/public/installer/views/redis-configuration.php
similarity index 100%
rename from public/installer/view/redis-configuration.php
rename to public/installer/views/redis-configuration.php
diff --git a/public/installer/view/timezone-configuration.php b/public/installer/views/timezone-configuration.php
similarity index 100%
rename from public/installer/view/timezone-configuration.php
rename to public/installer/views/timezone-configuration.php

From ccf64c90054d04b09116bc92366e4ef027b0a86d Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 11:16:27 +0200
Subject: [PATCH 407/514] refactor: moved mailer files of installer in src

---
 public/installer/{ => src}/phpmailer/Exception.php | 0
 public/installer/{ => src}/phpmailer/PHPMailer.php | 0
 public/installer/{ => src}/phpmailer/SMTP.php      | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 rename public/installer/{ => src}/phpmailer/Exception.php (100%)
 rename public/installer/{ => src}/phpmailer/PHPMailer.php (100%)
 rename public/installer/{ => src}/phpmailer/SMTP.php (100%)

diff --git a/public/installer/phpmailer/Exception.php b/public/installer/src/phpmailer/Exception.php
similarity index 100%
rename from public/installer/phpmailer/Exception.php
rename to public/installer/src/phpmailer/Exception.php
diff --git a/public/installer/phpmailer/PHPMailer.php b/public/installer/src/phpmailer/PHPMailer.php
similarity index 100%
rename from public/installer/phpmailer/PHPMailer.php
rename to public/installer/src/phpmailer/PHPMailer.php
diff --git a/public/installer/phpmailer/SMTP.php b/public/installer/src/phpmailer/SMTP.php
similarity index 100%
rename from public/installer/phpmailer/SMTP.php
rename to public/installer/src/phpmailer/SMTP.php

From 37ec601ed3df38f0b08539b4859e1eca2c1d2599 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 11:16:53 +0200
Subject: [PATCH 408/514] refactor: refactored views of installer

---
 config/database.php                           |   2 +-
 public/installer/forms.php                    |   8 +-
 public/installer/index.php                    | 588 ++----------------
 public/installer/views/admin-creation.php     |  48 ++
 .../views/dashboard-configuration.php         |  42 ++
 .../views/database-configuration.php          |  75 +++
 public/installer/views/database-migration.php |  23 +
 .../installer/views/email-configuration.php   |  80 +++
 .../installer/views/installation-complete.php |  22 +
 public/installer/views/layout-bottom.php      |   7 +
 public/installer/views/layout-top.php         |  59 ++
 public/installer/views/mandatory-checks.php   |  54 ++
 .../views/pterodactyl-configuration.php       |  52 ++
 .../installer/views/redis-configuration.php   |  51 ++
 .../views/timezone-configuration.php          |  42 ++
 15 files changed, 601 insertions(+), 552 deletions(-)
 create mode 100644 public/installer/views/layout-bottom.php
 create mode 100644 public/installer/views/layout-top.php

diff --git a/config/database.php b/config/database.php
index dc722b5fd..1917bc6a7 100644
--- a/config/database.php
+++ b/config/database.php
@@ -119,7 +119,7 @@
 
     'redis' => [
 
-        'client' => env('REDIS_CLIENT', 'phpredis'),
+        'client' => env('REDIS_CLIENT', 'predis'),
 
         'options' => [
             'cluster' => env('REDIS_CLUSTER', 'redis'),
diff --git a/public/installer/forms.php b/public/installer/forms.php
index 23f910efc..af5fba754 100644
--- a/public/installer/forms.php
+++ b/public/installer/forms.php
@@ -7,11 +7,9 @@
 use PHPMailer\PHPMailer\PHPMailer;
 use Predis\Client;
 
-require 'phpmailer/Exception.php';
-require 'phpmailer/PHPMailer.php';
-require 'phpmailer/SMTP.php';
-
-include 'functions.php';
+require './src/phpmailer/Exception.php';
+require './src/phpmailer/PHPMailer.php';
+require './src/phpmailer/SMTP.php';
 
 if (isset($_POST['timezoneConfig'])) {
     wh_log('Setting up Timezone', 'debug');
diff --git a/public/installer/index.php b/public/installer/index.php
index 5d73c2e2a..24ee47bbd 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,551 +1,47 @@
 <?php
-include 'functions.php';
 
-if (file_exists('../../installer.lock')) {
+// Include the function files
+require_once './src/functions/environment.php';
+require_once './src/functions/database.php';
+require_once './src/functions/shell.php';
+require_once './src/functions/logging.php';
+require_once './src/functions/utils.php';
+
+// Include the form files
+require_once './src/forms/timezone.php';
+require_once './src/forms/database.php';
+require_once './src/forms/redis.php';
+require_once './src/forms/dashboard.php';
+require_once './src/forms/smtp.php';
+require_once './src/forms/pterodactyl.php';
+require_once './src/forms/admin.php';
+
+require_once './functions.php';
+require_once './forms.php';
+
+if (file_exists('../../install.lock')) {
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
-function cardStart($title, $subtitle = null): string
-{
-    return "
-    <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
-        <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
-        <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
-            <h2 class='text-xl text-center mb-2'>$title</h2>"
-        . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
-}
-
-?>
-
-<html lang="en">
-<head>
-    <title>CtrlPanel.gg installer Script</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link href="/installer/styles.css" rel="stylesheet">
-    <style>
-        body {
-            color-scheme: dark;
-        }
-
-        .check {
-            display: flex;
-            gap: 5px;
-            align-items: center;
-            margin-bottom: 5px;
-        }
-
-        .check::before {
-            width: 20px;
-            height: 20px;
-            display: block;
-        }
-
-        .ok {
-            color: lightgreen;
-        }
-
-        /* Green Checkmark */
-        .ok::before {
-            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightgreen' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
-        }
-
-        .not-ok {
-            color: lightcoral;
-        }
-
-        /* Red Cross */
-        .not-ok::before {
-            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightcoral' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
-        }
-    </style>
-</head>
-
-<body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
-
-<?php
-
-// Getting started
-if (!isset($_GET['step']) || $_GET['step'] == 1) {
-    ?>
-    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
-
-    <ul class="list-none mb-2">
-
-        <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
-
-        <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-        </li>
-
-        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-            Missing php-extentions:
-            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-            foreach (checkExtensions() as $ext) {
-                echo $ext . ', ';
-            }
-            echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
-        </li>
-
-        <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Git version:
-            <?php echo getGitVersion(); ?>
-        </li>
-
-        <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Tar version:
-            <?php echo getTarVersion(); ?>
-        </li>
-
-        <li>
-            <p class="text-neutral-400 mb-1">
-                <br>
-                <span style="color: #eab308;">Important:</span>
-                CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
-                Please make sure you have these installed and running before you continue.
-            </p>
-        </li>
-
-    </ul>
-
-    <a href="?step=2" class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
-            Lets go!
-        </button>
-    </a>
-
-    <?php
-}
-
-// Timezone Config
-if (isset($_GET['step']) && $_GET['step'] == 2) {
-    echo cardStart($title = "Timezone Configuration"); ?>
-
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="timezone">Timezone</label>
-                        <select id="timezone" name="timezone" required
-                                class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <?php
-                            foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
-                                if ($timezoneIdentifier === 'UTC') {
-                                    continue;
-                                }
-
-                                echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
-                            } ?>
-                        </select>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="timezoneConfig">Submit
-            </button>
-        </div>
-    </form>
-    <?php
-}
-
-// DB Config
-if (isset($_GET['step']) && $_GET['step'] == 3) {
-    echo cardStart($title = "Database Configuration"); ?>
-
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasedriver">Database Driver</label>
-                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
-                               value="mysql"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasehost">Database Host</label>
-                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
-                               value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseport">Database Port</label>
-                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
-                               value="3306"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuser">Database User</label>
-                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
-                               value="ctrlpaneluser"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuserpass">Database User Password</label>
-                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
-                               required
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-
-                <div class="form-group">
-                    <div class="flex flex-col">
-                        <label for="database">Database</label>
-                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="checkDB">Submit
-            </button>
-        </div>
-    </form>
-
-    <?php
-}
-
-// DB Migration & APP_KEY Generation
-if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
-
-    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?>
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
-
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="feedDB">Submit
-            </button>
-        </div>
-    </form>
-    <?php
-    }
-
-    // Redis Config
-    if (isset($_GET['step']) && $_GET['step'] == 4) {
-        echo cardStart($title = "Redis Configuration"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="redishost">Redis Host</label>
-                            <input x-model="redishost" id="redishost" name="redishost" type="text" required
-                                   value="<?php echo(determineIfRunningInDocker() ? 'redis' : '127.0.0.1') ?>"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="redisport">Redis Port</label>
-                            <input x-model="redisport" id="redisport" name="redisport" type="number" required
-                                   value="6379"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="redispassword">Redis Password (optionally, only if configured)</label>
-                            <input x-model="redispassword" id="redispassword" name="redispassword" type="text"
-                                   placeholder="usually can be left blank"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="redisSetup">Submit
-                </button>
-            </div>
-        </form>
-
-        <?php
-    }
-
-    // Dashboard Config
-    if (isset($_GET['step']) && $_GET['step'] == 5) {
-        echo cardStart($title = "Dashboard Configuration"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
-
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="database">Dashboard URL</label>
-                            <input id="url" name="url" type="text" required
-                                   value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="name">Dashboard Name</label>
-                            <input id="name" name="name" type="text" required value="CtrlPanel"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                </div>
-            </div>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="checkGeneral">Submit
-                </button>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Email Config
-    if (isset($_GET['step']) && $_GET['step'] == 6) {
-        echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="method">E-Mail Protocol</label>
-                            <select id="method" name="method" required
-                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <option value="smtp" selected>SMTP</option>
-                            </select>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="host">Your Mailer-Host</label>
-                            <input id="host" name="host" type="text" required value="smtp.google.com"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="port">Your Mail Port</label>
-                            <input id="port" name="port" type="number" required value="567"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="user">Your Mail User</label>
-                            <input id="user" name="user" type="text" required value="info@mydomain.com"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="pass">Your Mail-User Password</label>
-                            <input id="pass" name="pass" type="password" required value=""
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="encryption">Your Mail encryption method</label>
-                            <select id="encryption" name="encryption" required
-                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <option value="tls" selected>TLS</option>
-                                <option value="ssl">SSL</option>
-                                <option value="null">None</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-
-            <div class="flex w-full justify-around mt-4 gap-8 px-8">
-                <button type="submit"
-                        class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                        name="checkSMTP">Submit
-                </button>
-
-                <a href="?step=7" class="w-full">
-                    <button type="button"
-                            class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
-                        Skip For Now
-                    </button>
-                </a>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Pterodactyl Config
-    if (isset($_GET['step']) && $_GET['step'] == 7) {
-        echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-
-                            <label for="url">Pterodactyl URL</label>
-                            <input id="url" name="url" type="text" required placeholder="https://ptero.example.com"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="key">Application API Key</label>
-                            <input id="key" name="key" type="text" required value=""
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br/> The key needs all
-                                        Read & Write permissions! </span>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="clientkey">Admin User Client API Key</label>
-                            <input id="clientkey" name="clientkey" type="text" required value=""
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br/> Your Account
-                                        needs to be an Admin!</span>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="checkPtero">Submit
-                </button>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Admin Creation Form
-    if (isset($_GET['step']) && $_GET['step'] == 8) {
-        echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
-
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-
-            <div class="form-group">
-                <div class="flex flex-col mb-3">
-                    <label for="pteroID">Pterodactyl User ID </label>
-                    <input id="pteroID" name="pteroID" type="text" required value="1"
-                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
-                </div>
-            </div>
-
-            <div class="form-group">
-                <div class="flex flex-col mb-3">
-                    <label for="pass">Password</label>
-                    <input id="pass" name="pass" type="password" required value="" minlength="8"
-                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
-                </div>
-            </div>
-            <div class="form-group">
-                <div class="flex flex-col">
-                    <label for="repass">Confirm Password</label>
-                    <input id="repass" name="repass" type="password" required value="" minlength="8"
-                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                </div>
-            </div>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="createUser">Submit
-                </button>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Install Finished
-    if (isset($_GET['step']) && $_GET['step'] == 9) {
-        $lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
-        fwrite($lockfile, 'locked');
-        fclose($lockfile);
-
-        echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
-        ?>
-
-        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
-            <button
-                class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
-                Lets Go!
-            </button>
-        </a>
-
-        <?php
-    }
-    ?>
-</body>
-</html>
+$viewNames = [
+    1 => 'mandatory-checks',
+    2 => 'timezone-configuration',
+    3 => 'database-configuration',
+    4 => 'database-migration',
+    5 => 'redis-configuration',
+    6 => 'dashboard-configuration',
+    7 => 'email-configuration',
+    8 => 'pterodactyl-configuration',
+    9 => 'admin-creation',
+    10 => 'installation-complete',
+];
+
+$step = isset($_GET['step']) ? $_GET['step'] : 1;
+$viewName = $viewNames[$step];  // Get the appropriate view name
+
+// Load the layout and the specific view file
+include './views/layout-top.php';
+include "./views/{$viewName}.php";
+include './views/layout-bottom.php';
+
+?>
\ No newline at end of file
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index e69de29bb..b2eb9fa4f 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -0,0 +1,48 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "First Admin Creation",
+    $subtitle = "Lets create the first admin user!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="form-group">
+        <div class="flex flex-col mb-3">
+            <label for="pteroID">Pterodactyl User ID </label>
+            <input id="pteroID" name="pteroID" type="text" required value="1"
+                class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+            <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
+        </div>
+    </div>
+
+    <div class="form-group">
+        <div class="flex flex-col mb-3">
+            <label for="pass">Password</label>
+            <input id="pass" name="pass" type="password" required value="" minlength="8"
+                class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+            <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="flex flex-col">
+            <label for="repass">Confirm Password</label>
+            <input id="repass" name="repass" type="password" required value="" minlength="8"
+                class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="createUser">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index e69de29bb..642b0ddf5 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -0,0 +1,42 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Dashboard Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="database">Dashboard URL</label>
+                    <input id="url" name="url" type="text" required
+                            value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="name">Dashboard Name</label>
+                    <input id="name" name="name" type="text" required value="CtrlPanel"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="checkGeneral">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index e69de29bb..5aa96dd20 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -0,0 +1,75 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Database Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databasedriver">Database Driver</label>
+                    <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
+                           value="mysql"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databasehost">Database Host</label>
+                    <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
+                           value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databaseport">Database Port</label>
+                    <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
+                           value="3306"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databaseuser">Database User</label>
+                    <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
+                           value="ctrlpaneluser"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databaseuserpass">Database User Password</label>
+                    <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
+                           required
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="database">Database</label>
+                    <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="checkDB">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index e69de29bb..cf12ba40c 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -0,0 +1,23 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Database Migration and Encryption Key Generation",
+    $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="feedDB">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index e69de29bb..a7545fdae 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -0,0 +1,80 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "E-Mail Configuration",
+    $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="method">E-Mail Protocol</label>
+                    <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <option value="smtp" selected>SMTP</option>
+                    </select>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="host">Your Mailer-Host</label>
+                    <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="port">Your Mail Port</label>
+                    <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="user">Your Mail User</label>
+                    <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="pass">Your Mail-User Password</label>
+                    <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="encryption">Your Mail encryption method</label>
+                    <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <option value="tls" selected>TLS</option>
+                        <option value="ssl">SSL</option>
+                        <option value="null">None</option>
+                    </select>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="flex w-full justify-around mt-4 gap-8 px-8">
+        <button type="submit"
+                class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="checkSMTP">Submit
+        </button>
+
+        <a href="?step=7" class="w-full">
+            <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
+                Skip For Now
+            </button>
+        </a>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/installation-complete.php b/public/installer/views/installation-complete.php
index e69de29bb..c9e04d23d 100644
--- a/public/installer/views/installation-complete.php
+++ b/public/installer/views/installation-complete.php
@@ -0,0 +1,22 @@
+
+<!-- top layout here -->
+
+<?php
+$lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
+fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
+fclose($lockfile);
+
+echo cardStart(
+    $title = "Installation Complete!",
+    $subtitle = "You may navigate to your Dashboard now and log in!"
+);
+?>
+
+<a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
+    <button
+        class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
+        Lets Go!
+    </button>
+</a>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/layout-bottom.php b/public/installer/views/layout-bottom.php
new file mode 100644
index 000000000..35bfcba04
--- /dev/null
+++ b/public/installer/views/layout-bottom.php
@@ -0,0 +1,7 @@
+
+<!-- top layout here -->
+
+<!-- any middle view here -->
+
+    </body>
+</html>
diff --git a/public/installer/views/layout-top.php b/public/installer/views/layout-top.php
new file mode 100644
index 000000000..3d2b89382
--- /dev/null
+++ b/public/installer/views/layout-top.php
@@ -0,0 +1,59 @@
+<html lang="en">
+<head>
+    <title>CtrlPanel.gg installer Script</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="/installer/styles.css" rel="stylesheet">
+    <style>
+        body {
+            color-scheme: dark;
+        }
+
+        .check {
+            display: flex;
+            gap: 5px;
+            align-items: center;
+            margin-bottom: 5px;
+        }
+
+        .check::before {
+            width: 20px;
+            height: 20px;
+            display: block;
+        }
+
+        .ok {
+            color: lightgreen;
+        }
+
+        /* Green Checkmark */
+        .ok::before {
+            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightgreen' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
+        }
+
+        .not-ok {
+            color: lightcoral;
+        }
+
+        /* Red Cross */
+        .not-ok::before {
+            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightcoral' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
+        }
+    </style>
+</head>
+
+<body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
+    <?php
+        function cardStart($title, $subtitle = null): string
+        {
+            return "
+            <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
+                <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
+                <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
+                    <h2 class='text-xl text-center mb-2'>$title</h2>"
+                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
+        }
+    ?>
+
+<!-- any middle view here -->
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/mandatory-checks.php b/public/installer/views/mandatory-checks.php
index e69de29bb..039f378c4 100644
--- a/public/installer/views/mandatory-checks.php
+++ b/public/installer/views/mandatory-checks.php
@@ -0,0 +1,54 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Mandatory Checks before Installation",
+    $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"
+); ?>
+
+<ul class="list-none mb-2">
+
+    <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+
+    <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+        php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+    </li>
+
+    <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+        Missing php-extentions:
+        <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+        foreach (checkExtensions() as $ext) {
+            echo $ext . ', ';
+        }
+        echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
+    </li>
+
+    <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+        Git version:
+        <?php echo getGitVersion(); ?>
+    </li>
+
+    <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+        Tar version:
+        <?php echo getTarVersion(); ?>
+    </li>
+
+    <li>
+        <p class="text-neutral-400 mb-1">
+            <br>
+            <span style="color: #eab308;">Important:</span>
+            CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
+            Please make sure you have these installed and running before you continue.
+        </p>
+    </li>
+
+</ul>
+
+<a href="?step=2" class="w-full flex justify-center">
+    <button
+        class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
+        Lets go!
+    </button>
+</a>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index e69de29bb..47ca4acda 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -0,0 +1,52 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Pterodactyl Configuration",
+    $subtitle = "Lets get some info about your Pterodactyl Installation!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="url">Pterodactyl URL</label>
+                    <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="key">Application API Key</label>
+                    <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">
+                    [Found at: ptero.example.com/admin/api] <br/>
+                    The key needs all Read & Write permissions! </span>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="clientkey">Admin User Client API Key</label>
+                    <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">
+                    [Found at: ptero.example.com/account/api] <br/>
+                    Your Account needs to be an Admin!</span>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="checkPtero">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index e69de29bb..76bc67380 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -0,0 +1,51 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Redis Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="redishost">Redis Host</label>
+                    <input x-model="redishost" id="redishost" name="redishost" type="text" required
+                            value="<?php echo(determineIfRunningInDocker() ? 'redis' : '127.0.0.1') ?>"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="redisport">Redis Port</label>
+                    <input x-model="redisport" id="redisport" name="redisport" type="number" required
+                            value="6379"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="redispassword">Redis Password (optionally, only if configured)</label>
+                    <input x-model="redispassword" id="redispassword" name="redispassword" type="text"
+                            placeholder="usually can be left blank"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="redisSetup">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index e69de29bb..0d2228773 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -0,0 +1,42 @@
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Timezone Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="timezone">Timezone</label>
+                    <select id="timezone" name="timezone" required
+                            class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <?php
+                        foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
+                            if ($timezoneIdentifier === 'UTC') {
+                                continue;
+                            }
+
+                            echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
+                        } ?>
+                    </select>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="timezoneConfig">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
\ No newline at end of file

From b9a1cd8e52054ac5286b44dcfc8ab8a272083e99 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 11:17:55 +0200
Subject: [PATCH 409/514] fix: changed database oops reverting back change

---
 config/database.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/database.php b/config/database.php
index 1917bc6a7..dc722b5fd 100644
--- a/config/database.php
+++ b/config/database.php
@@ -119,7 +119,7 @@
 
     'redis' => [
 
-        'client' => env('REDIS_CLIENT', 'predis'),
+        'client' => env('REDIS_CLIENT', 'phpredis'),
 
         'options' => [
             'cluster' => env('REDIS_CLUSTER', 'redis'),

From b45566c7218fcdd1b66c9641dee1c284caca7c68 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 15:14:28 +0200
Subject: [PATCH 410/514] refactor: too many things, refactored the form and
 functions and added better step and error handling

---
 public/installer/forms.php                    | 372 ------------------
 public/installer/functions.php                | 280 -------------
 public/installer/index.php                    |  51 ++-
 public/installer/src/forms/admin.php          |  96 +++++
 public/installer/src/forms/dashboard.php      |  29 ++
 public/installer/src/forms/database.php       |  62 +++
 public/installer/src/forms/pterodactyl.php    |  80 ++++
 public/installer/src/forms/redis.php          |  32 ++
 public/installer/src/forms/smtp.php           |  71 ++++
 public/installer/src/forms/timezone.php       |  13 +
 public/installer/src/functions/database.php   |   0
 .../installer/src/functions/environment.php   | 132 +++++++
 public/installer/src/functions/installer.php  |  16 +
 public/installer/src/functions/logging.php    |  45 +++
 public/installer/src/functions/shell.php      |  41 ++
 public/installer/src/functions/utils.php      |  41 ++
 public/installer/views/admin-creation.php     |   6 +-
 .../views/dashboard-configuration.php         |   6 +-
 .../views/database-configuration.php          |   6 +-
 public/installer/views/database-migration.php |   6 +-
 .../installer/views/email-configuration.php   |   6 +-
 .../views/pterodactyl-configuration.php       |   6 +-
 .../installer/views/redis-configuration.php   |   6 +-
 .../views/timezone-configuration.php          |   6 +-
 24 files changed, 721 insertions(+), 688 deletions(-)
 delete mode 100644 public/installer/forms.php
 delete mode 100644 public/installer/functions.php
 delete mode 100644 public/installer/src/functions/database.php
 create mode 100644 public/installer/src/functions/installer.php

diff --git a/public/installer/forms.php b/public/installer/forms.php
deleted file mode 100644
index af5fba754..000000000
--- a/public/installer/forms.php
+++ /dev/null
@@ -1,372 +0,0 @@
-<?php
-ini_set('display_errors', 1);
-ini_set('display_startup_errors', 1);
-error_reporting(E_ALL);
-
-use PHPMailer\PHPMailer\Exception;
-use PHPMailer\PHPMailer\PHPMailer;
-use Predis\Client;
-
-require './src/phpmailer/Exception.php';
-require './src/phpmailer/PHPMailer.php';
-require './src/phpmailer/SMTP.php';
-
-if (isset($_POST['timezoneConfig'])) {
-    wh_log('Setting up Timezone', 'debug');
-    $timezone = $_POST['timezone'];
-
-    setenv('APP_TIMEZONE', $timezone);
-
-    wh_log('Timezone set: ' . $timezone, 'debug');
-    header('LOCATION: index.php?step=3');
-}
-
-mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);
-
-if (isset($_POST['checkDB'])) {
-    $values = [
-        //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
-        'DB_HOST' => 'databasehost',
-        'DB_DATABASE' => 'database',
-        'DB_USERNAME' => 'databaseuser',
-        'DB_PASSWORD' => 'databaseuserpass',
-        'DB_PORT' => 'databaseport',
-        'DB_CONNECTION' => 'databasedriver',
-    ];
-
-    wh_log('Trying to connect to the Database', 'debug');
-
-    try {
-        $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
-    } catch (mysqli_sql_exception $e) {
-        wh_log($e->getMessage(), 'error');
-        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
-        exit();
-    }
-
-
-    foreach ($values as $key => $value) {
-        $param = $_POST[$value];
-        // if ($key == "DB_PASSWORD") {
-        //    $param = '"' . $_POST[$value] . '"';
-        // }
-        setenv($key, $param);
-    }
-
-    wh_log('Database connection successful', 'debug');
-    header('LOCATION: index.php?step=3.5');
-}
-
-if (isset($_POST['feedDB'])) {
-    wh_log('Feeding the Database', 'debug');
-    $logs = '';
-
-    try {
-        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
-        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
-        if (!str_contains(getenv('APP_KEY'), 'base64')) {
-            $logs .= run_console('php artisan key:generate --force');
-        } else {
-            $logs .= "Key already exists. Skipping\n";
-        }
-        $logs .= run_console('php artisan storage:link');
-        $logs .= run_console('php artisan migrate --seed --force');
-        $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
-        $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
-
-        wh_log($logs, 'debug');
-
-        wh_log('Feeding the Database successful', 'debug');
-        header('LOCATION: index.php?step=4');
-    } catch (Throwable $th) {
-        wh_log('Feeding the Database failed', 'error');
-        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
-    }
-}
-
-if (isset($_POST['redisSetup'])) {
-    wh_log('Setting up Redis', 'debug');
-    $redisHost = $_POST['redishost'];
-    $redisPort = $_POST['redisport'];
-    $redisPassword = $_POST['redispassword'];
-
-    $redisClient = new Client([
-        'host'     => $redisHost,
-        'port'     => $redisPort,
-        'password' => $redisPassword,
-        'timeout'  => 1.0,
-    ]);
-
-    try {
-        $redisClient->ping();
-
-        setenv('MEMCACHED_HOST', $redisHost);
-        setenv('REDIS_HOST', $redisHost);
-        setenv('REDIS_PORT', $redisPort);
-        setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
-
-        wh_log('Redis connection successful. Settings updated.', 'debug');
-        header('LOCATION: index.php?step=5');
-    } catch (Throwable $th) {
-        wh_log('Redis connection failed. Settings updated.', 'debug');
-        header("LOCATION: index.php?step=4&message=Please check your credentials!<br>" . $th->getMessage());
-    }
-}
-
-if (isset($_POST['checkGeneral'])) {
-    wh_log('setting app settings', 'debug');
-    $appname = '"' . $_POST['name'] . '"';
-    $appurl = $_POST['url'];
-
-    $parsedUrl = parse_url($appurl);
-
-    if (!isset($parsedUrl['scheme'])) {
-        header('LOCATION: index.php?step=5&message=Please set an URL Scheme like "https://"!');
-        exit();
-    }
-
-    if (!isset($parsedUrl['host'])) {
-        header('LOCATION: index.php?step=5&message=Please set an valid URL host like "https://ctrlpanel.example.com"!');
-        exit();
-    }
-
-    $appurl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
-
-    setenv('APP_NAME', $appname);
-    setenv('APP_URL', $appurl);
-
-    wh_log('App settings set', 'debug');
-    header('LOCATION: index.php?step=6');
-}
-
-if (isset($_POST['checkSMTP'])) {
-    wh_log('Checking SMTP Settings', 'debug');
-    try {
-        $mail = new PHPMailer(true);
-
-        //Server settings
-        // Send using SMTP
-        $mail->isSMTP();
-        $mail->Host = $_POST['host'];
-        // Enable SMTP authentication
-        $mail->SMTPAuth = true;
-        $mail->Username = $_POST['user'];
-        $mail->Password = $_POST['pass'];
-        $mail->SMTPSecure = $_POST['encryption'];
-        $mail->Port = (int) $_POST['port'];
-
-        // Test E-mail metadata
-        $mail->setFrom($_POST['user'], $_POST['user']);
-        $mail->addAddress($_POST['user'], $_POST['user']);
-
-        // Content
-        // Set email format to HTML
-        $mail->isHTML(true);
-        $mail->Subject = 'It Worked! - Test E-Mail from Ctrlpanel.gg';
-        $mail->Body = 'Your E-Mail Settings are correct!';
-
-        $mail->send();
-    } catch (Exception $e) {
-        wh_log($mail->ErrorInfo, 'error');
-        header('LOCATION: index.php?step=6&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
-        exit();
-    }
-
-    wh_log('SMTP Settings are correct', 'debug');
-    wh_log('Updating Database', 'debug');
-    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
-    if ($db->connect_error) {
-        wh_log($db->connect_error, 'error');
-        header('LOCATION: index.php?step=6&message=Could not connect to the Database: ');
-        exit();
-    }
-    $values = [
-        'mail_mailer' => $_POST['method'],
-        'mail_host' => $_POST['host'],
-        'mail_port' => $_POST['port'],
-        'mail_username' => $_POST['user'],
-        'mail_password' => $_POST['pass'],
-        'mail_encryption' => $_POST['encryption'],
-        'mail_from_address' => $_POST['user'],
-    ];
-
-    foreach ($values as $key => $value) {
-        run_console("php artisan settings:set 'MailSettings' '$key' '$value'");
-    }
-
-    wh_log('Database updated', 'debug');
-    header('LOCATION: index.php?step=7');
-}
-
-if (isset($_POST['checkPtero'])) {
-    wh_log('Checking Pterodactyl Settings', 'debug');
-
-    $url = $_POST['url'];
-    $key = $_POST['key'];
-    $clientkey = $_POST['clientkey'];
-
-    $parsedUrl = parse_url($url);
-
-    if (!isset($parsedUrl['scheme'])) {
-        header('LOCATION: index.php?step=7&message=Please set an URL Scheme like "https://"!');
-        exit();
-    }
-
-    if (!isset($parsedUrl['host'])) {
-        header('LOCATION: index.php?step=7&message=Please set an valid URL host like "https://panel.example.com"!');
-        exit();
-    }
-
-    $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
-
-    $callpteroURL = $url . '/api/client/account';
-    $call = curl_init();
-
-    curl_setopt($call, CURLOPT_URL, $callpteroURL);
-    curl_setopt($call, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($call, CURLOPT_HTTPHEADER, [
-        'Accept: Application/vnd.pterodactyl.v1+json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $clientkey,
-    ]);
-    $callresponse = curl_exec($call);
-    $callresult = json_decode($callresponse, true);
-    curl_close($call);
-
-    $pteroURL = $url . '/api/application/users';
-    $ch = curl_init();
-
-    curl_setopt($ch, CURLOPT_URL, $pteroURL);
-    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: Application/vnd.pterodactyl.v1+json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $key,
-    ]);
-    $response = curl_exec($ch);
-    $result = json_decode($response, true);
-    curl_close($ch);
-
-    if (!is_array($result)) {
-        wh_log('No array in response found', 'error');
-        header('LOCATION: index.php?step=7&message=An unknown Error occured, please try again!');
-    }
-
-    if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
-        wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
-        header('LOCATION: index.php?step=7&message=Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!');
-        exit();
-    }
-
-    if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
-        wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
-        header('LOCATION: index.php?step=7&message=Your ClientAPI Key is wrong or the account is not an admin!');
-        exit();
-    }
-
-    try {
-        run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
-        run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
-        run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
-        wh_log('Database updated', 'debug');
-        header('LOCATION: index.php?step=8');
-    } catch (Throwable $th) {
-        wh_log("Setting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
-        exit();
-    }
-}
-
-if (isset($_POST['createUser'])) {
-    wh_log('Getting Pterodactyl User', 'debug');
-
-    try {
-        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
-    } catch (Throwable $th) {
-        wh_log($th->getMessage(), 'error');
-        header('LOCATION: index.php?step=8&message=Could not connect to the Database');
-        exit();
-    }
-
-    $pteroID = $_POST['pteroID'];
-    $pass = $_POST['pass'];
-    $repass = $_POST['repass'];
-
-    try {
-        $panelUrl = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
-        $adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
-    } catch (Throwable $th) {
-        wh_log("Getting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
-        exit();
-    }
-
-    $panelApiUrl = $panelUrl . '/api/application/users/' . $pteroID;
-
-    $ch = curl_init();
-
-    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
-    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: application/json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $adminToken,
-    ]);
-    $response = curl_exec($ch);
-    $result = json_decode($response, true);
-    curl_close($ch);
-
-    if ($pass !== $repass) {
-        header('LOCATION: index.php?step=8&message=The Passwords did not match!');
-        exit();
-    }
-
-    if (array_key_exists('errors', $result)) {
-        header('LOCATION: index.php?step=8&message=Could not find the user with pterodactyl ID ' . $pteroID);
-        exit();
-    }
-
-    $mail = $result['attributes']['email'];
-    $name = $result['attributes']['username'];
-    $pass = password_hash($pass, PASSWORD_DEFAULT);
-
-    $ch = curl_init();
-
-    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
-    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: application/json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $adminToken,
-    ]);
-    curl_setopt($ch, CURLOPT_POSTFIELDS, [
-        'email' => $mail,
-        'username' => $name,
-        'first_name' => $name,
-        'last_name' => $name,
-        'password' => $pass,
-    ]);
-    $response = curl_exec($ch);
-    $result = json_decode($response, true);
-    curl_close($ch);
-
-    $random = generateRandomString();
-
-    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
-    $query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
-    try {
-        $db->query($query1);
-        $db->query($query2);
-
-        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
-        header('LOCATION: index.php?step=9');
-    } catch (Throwable $th) {
-        wh_log($th->getMessage(), 'error');
-        if (str_contains($th->getMessage(), 'Duplicate entry')) {
-            header('LOCATION: index.php?step=8&message=User already exists in CtrlPanel\'s Database.');
-        } else {
-            header('LOCATION: index.php?step=8&message=Something went wrong when communicating with the Database.');
-        }
-        exit();
-    }
-}
diff --git a/public/installer/functions.php b/public/installer/functions.php
deleted file mode 100644
index e450e8cc1..000000000
--- a/public/installer/functions.php
+++ /dev/null
@@ -1,280 +0,0 @@
-<?php
-require '../../vendor/autoload.php';
-require 'dotenv.php';
-
-use DevCoder\DotEnv;
-use Illuminate\Encryption\Encrypter;
-use Illuminate\Support\Str;
-use Monolog\Formatter\LineFormatter;
-use Monolog\Handler\StreamHandler;
-use Monolog\Logger;
-
-if (!file_exists('../../.env')) {
-    echo run_console('cp .env.example .env');
-}
-
-(new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
-
-$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
-
-$requirements = [
-    'minPhp' => '8.1',
-    'maxPhp' => '8.4', // This version is not supported
-    'mysql' => '5.7.22',
-];
-
-/**
- * Check if the minimum PHP version is present
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function checkPhpVersion(): string
-{
-    global $requirements;
-
-    wh_log('php version: ' . phpversion(), 'debug');
-    if (version_compare(phpversion(), $requirements['minPhp'], '>=') && version_compare(phpversion(), $requirements['maxPhp'], '<=')) {
-        return 'OK';
-    }
-
-    return 'not OK';
-}
-
-/**
- * Check if the environment file is writable
- * @return bool Returns true on writable and false on not writable.
- */
-function checkWriteable(): bool
-{
-    return is_writable('../../.env');
-}
-
-/**
- * Check if zip is installed using a shell command
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function getZipVersion(): string
-{
-    wh_log('attempting to get zip version', 'debug');
-    $output = shell_exec('zip  -v') ?? '';
-    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? 0;
-    wh_log('zip version: ' . $versionoutput, 'debug');
-
-    return $versionoutput != 0 ? 'OK' : 'not OK';
-}
-
-/**
- * Check if git is installed using a shell command
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function getGitVersion(): string
-{
-    wh_log('attempting to get git version', 'debug');
-    $output = shell_exec('git  --version') ?? '';
-    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? 0;
-    wh_log('git version: ' . $versionoutput, 'debug');
-
-    return $versionoutput != 0 ? 'OK' : 'not OK';
-}
-
-/**
- * Check if tar is installed using a shell command
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function getTarVersion(): string
-{
-    wh_log('attempting to get tar version', 'debug');
-    $output = shell_exec('tar  --version') ?? '';
-    preg_match('@[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? 0;
-    wh_log('tar version: ' . $versionoutput, 'debug');
-
-    return $versionoutput != 0 ? 'OK' : 'not OK';
-}
-
-/**
- * Check all extensions to see if they have loaded or not
- * @return array Returns an array of extensions that failed to load.
- */
-function checkExtensions(): array
-{
-    global $required_extensions;
-
-    wh_log('checking extensions', 'debug');
-
-    $not_ok = [];
-    $extentions = get_loaded_extensions();
-
-    foreach ($required_extensions as $ext) {
-        if (!preg_grep('/^(?=.*' . $ext . ').*$/', $extentions)) {
-            array_push($not_ok, $ext);
-        }
-    }
-
-    wh_log('loaded extensions:', 'debug', $extentions);
-    wh_log('failed extensions:', 'debug', $not_ok);
-    return $not_ok;
-}
-
-function removeQuotes($string)
-{
-    return str_replace('"', "", $string);
-}
-
-/**
- * Sets the environment variable into the env file
- * @param string $envKey The environment key to set or modify
- * @param string $envValue The environment variable to set
- * @return bool true on success or false on failure.
- */
-function setenv($envKey, $envValue)
-{
-    $envFile = dirname(__FILE__, 3) . '/.env';
-    $str = file_get_contents($envFile);
-
-    $str .= "\n"; // In case the searched variable is in the last line without \n
-    $keyPosition = strpos($str, "{$envKey}=");
-    $endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
-    $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
-    $str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
-    $str = substr($str, 0, -1);
-
-    $fp = fopen($envFile, 'w');
-    fwrite($fp, $str);
-    fclose($fp);
-}
-
-/**
- * Encrypt the given value
- * @param mixed $value The variable to be encrypted
- * @param bool $serialize If the encryption should be serialized
- * @return string Returns the encrypted variable.
- */
-function encryptSettingsValue(mixed $value, $serialize = true): string
-{
-    $appKey = getenv('APP_KEY');
-    $appKey = base64_decode(Str::after($appKey, 'base64:'));
-    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
-    $encryptedKey = $encrypter->encrypt($value, $serialize);
-
-    return $encryptedKey;
-}
-
-/**
- * Decrypt the given value
- * @param mixed $payload The payload to be decrypted
- * @param bool $unserialize If the encryption should be unserialized
- * @return mixed Returns the decrypted variable on success, throws otherwise.
- */
-
-function decryptSettingsValue(mixed $payload, $unserialize = true)
-{
-    $appKey = getenv('APP_KEY');
-    $appKey = base64_decode(Str::after($appKey, 'base64:'));
-    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
-    $decryptedKey = $encrypter->decrypt($payload, $unserialize);
-
-    return $decryptedKey;
-}
-
-/**
- * Run a shell command
- * @param string $command The command string to run
- * @param array|null $descriptors [optional]<p>
- * An indexed array where the key represents the descriptor number and the value represents how PHP will pass that descriptor to the child process. 0 is stdin, 1 is stdout, while 2 is stderr.
- * Default descriptors when null are 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']
- * </p>
- * @param string|null $cwd [optional] <p>
- * The initial working dir for the command. This must be an
- * absolute directory path, or null
- * if you want to use the default value (the working dir of the current
- * PHP process)
- * </p>
- * @param array|null $options [optional] <p>
- * Allows you to specify additional options.
- * @link https://www.php.net/manual/en/function.proc-open.php proc_open
- * </p>
- * @return false|string|null Returns the result from the command.
- */
-function run_console(string $command, array $descriptors = null, string $cwd = null, array $options = null)
-{
-    wh_log('running command: ' . $command, 'debug');
-
-    $path = dirname(__FILE__, 3);
-    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
-    $output = stream_get_contents($pipes[1]);
-    $exit_code = proc_close($handle);
-
-    if ($exit_code > 0) {
-        wh_log('command result: ' . $output, 'error');
-        throw new Exception("There was an error after running command `$command`", $exit_code);
-        return $output;
-    } else {
-        return $output;
-    }
-}
-
-/**
- * Log to the default laravel.log file
- * @param string $message The message to log
- * @param string $level The log level to use (debug, info, warning, error, critical)
- * @param array $context [optional] The context to log extra information
- * @return void
- */
-function wh_log(string $message, string $level = 'info', array $context = []): void
-{
-    $formatter = new LineFormatter(null, null, true, true);
-    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG);
-    $stream->setFormatter($formatter);
-
-    $log = new Logger('CtrlPanel');
-    $log->pushHandler($stream);
-
-    switch (strtolower($level)) {
-        case 'debug': // Only log debug messages if APP_DEBUG is true
-            if (getenv('APP_DEBUG') === false) return;
-            $log->debug($message, $context);
-            break;
-        case 'info':
-            $log->info($message, $context);
-            break;
-        case 'warning':
-            $log->warning($message, $context);
-            break;
-        case 'error':
-            $log->error($message, $context);
-            break;
-        case 'critical':
-            $log->critical($message, $context);
-            break;
-    }
-    // Prevent memory leaks by resetting the logger
-    $log->reset();
-}
-
-/**
- * Generate a random string
- * @param int $length The length of the random string
- * @return string The randomly generated string.
- */
-function generateRandomString(int $length = 8): string
-{
-    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-    $charactersLength = strlen($characters);
-    $randomString = '';
-    for ($i = 0; $i < $length; $i++) {
-        $randomString .= $characters[rand(0, $charactersLength - 1)];
-    }
-
-    return $randomString;
-}
-
-function determineIfRunningInDocker(): bool
-{
-    return file_exists('/.dockerenv');
-}
diff --git a/public/installer/index.php b/public/installer/index.php
index 24ee47bbd..4feed33b6 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,28 +1,43 @@
 <?php
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
+error_reporting(E_ALL);
+
+session_start();
+
+use DevCoder\DotEnv;
+// use Illuminate\Encryption\Encrypter;
+// use Illuminate\Support\Str;
+
+require '../../vendor/autoload.php';
+require 'dotenv.php';
 
 // Include the function files
+require_once './src/functions/installer.php'; // very important
 require_once './src/functions/environment.php';
-require_once './src/functions/database.php';
 require_once './src/functions/shell.php';
 require_once './src/functions/logging.php';
 require_once './src/functions/utils.php';
 
 // Include the form files
-require_once './src/forms/timezone.php';
-require_once './src/forms/database.php';
-require_once './src/forms/redis.php';
-require_once './src/forms/dashboard.php';
-require_once './src/forms/smtp.php';
-require_once './src/forms/pterodactyl.php';
-require_once './src/forms/admin.php';
-
-require_once './functions.php';
-require_once './forms.php';
+include './src/forms/timezone.php';
+include './src/forms/database.php';
+include './src/forms/redis.php';
+include './src/forms/dashboard.php';
+include './src/forms/smtp.php';
+include './src/forms/pterodactyl.php';
+include './src/forms/admin.php';
 
 if (file_exists('../../install.lock')) {
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
+if (!file_exists('../../.env')) {
+    echo run_console('cp .env.example .env');
+}
+
+(new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
+
 $viewNames = [
     1 => 'mandatory-checks',
     2 => 'timezone-configuration',
@@ -36,7 +51,16 @@
     10 => 'installation-complete',
 ];
 
-$step = isset($_GET['step']) ? $_GET['step'] : 1;
+// Prioritize $_GET['step'], then session, then default to 1
+$step = isset($_GET['step'])
+    ? (int)$_GET['step']  // Convert to integer for safety
+    : (isset($_SESSION['installation_step'])
+        ? $_SESSION['installation_step']
+        : 1);
+
+// Update session with the current step
+$_SESSION['installation_step'] = $step;
+
 $viewName = $viewNames[$step];  // Get the appropriate view name
 
 // Load the layout and the specific view file
@@ -44,4 +68,7 @@
 include "./views/{$viewName}.php";
 include './views/layout-bottom.php';
 
+// setting / reseting the error message
+$_SESSION['error-message'] = null;
+
 ?>
\ No newline at end of file
diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
index e69de29bb..9d0df6229 100644
--- a/public/installer/src/forms/admin.php
+++ b/public/installer/src/forms/admin.php
@@ -0,0 +1,96 @@
+<?php
+
+if (isset($_POST['createUser'])) {
+    wh_log('Getting Pterodactyl User', 'debug');
+
+    try {
+        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
+    } catch (Throwable $th) {
+        wh_log($th->getMessage(), 'error');
+        send_error_message("Could not connect to the Database");
+        exit();
+    }
+
+    $pteroID = $_POST['pteroID'];
+    $pass = $_POST['pass'];
+    $repass = $_POST['repass'];
+
+    try {
+        $panelUrl = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
+        $adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
+    } catch (Throwable $th) {
+        wh_log("Getting Pterodactyl information failed.", 'error');
+        send_error_message($th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        exit();
+    }
+
+    $panelApiUrl = $panelUrl . '/api/application/users/' . $pteroID;
+
+    $ch = curl_init();
+
+    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, [
+        'Accept: application/json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $adminToken,
+    ]);
+    $response = curl_exec($ch);
+    $result = json_decode($response, true);
+    curl_close($ch);
+
+    if ($pass !== $repass) {
+        send_error_message("The Passwords did not match!");
+        exit();
+    }
+
+    if (array_key_exists('errors', $result)) {
+        send_error_message("Could not find the user with pterodactyl ID" . $pteroID);
+        exit();
+    }
+
+    $mail = $result['attributes']['email'];
+    $name = $result['attributes']['username'];
+    $pass = password_hash($pass, PASSWORD_DEFAULT);
+
+    $ch = curl_init();
+
+    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, [
+        'Accept: application/json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $adminToken,
+    ]);
+    curl_setopt($ch, CURLOPT_POSTFIELDS, [
+        'email' => $mail,
+        'username' => $name,
+        'first_name' => $name,
+        'last_name' => $name,
+        'password' => $pass,
+    ]);
+    $response = curl_exec($ch);
+    $result = json_decode($response, true);
+    curl_close($ch);
+
+    $random = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 8); // random referal
+
+    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
+    $query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
+    try {
+        $db->query($query1);
+        $db->query($query2);
+
+        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
+        next_step();
+    } catch (Throwable $th) {
+        wh_log($th->getMessage(), 'error');
+        if (str_contains($th->getMessage(), 'Duplicate entry')) {
+            send_error_message("User already exists in CtrlPanel\'s Database");
+        } else {
+            send_error_message("Something went wrong when communicating with the Database.");
+        }
+        exit();
+    }
+}
+?>
diff --git a/public/installer/src/forms/dashboard.php b/public/installer/src/forms/dashboard.php
index e69de29bb..2229d4133 100644
--- a/public/installer/src/forms/dashboard.php
+++ b/public/installer/src/forms/dashboard.php
@@ -0,0 +1,29 @@
+<?php
+
+
+if (isset($_POST['checkGeneral'])) {
+    wh_log('setting app settings', 'debug');
+    $appname = '"' . $_POST['name'] . '"';
+    $appurl = $_POST['url'];
+
+    $parsedUrl = parse_url($appurl);
+
+    if (!isset($parsedUrl['scheme'])) {
+        send_error_message("Please set an URL Scheme like 'https://'!");
+        exit();
+    }
+
+    if (!isset($parsedUrl['host'])) {
+        send_error_message("Please set an valid URL host like 'https://ctrlpanel.example.com'!");
+        exit();
+    }
+
+    $appurl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
+
+    setenv('APP_NAME', $appname);
+    setenv('APP_URL', $appurl);
+
+    wh_log('App settings set', 'debug');
+    next_step();
+}
+?>
\ No newline at end of file
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index e69de29bb..8e0bdb615 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -0,0 +1,62 @@
+<?php
+
+mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);
+
+if (isset($_POST['checkDB'])) {
+    $values = [
+        //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
+        'DB_HOST' => 'databasehost',
+        'DB_DATABASE' => 'database',
+        'DB_USERNAME' => 'databaseuser',
+        'DB_PASSWORD' => 'databaseuserpass',
+        'DB_PORT' => 'databaseport',
+        'DB_CONNECTION' => 'databasedriver',
+    ];
+
+    wh_log('Trying to connect to the Database', 'debug');
+
+    try {
+        $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
+    } catch (mysqli_sql_exception $e) {
+        wh_log($e->getMessage(), 'error');
+        send_error_message($e->getMessage());
+        exit();
+    }
+
+    foreach ($values as $key => $value) {
+        $param = $_POST[$value];
+        setenv($key, $param);
+    }
+
+    wh_log('Database connection successful', 'debug');
+    next_step();
+}
+
+if (isset($_POST['feedDB'])) {
+    wh_log('Feeding the Database', 'debug');
+    $logs = '';
+
+    try {
+        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
+        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
+        if (!str_contains(getenv('APP_KEY'), 'base64')) {
+            $logs .= run_console('php artisan key:generate --force');
+        } else {
+            $logs .= "Key already exists. Skipping\n";
+        }
+        $logs .= run_console('php artisan storage:link');
+        $logs .= run_console('php artisan migrate --seed --force');
+        $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
+        $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
+
+        wh_log($logs, 'debug');
+
+        wh_log('Feeding the Database successful', 'debug');
+        next_step();
+    } catch (Throwable $th) {
+        wh_log('Feeding the Database failed', 'error');
+        send_error_message("Feeding the Database failed");
+    }
+}
+
+?>
diff --git a/public/installer/src/forms/pterodactyl.php b/public/installer/src/forms/pterodactyl.php
index e69de29bb..d4c24dd94 100644
--- a/public/installer/src/forms/pterodactyl.php
+++ b/public/installer/src/forms/pterodactyl.php
@@ -0,0 +1,80 @@
+<?php
+if (isset($_POST['checkPtero'])) {
+    wh_log('Checking Pterodactyl Settings', 'debug');
+
+    $url = $_POST['url'];
+    $key = $_POST['key'];
+    $clientkey = $_POST['clientkey'];
+
+    $parsedUrl = parse_url($url);
+
+    if (!isset($parsedUrl['scheme'])) {
+        send_error_message("Please set an URL Scheme like 'https://'!");
+        exit();
+    }
+
+    if (!isset($parsedUrl['host'])) {
+        send_error_message("Please set an valid URL host like 'https://panel.example.com'!");
+        exit();
+    }
+
+    $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
+
+    $callpteroURL = $url . '/api/client/account';
+    $call = curl_init();
+
+    curl_setopt($call, CURLOPT_URL, $callpteroURL);
+    curl_setopt($call, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($call, CURLOPT_HTTPHEADER, [
+        'Accept: Application/vnd.pterodactyl.v1+json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $clientkey,
+    ]);
+    $callresponse = curl_exec($call);
+    $callresult = json_decode($callresponse, true);
+    curl_close($call);
+
+    $pteroURL = $url . '/api/application/users';
+    $ch = curl_init();
+
+    curl_setopt($ch, CURLOPT_URL, $pteroURL);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, [
+        'Accept: Application/vnd.pterodactyl.v1+json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $key,
+    ]);
+    $response = curl_exec($ch);
+    $result = json_decode($response, true);
+    curl_close($ch);
+
+    if (!is_array($result)) {
+        wh_log('No array in response found', 'error');
+        send_error_message("An unknown Error occured, please try again!");
+    }
+
+    if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
+        wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
+        send_error_message("Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!");
+        exit();
+    }
+
+    if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
+        wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
+        send_error_message("Your ClientAPI Key is wrong or the account is not an admin!");
+        exit();
+    }
+
+    try {
+        run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
+        run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
+        run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
+        wh_log('Database updated', 'debug');
+        next_step();
+    } catch (Throwable $th) {
+        wh_log("Setting Pterodactyl information failed.", 'error');
+        send_error_message($th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        exit();
+    }
+}
+?>
\ No newline at end of file
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
index e69de29bb..6837df3ae 100644
--- a/public/installer/src/forms/redis.php
+++ b/public/installer/src/forms/redis.php
@@ -0,0 +1,32 @@
+<?php
+
+
+if (isset($_POST['redisSetup'])) {
+    wh_log('Setting up Redis', 'debug');
+    $redisHost = $_POST['redishost'];
+    $redisPort = $_POST['redisport'];
+    $redisPassword = $_POST['redispassword'];
+
+    $redisClient = new Client([
+        'host'     => $redisHost,
+        'port'     => $redisPort,
+        'password' => $redisPassword,
+        'timeout'  => 1.0,
+    ]);
+
+    try {
+        $redisClient->ping();
+
+        setenv('MEMCACHED_HOST', $redisHost);
+        setenv('REDIS_HOST', $redisHost);
+        setenv('REDIS_PORT', $redisPort);
+        setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
+
+        wh_log('Redis connection successful. Settings updated.', 'debug');
+        next_step();
+    } catch (Throwable $th) {
+        wh_log('Redis connection failed. Settings updated.', 'debug');
+        send_error_message("Please check your credentials!<br>" . $th->getMessage());
+    }
+}
+?>
diff --git a/public/installer/src/forms/smtp.php b/public/installer/src/forms/smtp.php
index e69de29bb..0ec801da9 100644
--- a/public/installer/src/forms/smtp.php
+++ b/public/installer/src/forms/smtp.php
@@ -0,0 +1,71 @@
+<?php
+
+use PHPMailer\PHPMailer\Exception;
+use PHPMailer\PHPMailer\PHPMailer;
+use Predis\Client;
+
+require './src/phpmailer/Exception.php';
+require './src/phpmailer/PHPMailer.php';
+require './src/phpmailer/SMTP.php';
+
+
+if (isset($_POST['checkSMTP'])) {
+    wh_log('Checking SMTP Settings', 'debug');
+    try {
+        $mail = new PHPMailer(true);
+
+        //Server settings
+        // Send using SMTP
+        $mail->isSMTP();
+        $mail->Host = $_POST['host'];
+        // Enable SMTP authentication
+        $mail->SMTPAuth = true;
+        $mail->Username = $_POST['user'];
+        $mail->Password = $_POST['pass'];
+        $mail->SMTPSecure = $_POST['encryption'];
+        $mail->Port = (int) $_POST['port'];
+
+        // Test E-mail metadata
+        $mail->setFrom($_POST['user'], $_POST['user']);
+        $mail->addAddress($_POST['user'], $_POST['user']);
+
+        // Content
+        // Set email format to HTML
+        $mail->isHTML(true);
+        $mail->Subject = 'It Worked! - Test E-Mail from Ctrlpanel.gg';
+        $mail->Body = 'Your E-Mail Settings are correct!';
+
+        $mail->send();
+    } catch (Exception $e) {
+        wh_log($mail->ErrorInfo, 'error');
+        send_error_message("Something went wrong while sending test E-Mail!<br>" . $mail->ErrorInfo);
+        exit();
+    }
+
+    wh_log('SMTP Settings are correct', 'debug');
+    wh_log('Updating Database', 'debug');
+    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
+    if ($db->connect_error) {
+        wh_log($db->connect_error, 'error');
+        send_error_message("Could not connect to the Database");
+        exit();
+    }
+    $values = [
+        'mail_mailer' => $_POST['method'],
+        'mail_host' => $_POST['host'],
+        'mail_port' => $_POST['port'],
+        'mail_username' => $_POST['user'],
+        'mail_password' => $_POST['pass'],
+        'mail_encryption' => $_POST['encryption'],
+        'mail_from_address' => $_POST['user'],
+    ];
+
+    foreach ($values as $key => $value) {
+        run_console("php artisan settings:set 'MailSettings' '$key' '$value'");
+    }
+
+    wh_log('Database updated', 'debug');
+    next_step();
+}
+
+?>
\ No newline at end of file
diff --git a/public/installer/src/forms/timezone.php b/public/installer/src/forms/timezone.php
index e69de29bb..b3ff5fa2c 100644
--- a/public/installer/src/forms/timezone.php
+++ b/public/installer/src/forms/timezone.php
@@ -0,0 +1,13 @@
+<?php
+
+if (isset($_POST['timezoneConfig'])) {
+    wh_log('Setting up Timezone', 'debug');
+    $timezone = $_POST['timezone'];
+
+    setenv('APP_TIMEZONE', $timezone);
+
+    wh_log('Timezone set: ' . $timezone, 'debug');
+    next_step();
+}
+
+?>
\ No newline at end of file
diff --git a/public/installer/src/functions/database.php b/public/installer/src/functions/database.php
deleted file mode 100644
index e69de29bb..000000000
diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
index e69de29bb..3ae262c39 100644
--- a/public/installer/src/functions/environment.php
+++ b/public/installer/src/functions/environment.php
@@ -0,0 +1,132 @@
+<?php
+
+/**
+* Sets the environment variable into the env file
+ * @param string $envKey The environment key to set or modify
+ * @param string $envValue The environment variable to set
+ * @return bool true on success or false on failure.
+ */
+function setenv($envKey, $envValue)
+{
+    $envFile = dirname(__FILE__, 3) . '/.env';
+    $str = file_get_contents($envFile);
+
+    $str .= "\n"; // In case the searched variable is in the last line without \n
+    $keyPosition = strpos($str, "{$envKey}=");
+    $endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
+    $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
+    $str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
+    $str = substr($str, 0, -1);
+
+    $fp = fopen($envFile, 'w');
+    fwrite($fp, $str);
+    fclose($fp);
+}
+
+
+$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
+
+/**
+ * Check all extensions to see if they have loaded or not
+ * @return array Returns an array of extensions that failed to load.
+ */
+function checkExtensions(): array
+{
+    global $required_extensions;
+
+    wh_log('checking extensions', 'debug');
+
+    $not_ok = [];
+    $extentions = get_loaded_extensions();
+
+    foreach ($required_extensions as $ext) {
+        if (!preg_grep('/^(?=.*' . $ext . ').*$/', $extentions)) {
+            array_push($not_ok, $ext);
+        }
+    }
+
+    wh_log('loaded extensions:', 'debug', $extentions);
+    wh_log('failed extensions:', 'debug', $not_ok);
+    return $not_ok;
+}
+
+$requirements = [
+    'minPhp' => '8.1',
+    'maxPhp' => '8.4', // This version is not supported
+    'mysql' => '5.7.22',
+];
+
+/**
+ * Check if the minimum PHP version is present
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function checkPhpVersion(): string
+{
+    global $requirements;
+
+    wh_log('php version: ' . phpversion(), 'debug');
+    if (version_compare(phpversion(), $requirements['minPhp'], '>=') && version_compare(phpversion(), $requirements['maxPhp'], '<=')) {
+        return 'OK';
+    }
+
+    return 'not OK';
+}
+
+/**
+ * Check if zip is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getZipVersion(): string
+{
+    wh_log('attempting to get zip version', 'debug');
+    $output = shell_exec('zip  -v') ?? '';
+    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
+
+    $versionoutput = $version[0] ?? 0;
+    wh_log('zip version: ' . $versionoutput, 'debug');
+
+    return $versionoutput != 0 ? 'OK' : 'not OK';
+}
+
+/**
+ * Check if git is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getGitVersion(): string
+{
+    wh_log('attempting to get git version', 'debug');
+    $output = shell_exec('git  --version') ?? '';
+    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
+
+    $versionoutput = $version[0] ?? 0;
+    wh_log('git version: ' . $versionoutput, 'debug');
+
+    return $versionoutput != 0 ? 'OK' : 'not OK';
+}
+
+/**
+ * Check if tar is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getTarVersion(): string
+{
+    wh_log('attempting to get tar version', 'debug');
+    $output = shell_exec('tar  --version') ?? '';
+    preg_match('@[0-9]+\.[0-9]+@', $output, $version);
+
+    $versionoutput = $version[0] ?? 0;
+    wh_log('tar version: ' . $versionoutput, 'debug');
+
+    return $versionoutput != 0 ? 'OK' : 'not OK';
+}
+
+/**
+ * Check if the environment file is writable
+ * @return bool Returns true on writable and false on not writable.
+ */
+function checkWriteable(): bool
+{
+    return is_writable('../../.env');
+}
+
+?>
diff --git a/public/installer/src/functions/installer.php b/public/installer/src/functions/installer.php
new file mode 100644
index 000000000..24cbf5954
--- /dev/null
+++ b/public/installer/src/functions/installer.php
@@ -0,0 +1,16 @@
+<?php
+
+function send_error_message(string $message): void
+{
+    $_SESSION['error-message'] = $message;
+    header("LOCATION: index.php");
+    exit();
+}
+
+function next_step(): void
+{
+    $_SESSION['installation_step']++;
+    header("LOCATION: index.php");
+}
+
+?>
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
index e69de29bb..f8151c4ec 100644
--- a/public/installer/src/functions/logging.php
+++ b/public/installer/src/functions/logging.php
@@ -0,0 +1,45 @@
+<?php
+
+use Monolog\Formatter\LineFormatter;
+use Monolog\Handler\StreamHandler;
+use Monolog\Logger;
+
+/**
+ * Log to the default laravel.log file
+ * @param string $message The message to log
+ * @param string $level The log level to use (debug, info, warning, error, critical)
+ * @param array $context [optional] The context to log extra information
+ * @return void
+ */
+function wh_log(string $message, string $level = 'info', array $context = []): void
+{
+    $formatter = new LineFormatter(null, null, true, true);
+    $stream = new StreamHandler(dirname(__FILE__, 3) . '../../storage/logs/installer.log', Logger::DEBUG);
+    $stream->setFormatter($formatter);
+
+    $log = new Logger('CtrlPanel');
+    $log->pushHandler($stream);
+
+    switch (strtolower($level)) {
+        case 'debug': // Only log debug messages if APP_DEBUG is true
+            if (getenv('APP_DEBUG') === false) return;
+            $log->debug($message, $context);
+            break;
+        case 'info':
+            $log->info($message, $context);
+            break;
+        case 'warning':
+            $log->warning($message, $context);
+            break;
+        case 'error':
+            $log->error($message, $context);
+            break;
+        case 'critical':
+            $log->critical($message, $context);
+            break;
+    }
+    // Prevent memory leaks by resetting the logger
+    $log->reset();
+}
+
+?>
diff --git a/public/installer/src/functions/shell.php b/public/installer/src/functions/shell.php
index e69de29bb..c0ebb8e62 100644
--- a/public/installer/src/functions/shell.php
+++ b/public/installer/src/functions/shell.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * Run a shell command
+ * @param string $command The command string to run
+ * @param array|null $descriptors [optional]<p>
+ * An indexed array where the key represents the descriptor number and the value represents how PHP will pass that descriptor to the child process. 0 is stdin, 1 is stdout, while 2 is stderr.
+ * Default descriptors when null are 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']
+ * </p>
+ * @param string|null $cwd [optional] <p>
+ * The initial working dir for the command. This must be an
+ * absolute directory path, or null
+ * if you want to use the default value (the working dir of the current
+ * PHP process)
+ * </p>
+ * @param array|null $options [optional] <p>
+ * Allows you to specify additional options.
+ * @link https://www.php.net/manual/en/function.proc-open.php proc_open
+ * </p>
+ * @return false|string|null Returns the result from the command.
+ */
+function run_console(string $command, array $descriptors = null, string $cwd = null, array $options = null)
+{
+    wh_log('running command: ' . $command, 'debug');
+
+    $path = dirname(__FILE__, 3);
+    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
+    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
+    $output = stream_get_contents($pipes[1]);
+    $exit_code = proc_close($handle);
+
+    if ($exit_code > 0) {
+        wh_log('command result: ' . $output, 'error');
+        throw new Exception("There was an error after running command `$command`", $exit_code);
+        return $output;
+    } else {
+        return $output;
+    }
+}
+
+?>
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
index e69de29bb..381064027 100644
--- a/public/installer/src/functions/utils.php
+++ b/public/installer/src/functions/utils.php
@@ -0,0 +1,41 @@
+<?php
+
+function determineIfRunningInDocker(): bool
+{
+    return file_exists('/.dockerenv');
+}
+
+/**
+ * Encrypt the given value
+ * @param mixed $value The variable to be encrypted
+ * @param bool $serialize If the encryption should be serialized
+ * @return string Returns the encrypted variable.
+ */
+function encryptSettingsValue(mixed $value, $serialize = true): string
+{
+    $appKey = getenv('APP_KEY');
+    $appKey = base64_decode(Str::after($appKey, 'base64:'));
+    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
+    $encryptedKey = $encrypter->encrypt($value, $serialize);
+
+    return $encryptedKey;
+}
+
+/**
+ * Decrypt the given value
+ * @param mixed $payload The payload to be decrypted
+ * @param bool $unserialize If the encryption should be unserialized
+ * @return mixed Returns the decrypted variable on success, throws otherwise.
+ */
+
+function decryptSettingsValue(mixed $payload, $unserialize = true)
+{
+    $appKey = getenv('APP_KEY');
+    $appKey = base64_decode(Str::after($appKey, 'base64:'));
+    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
+    $decryptedKey = $encrypter->decrypt($payload, $unserialize);
+
+    return $decryptedKey;
+}
+
+?>
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index b2eb9fa4f..19fe8c83e 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -6,10 +6,10 @@
     $subtitle = "Lets create the first admin user!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="createUser">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="form-group">
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index 642b0ddf5..76e6fc0b8 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -5,10 +5,10 @@
     $title = "Dashboard Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkGeneral">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index 5aa96dd20..623e92838 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -5,10 +5,10 @@
     $title = "Database Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkDB">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index cf12ba40c..cace87f77 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -6,10 +6,10 @@
     $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="feedDB">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="w-full flex justify-center">
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index a7545fdae..195a4ad91 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -6,10 +6,10 @@
     $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkSMTP">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index 47ca4acda..83100192f 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -6,10 +6,10 @@
     $subtitle = "Lets get some info about your Pterodactyl Installation!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkPtero">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index 76bc67380..24ad5d3b5 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -5,10 +5,10 @@
     $title = "Redis Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="redisSetup">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 0d2228773..4d57cfb1b 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -4,10 +4,10 @@
     $title = "Timezone Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="timezoneConfig">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">

From d08915d51fc683fc45e063b2ff1f96b27256ebe5 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 14 Jun 2024 00:00:19 +0200
Subject: [PATCH 411/514] refactor: refactored a lot of thing in the installer
 and added progress bar and next and previous button, and a footer and fixed
 some bugs

---
 public/installer/index.php                    |  71 +-
 public/installer/src/forms/admin.php          |   1 +
 public/installer/src/forms/dashboard.php      |   4 +-
 public/installer/src/forms/database.php       |   2 -
 public/installer/src/forms/redis.php          |   2 +-
 .../installer/src/functions/environment.php   |   5 +-
 public/installer/src/functions/installer.php  |   2 +-
 public/installer/src/functions/logging.php    |   2 +-
 public/installer/src/functions/shell.php      |   2 +-
 public/installer/src/functions/utils.php      |  10 +-
 public/installer/styles.css                   | 968 +++++++++++++++++-
 public/installer/views/admin-creation.php     |  27 +-
 .../views/dashboard-configuration.php         |  27 +-
 .../views/database-configuration.php          |  27 +-
 public/installer/views/database-migration.php |  27 +-
 .../installer/views/email-configuration.php   |  31 +-
 .../installer/views/installation-complete.php |   2 +-
 public/installer/views/layout-bottom.php      |   5 +
 public/installer/views/layout-top.php         |  35 +-
 public/installer/views/mandatory-checks.php   |  32 +-
 .../views/pterodactyl-configuration.php       |  27 +-
 .../installer/views/redis-configuration.php   |  27 +-
 .../views/timezone-configuration.php          |  32 +-
 23 files changed, 1271 insertions(+), 97 deletions(-)

diff --git a/public/installer/index.php b/public/installer/index.php
index 4feed33b6..a51c67455 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,4 +1,5 @@
 <?php
+// repport all error
 ini_set('display_errors', 1);
 ini_set('display_startup_errors', 1);
 error_reporting(E_ALL);
@@ -6,17 +7,16 @@
 session_start();
 
 use DevCoder\DotEnv;
-// use Illuminate\Encryption\Encrypter;
-// use Illuminate\Support\Str;
 
-require '../../vendor/autoload.php';
-require 'dotenv.php';
+// Include systems
+require_once '../../vendor/autoload.php';
+require_once 'dotenv.php';
+require_once './src/functions/installer.php';
 
 // Include the function files
-require_once './src/functions/installer.php'; // very important
+require_once './src/functions/logging.php';
 require_once './src/functions/environment.php';
 require_once './src/functions/shell.php';
-require_once './src/functions/logging.php';
 require_once './src/functions/utils.php';
 
 // Include the form files
@@ -33,35 +33,52 @@
 }
 
 if (!file_exists('../../.env')) {
-    echo run_console('cp .env.example .env');
+    echo run_console('cp ../../.env.example ../../.env');
 }
 
+// load all the .env value in php env
 (new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
 
-$viewNames = [
-    1 => 'mandatory-checks',
-    2 => 'timezone-configuration',
-    3 => 'database-configuration',
-    4 => 'database-migration',
-    5 => 'redis-configuration',
-    6 => 'dashboard-configuration',
-    7 => 'email-configuration',
-    8 => 'pterodactyl-configuration',
-    9 => 'admin-creation',
-    10 => 'installation-complete',
+$stepConfig = [
+    1 => ['view' => 'mandatory-checks', 'is_revertable' => false],
+    2 => ['view' => 'timezone-configuration', 'is_revertable' => true],
+    3 => ['view' => 'database-configuration', 'is_revertable' => true],
+    4 => ['view' => 'database-migration', 'is_revertable' => false],
+    5 => ['view' => 'redis-configuration', 'is_revertable' => true],
+    6 => ['view' => 'dashboard-configuration', 'is_revertable' => true],
+    7 => ['view' => 'email-configuration', 'is_revertable' => true],
+    8 => ['view' => 'pterodactyl-configuration', 'is_revertable' => false],
+    9 => ['view' => 'admin-creation', 'is_revertable' => false],
+    10 => ['view' => 'installation-complete', 'is_revertable' => false],
 ];
 
-// Prioritize $_GET['step'], then session, then default to 1
-$step = isset($_GET['step'])
-    ? (int)$_GET['step']  // Convert to integer for safety
-    : (isset($_SESSION['installation_step'])
-        ? $_SESSION['installation_step']
-        : 1);
+$_SESSION['last_installation_step'] = count($stepConfig);
+
+// Initialize or get the current step:
+if (!isset($_SESSION['current_installation_step'])) {
+    // Session variable is not set, initialize it in the SESSION
+    $_SESSION['current_installation_step'] = 1;
+}
+
+if (isset($_GET['step'])) {
+    $stepValue = $_GET['step'];
+
+    if (is_numeric($stepValue) && $stepValue >= 1 && $stepValue <= $_SESSION['last_installation_step']) {
+        // Step is valid numeric within range:
+        $_SESSION['current_installation_step'] = $stepValue;
+    } elseif (strtolower($stepValue) === 'next' && $_SESSION['current_installation_step'] < $_SESSION['last_installation_step']) {
+        // Move to next step:
+        $_SESSION['current_installation_step']++;
+    } elseif (strtolower($stepValue) === 'previous' && $_SESSION['current_installation_step'] > 1) {
+        // Move to previous step:
+        $_SESSION['current_installation_step']--;
+    }
+}
 
-// Update session with the current step
-$_SESSION['installation_step'] = $step;
+$viewName = $stepConfig[$_SESSION['current_installation_step']]['view'];
 
-$viewName = $viewNames[$step];  // Get the appropriate view name
+// Set previous button availability based on step reversibility
+$_SESSION['is_previous_button_available'] = $_SESSION['current_installation_step'] > 1 && $stepConfig[$_SESSION['current_installation_step'] - 1]['is_revertable'];
 
 // Load the layout and the specific view file
 include './views/layout-top.php';
diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
index 9d0df6229..b909f9451 100644
--- a/public/installer/src/forms/admin.php
+++ b/public/installer/src/forms/admin.php
@@ -93,4 +93,5 @@
         exit();
     }
 }
+
 ?>
diff --git a/public/installer/src/forms/dashboard.php b/public/installer/src/forms/dashboard.php
index 2229d4133..79804edd6 100644
--- a/public/installer/src/forms/dashboard.php
+++ b/public/installer/src/forms/dashboard.php
@@ -1,6 +1,5 @@
 <?php
 
-
 if (isset($_POST['checkGeneral'])) {
     wh_log('setting app settings', 'debug');
     $appname = '"' . $_POST['name'] . '"';
@@ -26,4 +25,5 @@
     wh_log('App settings set', 'debug');
     next_step();
 }
-?>
\ No newline at end of file
+
+?>
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index 8e0bdb615..24d5dc816 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -37,8 +37,6 @@
     $logs = '';
 
     try {
-        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
-        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
         if (!str_contains(getenv('APP_KEY'), 'base64')) {
             $logs .= run_console('php artisan key:generate --force');
         } else {
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
index 6837df3ae..3e9ece35a 100644
--- a/public/installer/src/forms/redis.php
+++ b/public/installer/src/forms/redis.php
@@ -1,6 +1,5 @@
 <?php
 
-
 if (isset($_POST['redisSetup'])) {
     wh_log('Setting up Redis', 'debug');
     $redisHost = $_POST['redishost'];
@@ -29,4 +28,5 @@
         send_error_message("Please check your credentials!<br>" . $th->getMessage());
     }
 }
+
 ?>
diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
index 3ae262c39..c98223212 100644
--- a/public/installer/src/functions/environment.php
+++ b/public/installer/src/functions/environment.php
@@ -8,7 +8,9 @@
  */
 function setenv($envKey, $envValue)
 {
-    $envFile = dirname(__FILE__, 3) . '/.env';
+    $rootDirectory = dirname(__DIR__, 4);
+    $envFile = $rootDirectory . '/.env';
+
     $str = file_get_contents($envFile);
 
     $str .= "\n"; // In case the searched variable is in the last line without \n
@@ -23,7 +25,6 @@ function setenv($envKey, $envValue)
     fclose($fp);
 }
 
-
 $required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
 
 /**
diff --git a/public/installer/src/functions/installer.php b/public/installer/src/functions/installer.php
index 24cbf5954..169931ea4 100644
--- a/public/installer/src/functions/installer.php
+++ b/public/installer/src/functions/installer.php
@@ -9,7 +9,7 @@ function send_error_message(string $message): void
 
 function next_step(): void
 {
-    $_SESSION['installation_step']++;
+    $_SESSION['current_installation_step']++;
     header("LOCATION: index.php");
 }
 
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
index f8151c4ec..3960ca11f 100644
--- a/public/installer/src/functions/logging.php
+++ b/public/installer/src/functions/logging.php
@@ -14,7 +14,7 @@
 function wh_log(string $message, string $level = 'info', array $context = []): void
 {
     $formatter = new LineFormatter(null, null, true, true);
-    $stream = new StreamHandler(dirname(__FILE__, 3) . '../../storage/logs/installer.log', Logger::DEBUG);
+    $stream = new StreamHandler(dirname(__DIR__, 4) . '/storage/logs/installer.log', Logger::DEBUG);
     $stream->setFormatter($formatter);
 
     $log = new Logger('CtrlPanel');
diff --git a/public/installer/src/functions/shell.php b/public/installer/src/functions/shell.php
index c0ebb8e62..7a72fcedf 100644
--- a/public/installer/src/functions/shell.php
+++ b/public/installer/src/functions/shell.php
@@ -23,7 +23,7 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 {
     wh_log('running command: ' . $command, 'debug');
 
-    $path = dirname(__FILE__, 3);
+    $path = dirname(__DIR__, 4);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
     $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
     $output = stream_get_contents($pipes[1]);
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
index 381064027..8f13bb69a 100644
--- a/public/installer/src/functions/utils.php
+++ b/public/installer/src/functions/utils.php
@@ -1,9 +1,6 @@
 <?php
 
-function determineIfRunningInDocker(): bool
-{
-    return file_exists('/.dockerenv');
-}
+use Illuminate\Encryption\Encrypter;
 
 /**
  * Encrypt the given value
@@ -38,4 +35,9 @@ function decryptSettingsValue(mixed $payload, $unserialize = true)
     return $decryptedKey;
 }
 
+function determineIfRunningInDocker(): bool
+{
+    return file_exists('/.dockerenv');
+}
+
 ?>
diff --git a/public/installer/styles.css b/public/installer/styles.css
index 22f5b596a..b7db03605 100644
--- a/public/installer/styles.css
+++ b/public/installer/styles.css
@@ -1 +1,967 @@
-/*! tailwindcss v3.3.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#94a3b8}input::placeholder,textarea::placeholder{opacity:1;color:#94a3b8}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.absolute{position:absolute}.relative{position:relative}.m-0{margin:0}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.box-border{box-sizing:border-box}.block{display:block}.inline{display:inline}.flex{display:flex}.hidden{display:none}.w-1\/3{width:33.333333%}.w-full{width:100%}.min-w-fit{min-width:-moz-fit-content;min-width:fit-content}.list-none{list-style-type:none}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-around{justify-content:space-around}.gap-4{gap:1rem}.gap-8{gap:2rem}.rounded-2xl{border-radius:1rem}.rounded-md{border-radius:.375rem}.border-2{border-width:2px}.border-4{border-width:4px}.border-\[\#2E373B\]{--tw-border-opacity:1;border-color:rgb(46 55 59/var(--tw-border-opacity))}.border-transparent{border-color:#0000}.bg-\[\#1D2125\]{--tw-bg-opacity:1;background-color:rgb(29 33 37/var(--tw-bg-opacity))}.bg-\[\#242A2E\]{--tw-bg-opacity:1;background-color:rgb(36 42 46/var(--tw-bg-opacity))}.bg-green-500\/90{background-color:#22c55ee6}.bg-sky-500{--tw-bg-opacity:1;background-color:rgb(14 165 233/var(--tw-bg-opacity))}.bg-yellow-500\/90{background-color:#eab308e6}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.pt-3{padding-top:.75rem}.text-center{text-align:center}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-neutral-400{--tw-text-opacity:1;color:rgb(163 163 163/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.shadow-green-400{--tw-shadow-color:#4ade80;--tw-shadow:var(--tw-shadow-colored)}.shadow-sky-400{--tw-shadow-color:#38bdf8;--tw-shadow:var(--tw-shadow-colored)}.shadow-yellow-400{--tw-shadow-color:#facc15;--tw-shadow:var(--tw-shadow-colored)}.outline-none{outline:2px solid #0000;outline-offset:2px}.\[hostname\:port\]{hostname:port}.hover\:bg-green-600:hover{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity))}.hover\:bg-sky-600:hover{--tw-bg-opacity:1;background-color:rgb(2 132 199/var(--tw-bg-opacity))}.hover\:bg-yellow-600:hover{--tw-bg-opacity:1;background-color:rgb(202 138 4/var(--tw-bg-opacity))}.focus\:border-sky-500:focus{--tw-border-opacity:1;border-color:rgb(14 165 233/var(--tw-border-opacity))}.focus\:outline:focus{outline-style:solid}.focus\:outline-2:focus{outline-width:2px}.focus\:outline-offset-2:focus{outline-offset:2px}.focus\:outline-green-500:focus{outline-color:#22c55e}.focus\:outline-sky-500:focus{outline-color:#0ea5e9}.focus\:outline-yellow-600:focus{outline-color:#ca8a04}@media (min-width:640px){.sm\:w-auto{width:auto}.sm\:min-w-\[550px\]{min-width:550px}}
\ No newline at end of file
+/* 
+ * You need to have `tailwindcss` packages installed for these commands to work.
+ * 
+ * Build: `tailwindcss -i tailwind_styles.css -o styles.css -m`
+ * Dev: `tailwindcss -i tailwind_styles.css -o styles.css --watch` 
+ */
+
+/* 
+ ! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com 
+ */
+
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+
+*,
+::before,
+::after {
+  box-sizing: border-box;
+  /* 1 */
+  border-width: 0;
+  /* 2 */
+  border-style: solid;
+  /* 2 */
+  border-color: #e2e8f0;
+  /* 2 */
+}
+
+::before,
+::after {
+  --tw-content: '';
+}
+
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+5. Use the user's configured `sans` font-feature-settings by default.
+6. Use the user's configured `sans` font-variation-settings by default.
+7. Disable tap highlights on iOS
+*/
+
+html,
+:host {
+  line-height: 1.5;
+  /* 1 */
+  -webkit-text-size-adjust: 100%;
+  /* 2 */
+  -moz-tab-size: 4;
+  /* 3 */
+  -o-tab-size: 4;
+     tab-size: 4;
+  /* 3 */
+  font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+  /* 4 */
+  font-feature-settings: normal;
+  /* 5 */
+  font-variation-settings: normal;
+  /* 6 */
+  -webkit-tap-highlight-color: transparent;
+  /* 7 */
+}
+
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+
+body {
+  margin: 0;
+  /* 1 */
+  line-height: inherit;
+  /* 2 */
+}
+
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+
+hr {
+  height: 0;
+  /* 1 */
+  color: inherit;
+  /* 2 */
+  border-top-width: 1px;
+  /* 3 */
+}
+
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr:where([title]) {
+  -webkit-text-decoration: underline dotted;
+          text-decoration: underline dotted;
+}
+
+/*
+Remove the default font size and weight for headings.
+*/
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-size: inherit;
+  font-weight: inherit;
+}
+
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+
+a {
+  color: inherit;
+  text-decoration: inherit;
+}
+
+/*
+Add the correct font weight in Edge and Safari.
+*/
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/*
+1. Use the user's configured `mono` font-family by default.
+2. Use the user's configured `mono` font-feature-settings by default.
+3. Use the user's configured `mono` font-variation-settings by default.
+4. Correct the odd `em` font sizing in all browsers.
+*/
+
+code,
+kbd,
+samp,
+pre {
+  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+  /* 1 */
+  font-feature-settings: normal;
+  /* 2 */
+  font-variation-settings: normal;
+  /* 3 */
+  font-size: 1em;
+  /* 4 */
+}
+
+/*
+Add the correct font size in all browsers.
+*/
+
+small {
+  font-size: 80%;
+}
+
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+
+table {
+  text-indent: 0;
+  /* 1 */
+  border-color: inherit;
+  /* 2 */
+  border-collapse: collapse;
+  /* 3 */
+}
+
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit;
+  /* 1 */
+  font-feature-settings: inherit;
+  /* 1 */
+  font-variation-settings: inherit;
+  /* 1 */
+  font-size: 100%;
+  /* 1 */
+  font-weight: inherit;
+  /* 1 */
+  line-height: inherit;
+  /* 1 */
+  letter-spacing: inherit;
+  /* 1 */
+  color: inherit;
+  /* 1 */
+  margin: 0;
+  /* 2 */
+  padding: 0;
+  /* 3 */
+}
+
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+  text-transform: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+
+button,
+input:where([type='button']),
+input:where([type='reset']),
+input:where([type='submit']) {
+  -webkit-appearance: button;
+  /* 1 */
+  background-color: transparent;
+  /* 2 */
+  background-image: none;
+  /* 2 */
+}
+
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+
+:-moz-focusring {
+  outline: auto;
+}
+
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+
+:-moz-ui-invalid {
+  box-shadow: none;
+}
+
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+  vertical-align: baseline;
+}
+
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type='search'] {
+  -webkit-appearance: textfield;
+  /* 1 */
+  outline-offset: -2px;
+  /* 2 */
+}
+
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button;
+  /* 1 */
+  font: inherit;
+  /* 2 */
+}
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+  display: list-item;
+}
+
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+  margin: 0;
+}
+
+fieldset {
+  margin: 0;
+  padding: 0;
+}
+
+legend {
+  padding: 0;
+}
+
+ol,
+ul,
+menu {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+/*
+Reset default styling for dialogs.
+*/
+
+dialog {
+  padding: 0;
+}
+
+/*
+Prevent resizing textareas horizontally by default.
+*/
+
+textarea {
+  resize: vertical;
+}
+
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+
+input::-moz-placeholder, textarea::-moz-placeholder {
+  opacity: 1;
+  /* 1 */
+  color: #94a3b8;
+  /* 2 */
+}
+
+input::placeholder,
+textarea::placeholder {
+  opacity: 1;
+  /* 1 */
+  color: #94a3b8;
+  /* 2 */
+}
+
+/*
+Set the default cursor for buttons.
+*/
+
+button,
+[role="button"] {
+  cursor: pointer;
+}
+
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+
+:disabled {
+  cursor: default;
+}
+
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+   This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+  display: block;
+  /* 1 */
+  vertical-align: middle;
+  /* 2 */
+}
+
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+
+img,
+video {
+  max-width: 100%;
+  height: auto;
+}
+
+/* Make elements with the HTML hidden attribute stay hidden by default */
+
+[hidden] {
+  display: none;
+}
+
+*, ::before, ::after {
+  --tw-border-spacing-x: 0;
+  --tw-border-spacing-y: 0;
+  --tw-translate-x: 0;
+  --tw-translate-y: 0;
+  --tw-rotate: 0;
+  --tw-skew-x: 0;
+  --tw-skew-y: 0;
+  --tw-scale-x: 1;
+  --tw-scale-y: 1;
+  --tw-pan-x:  ;
+  --tw-pan-y:  ;
+  --tw-pinch-zoom:  ;
+  --tw-scroll-snap-strictness: proximity;
+  --tw-gradient-from-position:  ;
+  --tw-gradient-via-position:  ;
+  --tw-gradient-to-position:  ;
+  --tw-ordinal:  ;
+  --tw-slashed-zero:  ;
+  --tw-numeric-figure:  ;
+  --tw-numeric-spacing:  ;
+  --tw-numeric-fraction:  ;
+  --tw-ring-inset:  ;
+  --tw-ring-offset-width: 0px;
+  --tw-ring-offset-color: #fff;
+  --tw-ring-color: rgb(59 130 246 / 0.5);
+  --tw-ring-offset-shadow: 0 0 #0000;
+  --tw-ring-shadow: 0 0 #0000;
+  --tw-shadow: 0 0 #0000;
+  --tw-shadow-colored: 0 0 #0000;
+  --tw-blur:  ;
+  --tw-brightness:  ;
+  --tw-contrast:  ;
+  --tw-grayscale:  ;
+  --tw-hue-rotate:  ;
+  --tw-invert:  ;
+  --tw-saturate:  ;
+  --tw-sepia:  ;
+  --tw-drop-shadow:  ;
+  --tw-backdrop-blur:  ;
+  --tw-backdrop-brightness:  ;
+  --tw-backdrop-contrast:  ;
+  --tw-backdrop-grayscale:  ;
+  --tw-backdrop-hue-rotate:  ;
+  --tw-backdrop-invert:  ;
+  --tw-backdrop-opacity:  ;
+  --tw-backdrop-saturate:  ;
+  --tw-backdrop-sepia:  ;
+  --tw-contain-size:  ;
+  --tw-contain-layout:  ;
+  --tw-contain-paint:  ;
+  --tw-contain-style:  ;
+}
+
+::backdrop {
+  --tw-border-spacing-x: 0;
+  --tw-border-spacing-y: 0;
+  --tw-translate-x: 0;
+  --tw-translate-y: 0;
+  --tw-rotate: 0;
+  --tw-skew-x: 0;
+  --tw-skew-y: 0;
+  --tw-scale-x: 1;
+  --tw-scale-y: 1;
+  --tw-pan-x:  ;
+  --tw-pan-y:  ;
+  --tw-pinch-zoom:  ;
+  --tw-scroll-snap-strictness: proximity;
+  --tw-gradient-from-position:  ;
+  --tw-gradient-via-position:  ;
+  --tw-gradient-to-position:  ;
+  --tw-ordinal:  ;
+  --tw-slashed-zero:  ;
+  --tw-numeric-figure:  ;
+  --tw-numeric-spacing:  ;
+  --tw-numeric-fraction:  ;
+  --tw-ring-inset:  ;
+  --tw-ring-offset-width: 0px;
+  --tw-ring-offset-color: #fff;
+  --tw-ring-color: rgb(59 130 246 / 0.5);
+  --tw-ring-offset-shadow: 0 0 #0000;
+  --tw-ring-shadow: 0 0 #0000;
+  --tw-shadow: 0 0 #0000;
+  --tw-shadow-colored: 0 0 #0000;
+  --tw-blur:  ;
+  --tw-brightness:  ;
+  --tw-contrast:  ;
+  --tw-grayscale:  ;
+  --tw-hue-rotate:  ;
+  --tw-invert:  ;
+  --tw-saturate:  ;
+  --tw-sepia:  ;
+  --tw-drop-shadow:  ;
+  --tw-backdrop-blur:  ;
+  --tw-backdrop-brightness:  ;
+  --tw-backdrop-contrast:  ;
+  --tw-backdrop-grayscale:  ;
+  --tw-backdrop-hue-rotate:  ;
+  --tw-backdrop-invert:  ;
+  --tw-backdrop-opacity:  ;
+  --tw-backdrop-saturate:  ;
+  --tw-backdrop-sepia:  ;
+  --tw-contain-size:  ;
+  --tw-contain-layout:  ;
+  --tw-contain-paint:  ;
+  --tw-contain-style:  ;
+}
+
+.container {
+  width: 100%;
+}
+
+@media (min-width: 640px) {
+  .container {
+    max-width: 640px;
+  }
+}
+
+@media (min-width: 768px) {
+  .container {
+    max-width: 768px;
+  }
+}
+
+@media (min-width: 1024px) {
+  .container {
+    max-width: 1024px;
+  }
+}
+
+@media (min-width: 1280px) {
+  .container {
+    max-width: 1280px;
+  }
+}
+
+@media (min-width: 1536px) {
+  .container {
+    max-width: 1536px;
+  }
+}
+
+.static {
+  position: static;
+}
+
+.fixed {
+  position: fixed;
+}
+
+.absolute {
+  position: absolute;
+}
+
+.relative {
+  position: relative;
+}
+
+.bottom-0 {
+  bottom: 0px;
+}
+
+.m-0 {
+  margin: 0px;
+}
+
+.mx-2 {
+  margin-left: 0.5rem;
+  margin-right: 0.5rem;
+}
+
+.my-6 {
+  margin-top: 1.5rem;
+  margin-bottom: 1.5rem;
+}
+
+.mb-1 {
+  margin-bottom: 0.25rem;
+}
+
+.mb-2 {
+  margin-bottom: 0.5rem;
+}
+
+.mb-3 {
+  margin-bottom: 0.75rem;
+}
+
+.mt-2 {
+  margin-top: 0.5rem;
+}
+
+.mt-4 {
+  margin-top: 1rem;
+}
+
+.box-border {
+  box-sizing: border-box;
+}
+
+.block {
+  display: block;
+}
+
+.inline {
+  display: inline;
+}
+
+.flex {
+  display: flex;
+}
+
+.hidden {
+  display: none;
+}
+
+.w-full {
+  width: 100%;
+}
+
+.cursor-not-allowed {
+  cursor: not-allowed;
+}
+
+.list-none {
+  list-style-type: none;
+}
+
+.flex-col {
+  flex-direction: column;
+}
+
+.items-center {
+  align-items: center;
+}
+
+.justify-center {
+  justify-content: center;
+}
+
+.justify-between {
+  justify-content: space-between;
+}
+
+.gap-4 {
+  gap: 1rem;
+}
+
+.rounded-2xl {
+  border-radius: 1rem;
+}
+
+.rounded-full {
+  border-radius: 9999px;
+}
+
+.rounded-md {
+  border-radius: 0.375rem;
+}
+
+.border {
+  border-width: 1px;
+}
+
+.border-2 {
+  border-width: 2px;
+}
+
+.border-4 {
+  border-width: 4px;
+}
+
+.border-\[\#2E373B\] {
+  --tw-border-opacity: 1;
+  border-color: rgb(46 55 59 / var(--tw-border-opacity));
+}
+
+.border-transparent {
+  border-color: transparent;
+}
+
+.bg-\[\#1D2125\] {
+  --tw-bg-opacity: 1;
+  background-color: rgb(29 33 37 / var(--tw-bg-opacity));
+}
+
+.bg-\[\#242A2E\] {
+  --tw-bg-opacity: 1;
+  background-color: rgb(36 42 46 / var(--tw-bg-opacity));
+}
+
+.bg-gray-200 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(226 232 240 / var(--tw-bg-opacity));
+}
+
+.bg-gray-800 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(30 41 59 / var(--tw-bg-opacity));
+}
+
+.bg-green-500\/90 {
+  background-color: rgb(34 197 94 / 0.9);
+}
+
+.bg-red-300 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(252 165 165 / var(--tw-bg-opacity));
+}
+
+.bg-sky-500 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(14 165 233 / var(--tw-bg-opacity));
+}
+
+.bg-sky-600 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
+}
+
+.bg-yellow-500\/90 {
+  background-color: rgb(234 179 8 / 0.9);
+}
+
+.bg-opacity-20 {
+  --tw-bg-opacity: 0.2;
+}
+
+.p-0 {
+  padding: 0px;
+}
+
+.p-0\.5 {
+  padding: 0.125rem;
+}
+
+.p-6 {
+  padding: 1.5rem;
+}
+
+.px-2 {
+  padding-left: 0.5rem;
+  padding-right: 0.5rem;
+}
+
+.px-4 {
+  padding-left: 1rem;
+  padding-right: 1rem;
+}
+
+.py-1 {
+  padding-top: 0.25rem;
+  padding-bottom: 0.25rem;
+}
+
+.py-2 {
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+}
+
+.pt-3 {
+  padding-top: 0.75rem;
+}
+
+.text-center {
+  text-align: center;
+}
+
+.text-3xl {
+  font-size: 1.875rem;
+  line-height: 2.25rem;
+}
+
+.text-xl {
+  font-size: 1.25rem;
+  line-height: 1.75rem;
+}
+
+.text-xs {
+  font-size: 0.75rem;
+  line-height: 1rem;
+}
+
+.font-bold {
+  font-weight: 700;
+}
+
+.font-medium {
+  font-weight: 500;
+}
+
+.leading-none {
+  line-height: 1;
+}
+
+.text-gray-500 {
+  --tw-text-opacity: 1;
+  color: rgb(100 116 139 / var(--tw-text-opacity));
+}
+
+.text-neutral-400 {
+  --tw-text-opacity: 1;
+  color: rgb(163 163 163 / var(--tw-text-opacity));
+}
+
+.text-sky-100 {
+  --tw-text-opacity: 1;
+  color: rgb(224 242 254 / var(--tw-text-opacity));
+}
+
+.text-white {
+  --tw-text-opacity: 1;
+  color: rgb(255 255 255 / var(--tw-text-opacity));
+}
+
+.shadow-inner {
+  --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
+  --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
+  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-green-400 {
+  --tw-shadow-color: #4ade80;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-red-200 {
+  --tw-shadow-color: #fecaca;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-sky-400 {
+  --tw-shadow-color: #38bdf8;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-yellow-400 {
+  --tw-shadow-color: #facc15;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.outline-none {
+  outline: 2px solid transparent;
+  outline-offset: 2px;
+}
+
+.\[hostname\:port\] {
+  hostname: port;
+}
+
+.hover\:bg-green-600:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(22 163 74 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-red-400:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(248 113 113 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-sky-600:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-yellow-600:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(202 138 4 / var(--tw-bg-opacity));
+}
+
+.focus\:border-sky-500:focus {
+  --tw-border-opacity: 1;
+  border-color: rgb(14 165 233 / var(--tw-border-opacity));
+}
+
+.focus\:outline:focus {
+  outline-style: solid;
+}
+
+.focus\:outline-2:focus {
+  outline-width: 2px;
+}
+
+.focus\:outline-offset-2:focus {
+  outline-offset: 2px;
+}
+
+.focus\:outline-green-500:focus {
+  outline-color: #22c55e;
+}
+
+.focus\:outline-red-500:focus {
+  outline-color: #ef4444;
+}
+
+.focus\:outline-sky-500:focus {
+  outline-color: #0ea5e9;
+}
+
+.focus\:outline-yellow-600:focus {
+  outline-color: #ca8a04;
+}
+
+@media (min-width: 640px) {
+  .sm\:w-auto {
+    width: auto;
+  }
+
+  .sm\:min-w-\[550px\] {
+    min-width: 550px;
+  }
+}
\ No newline at end of file
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index 19fe8c83e..ef528555f 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -37,10 +37,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="createUser">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index 76e6fc0b8..856f8df45 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -31,10 +31,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="checkGeneral">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index 623e92838..ca34a4a00 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -64,10 +64,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="checkDB">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index cace87f77..9962c25c1 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -12,10 +12,29 @@
         echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="feedDB">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index 195a4ad91..55ea14363 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -63,17 +63,36 @@
         </div>
     </div>
 
-    <div class="flex w-full justify-around mt-4 gap-8 px-8">
-        <button type="submit"
-                class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="checkSMTP">Submit
-        </button>
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
 
-        <a href="?step=7" class="w-full">
+        <a href="?step=next">
             <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
                 Skip For Now
             </button>
         </a>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">
+            Next &#8594;
+        </button>
     </div>
 </form>
 
diff --git a/public/installer/views/installation-complete.php b/public/installer/views/installation-complete.php
index c9e04d23d..027784714 100644
--- a/public/installer/views/installation-complete.php
+++ b/public/installer/views/installation-complete.php
@@ -2,7 +2,7 @@
 <!-- top layout here -->
 
 <?php
-$lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
+$lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
 fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
 fclose($lockfile);
 
diff --git a/public/installer/views/layout-bottom.php b/public/installer/views/layout-bottom.php
index 35bfcba04..944ac0107 100644
--- a/public/installer/views/layout-bottom.php
+++ b/public/installer/views/layout-bottom.php
@@ -3,5 +3,10 @@
 
 <!-- any middle view here -->
 
+
+    <footer class="fixed bottom-0 w-full bg-gray-800 bg-opacity-20 text-center py-2 text-xs">
+        &copy; 2024 CtrlPanel | installer v2.0.0
+    </footer>
+
     </body>
 </html>
diff --git a/public/installer/views/layout-top.php b/public/installer/views/layout-top.php
index 3d2b89382..42003869b 100644
--- a/public/installer/views/layout-top.php
+++ b/public/installer/views/layout-top.php
@@ -42,18 +42,31 @@
 </head>
 
 <body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
-    <?php
-        function cardStart($title, $subtitle = null): string
-        {
-            return "
-            <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
-                <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
-                <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
-                    <h2 class='text-xl text-center mb-2'>$title</h2>"
-                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
-        }
-    ?>
+<?php
+
+
+    function cardStart($title, $subtitle = null): string
+    {
+        // Get total number of steps (you'll need to define this)
+        $totalSteps = $_SESSION['last_installation_step']; // Assuming you have your $viewNames array defined
 
+        // Get current step from session (or default to 1 if not set)
+        $currentStep = $_SESSION['current_installation_step'] ?? 1;
+
+        // Calculate progress percentage
+        $progressValue = round(($currentStep / $totalSteps) * 100);
+
+        return "
+        <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
+            <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
+            <div class='border-2 border-[#2E373B] bg-[#242A2E] rounded-2xl mx-2'>
+                <div class='bg-sky-600 text-xs font-medium text-sky-100 text-center p-0.5 leading-none rounded-full' style='width: {$progressValue}%'>Step {$currentStep}</div>
+            </div>
+            <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
+                <h2 class='text-xl text-center mb-2'>$title</h2>"
+                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
+}
+?>
 <!-- any middle view here -->
 
 <!-- bottom layout here -->
diff --git a/public/installer/views/mandatory-checks.php b/public/installer/views/mandatory-checks.php
index 039f378c4..4713c4581 100644
--- a/public/installer/views/mandatory-checks.php
+++ b/public/installer/views/mandatory-checks.php
@@ -44,11 +44,31 @@
 
 </ul>
 
-<a href="?step=2" class="w-full flex justify-center">
-    <button
-        class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
-        Lets go!
-    </button>
-</a>
+<hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+<div class="w-full flex justify-between items-center mt-4">
+    <?php
+    if ($_SESSION['is_previous_button_available'] == true) {
+        ?>
+        <a href="?step=previous">
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                &#8592; Back
+            </button>
+        </a>
+        <?php
+    } else {
+        ?>
+        <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            &#8592; Back
+        </button>
+        <?php
+    }
+    ?>
+    <a href="?step=next">
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="mandatory">
+            Next &#8594;
+        </button>
+    </a>
+</div>
 
 <!-- bottom layout here -->
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index 83100192f..5d74bd444 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -41,10 +41,29 @@
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="checkPtero">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index 24ad5d3b5..04e4586d3 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -40,10 +40,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="redisSetup">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="redisSetup">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 4d57cfb1b..7806c76b2 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -15,8 +15,7 @@
             <div class="form-group">
                 <div class="flex flex-col mb-3">
                     <label for="timezone">Timezone</label>
-                    <select id="timezone" name="timezone" required
-                            class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <select id="timezone" name="timezone" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         <?php
                         foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
                             if ($timezoneIdentifier === 'UTC') {
@@ -31,12 +30,31 @@ class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="timezoneConfig">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="timezoneConfig">
+            Next &#8594;
         </button>
     </div>
 </form>
 
-<!-- bottom layout here -->
\ No newline at end of file
+<!-- bottom layout here -->

From d874b98d2498c0e3758f0bdba8a7924f8e8086dc Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 14 Jun 2024 00:06:04 +0200
Subject: [PATCH 412/514] docs: updated the .env.exemple

---
 .env.example | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/.env.example b/.env.example
index 46f1a273a..813110b54 100644
--- a/.env.example
+++ b/.env.example
@@ -1,25 +1,40 @@
+# ⚠️ CAUTION: Advanced Configuration ⚠️
+#
+# This file (.env) stores sensitive environment variables.
+# Modifying these values can significantly impact your application's behavior.
+#
+# Proceed with caution:
+#  - Only edit if you have a clear understanding of the specific variable and its purpose.
+#  - Use the control panel or installer for most configuration changes whenever possible.
+#  - Keep a backup of this file before making any modifications.
+#
+# Need Help? Consult the documentation or contact support before making changes.
+
 ### --- App Settings --- ###
 APP_NAME=CtrlPanel.gg
 APP_ENV=production
 APP_KEY=
 APP_DEBUG=false
 APP_URL=http://localhost
-APP_TIMEZONE=UTC # List with timezones https://www.php.net/manual/en/timezones.php
+APP_TIMEZONE=UTC
 ### --- App Settings End --- ###
 
 ### --- Database Settings (required) --- ###
+# SQL
 DB_CONNECTION=mysql
 DB_HOST=127.0.0.1
 DB_PORT=3306
 DB_DATABASE=dashboard
 DB_USERNAME=dashboarduser
 DB_PASSWORD=
-### --- Database Settings End --- ###
 
-### --- Google Recaptcha Settings --- ###
-RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
-RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
-### --- Google Recaptcha Settings End --- ###
+# No-SQL
+MEMCACHED_HOST=127.0.0.1
+
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+### --- Database Settings End --- ###
 
 ### --- Mail Server Settings --- ###
 MAIL_MAILER=smtp
@@ -55,15 +70,10 @@ PUSHER_APP_ID=
 PUSHER_APP_KEY=
 PUSHER_APP_SECRET=
 PUSHER_APP_CLUSTER=mt1
-### --- External Services Credentials End --- ###
-
-### --- Additional Configuration --- ###
-MEMCACHED_HOST=127.0.0.1
-
-REDIS_HOST=127.0.0.1
-REDIS_PASSWORD=null
-REDIS_PORT=6379
 
 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
-### --- Additional Configuration End --- ###
+
+RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
+RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
+### --- External Services Credentials End --- ###

From dbc12c1968aacaf7c7f87a716c414f058620b6d4 Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Fri, 14 Jun 2024 00:28:20 +0200
Subject: [PATCH 413/514] fix: README.md

---
 README.md | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/README.md b/README.md
index a3cc0e35d..291c86cff 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,6 @@
-<<<<<<< mercadopago-implementation
-### Features
-
--   PayPal, Stripe, Mollie and MercadoPago Integration
--   Hourly, Weekely, Monthly, Quarterly and Annual billing Cycles
--   Referral System
--   Partner System
--   Ticket System
--   Upgrade/Downgrade Server Resources
--   Store (credit system with hourly billing and invoices)
--   Email Verification
--   Audit Log
--   Admin Dashboard
--   User/Server Management
--   Customisable server plans
--   Vouchers
--   Alert System
--   Theme Support
--   and so much more!
-=======
 <div align="center">
     <img src="https://ctrlpanel.gg/img/controlpanel.png" width="128" alt="" />
 </div>
->>>>>>> development
 
 # CtrlPanel-gg
 

From d306a6b46913cff7dbdeacd226ea3c31c60913b1 Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Mon, 17 Jun 2024 14:12:31 +0200
Subject: [PATCH 414/514] docs: deleted discord link in the panel to prevent
 lost people from joining because of missconfiguration

---
 database/seeders/Seeds/UsefulLinksSeeder.php        | 7 -------
 themes/default/views/admin/overview/index.blade.php | 4 ----
 2 files changed, 11 deletions(-)

diff --git a/database/seeders/Seeds/UsefulLinksSeeder.php b/database/seeders/Seeds/UsefulLinksSeeder.php
index 03a8ce9dd..0d5f2b188 100644
--- a/database/seeders/Seeds/UsefulLinksSeeder.php
+++ b/database/seeders/Seeds/UsefulLinksSeeder.php
@@ -28,12 +28,5 @@ public function run()
             'description' => 'View your database online using phpMyAdmin',
             'position' => 'dashboard,topbar',
         ]);
-        UsefulLink::create([
-            'icon' => 'fab fa-discord',
-            'title' => 'Discord',
-            'link' => env('DISCORD_INVITE_URL', 'https://discord.gg/4Y6HjD2uyU'),
-            'description' => 'Need a helping hand? Want to chat? Got any questions? Join our discord!',
-            'position' => 'dashboard',
-        ]);
     }
 }
diff --git a/themes/default/views/admin/overview/index.blade.php b/themes/default/views/admin/overview/index.blade.php
index 09f07e93b..ab053f6bf 100644
--- a/themes/default/views/admin/overview/index.blade.php
+++ b/themes/default/views/admin/overview/index.blade.php
@@ -34,10 +34,6 @@
         <div class="container-fluid">
 
             <div class="mb-3 row">
-                <div class="col-md-3">
-                    <a href="https://discord.gg/4Y6HjD2uyU" class="px-3 btn btn-dark btn-block"><i
-                            class="mr-2 fab fa-discord"></i> {{__('Support server')}}</a>
-                </div>
                 <div class="col-md-3">
                     <a href="https://CtrlPanel.gg/docs/intro" class="px-3 btn btn-dark btn-block"><i
                             class="mr-2 fas fa-link"></i> {{__('Documentation')}}</a>

From 3818b4e94608a672732c39f5bb61c29fa0a9eecf Mon Sep 17 00:00:00 2001
From: AGuyNamedJens <jens.wesseling@gmail.com>
Date: Fri, 21 Jun 2024 22:46:38 +0200
Subject: [PATCH 415/514] [Bug] Fixed Discord Login Caveats: .env MUST contain
 DISCORD_CLIENT_ID and DISCORD_CLIENT_SECRET, otherwise insertion will still
 fail (NEEDS TO BE DOCUMENTED AS BREAKING!)

---
 .env.example                                      |  6 ++++++
 app/Http/Controllers/Admin/SettingsController.php | 15 ++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/.env.example b/.env.example
index 46f1a273a..7dbdbd6df 100644
--- a/.env.example
+++ b/.env.example
@@ -16,6 +16,12 @@ DB_USERNAME=dashboarduser
 DB_PASSWORD=
 ### --- Database Settings End --- ###
 
+### --- Discord Settings (required for Discord OAuth) --- ###
+DISCORD_CLIENT_ID=
+DISCORD_CLIENT_SECRET=
+
+### --- Discord Settings End --- ###
+
 ### --- Google Recaptcha Settings --- ###
 RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
 RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 988603220..448a65683 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -9,6 +9,7 @@
 use Illuminate\Contracts\View\View;
 use Illuminate\Http\Response;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\Redirect;
 use Illuminate\Support\Facades\Validator;
 use Qirolab\Theme\Theme;
@@ -99,7 +100,7 @@ public function update(Request $request)
 
         $this->checkPermission("settings." . strtolower($category) . ".write");
 
-        $settings_class = request()->get('settings_class');
+        $settings_class = (string) request()->get('settings_class');
 
         if (method_exists($settings_class, 'getValidations')) {
             $validations = $settings_class::getValidations();
@@ -120,6 +121,18 @@ public function update(Request $request)
             $rp = new \ReflectionProperty($settingsClass, $key);
             $rpType = $rp->getType();
 
+            // Check if the settingsclass is a DiscordSettings class
+            if($settings_class == 'App\Settings\DiscordSettings') {
+                if($key === 'client_id' || $key === 'client_secret') {
+
+                    $env = file_get_contents(base_path('.env'));
+                    $env = preg_replace('/DISCORD_CLIENT_ID=(.*)/', 'DISCORD_CLIENT_ID=' . $request->input('client_id'), $env);
+                    $env = preg_replace('/DISCORD_CLIENT_SECRET=(.*)/', 'DISCORD_CLIENT_SECRET=' . $request->input('client_secret'), $env);
+                    file_put_contents(base_path('.env'), $env);
+
+                    Artisan::call('config:clear');
+                }
+            }
 
             if ($rpType == 'bool') {
                 $settingsClass->$key = $request->has($key);

From 1619d81e7bf9e0b8e571eb3fd75f7c5cd718309a Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 13 Jun 2024 13:12:33 +0200
Subject: [PATCH 416/514] Fix wrong php typehint

---
 app/Settings/TicketSettings.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Settings/TicketSettings.php b/app/Settings/TicketSettings.php
index 89eec7270..4c7ab5a78 100644
--- a/app/Settings/TicketSettings.php
+++ b/app/Settings/TicketSettings.php
@@ -6,7 +6,7 @@
 
 class TicketSettings extends Settings
 {
-    public bool $enabled;
+    public ?bool $enabled;
     public ?string $information;
 
     public static function group(): string

From e52ab1f76b4a194872d33847c01c1cebfe6a11e7 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 13 Jun 2024 13:18:02 +0200
Subject: [PATCH 417/514] Fix trustedproxy deprecated default null value in
 explode function

---
 config/trustedproxy.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/trustedproxy.php b/config/trustedproxy.php
index dc46c31ba..f3b88cd52 100644
--- a/config/trustedproxy.php
+++ b/config/trustedproxy.php
@@ -26,7 +26,7 @@
      * subsequently passed through.
      */
     'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ?
-        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)),
+        env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', '')),
 
     /*
      * Or, to trust all proxies that connect

From 51a2d490553d4632fbdb941f63806994bebf0463 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 29 Jun 2024 11:31:43 +0200
Subject: [PATCH 418/514] Fix Installer migration failing to run because env
 encryption key is not loaded yet

---
 public/install/forms.php |  26 ++-
 public/install/index.php | 340 +++++++++++++++++++++------------------
 2 files changed, 200 insertions(+), 166 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 23f910efc..2fd18fe40 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -59,6 +59,25 @@
     header('LOCATION: index.php?step=3.5');
 }
 
+if (isset($_POST['generateKey'])) {
+    wh_log('Feeding the Database', 'debug');
+
+    try {
+        if (!str_contains(getenv('APP_KEY'), 'base64')) {
+            $logs = run_console('php artisan key:generate --force');
+            wh_log($logs, 'debug');
+
+            wh_log('Creating APP_KEY successful', 'debug');
+            header('LOCATION: index.php?step=3.6');
+        } else {
+            wh_log('Key already exists. Skipping', 'debug');
+        }
+    } catch (Throwable $th) {
+        wh_log('Creating APP_KEY failed', 'error');
+        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+    }
+}
+
 if (isset($_POST['feedDB'])) {
     wh_log('Feeding the Database', 'debug');
     $logs = '';
@@ -66,11 +85,6 @@
     try {
         //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
         //$logs .= run_console('composer install --no-dev --optimize-autoloader');
-        if (!str_contains(getenv('APP_KEY'), 'base64')) {
-            $logs .= run_console('php artisan key:generate --force');
-        } else {
-            $logs .= "Key already exists. Skipping\n";
-        }
         $logs .= run_console('php artisan storage:link');
         $logs .= run_console('php artisan migrate --seed --force');
         $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
@@ -82,7 +96,7 @@
         header('LOCATION: index.php?step=4');
     } catch (Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
-        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        header("LOCATION: index.php?step=3.6&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
     }
 }
 
diff --git a/public/install/index.php b/public/install/index.php
index 535411e45..629665423 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -64,189 +64,209 @@ function cardStart($title, $subtitle = null): string
 
 <?php
 
-// Getting started
-if (!isset($_GET['step']) || $_GET['step'] == 1) {
-    ?>
-    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
-
-    <ul class="list-none mb-2">
-
-        <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
-
-        <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-        </li>
-
-        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-            Missing php-extentions:
-            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-            foreach (checkExtensions() as $ext) {
-                echo $ext . ', ';
-            }
-            echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
-        </li>
-
-        <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Git version:
-            <?php echo getGitVersion(); ?>
-        </li>
-
-        <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Tar version:
-            <?php echo getTarVersion(); ?>
-        </li>
-
-        <li>
-            <p class="text-neutral-400 mb-1">
-                <br>
-                <span style="color: #eab308;">Important:</span>
-                CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
-                Please make sure you have these installed and running before you continue.
-            </p>
-        </li>
-
-    </ul>
-
-    <a href="?step=2" class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
-            Lets go!
-        </button>
-    </a>
+    // Getting started
+    if (!isset($_GET['step']) || $_GET['step'] == 1) {
+        ?>
+        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
+
+        <ul class="list-none mb-2">
+
+            <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+
+            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+            </li>
+
+            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+                Missing php-extentions:
+                <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+                foreach (checkExtensions() as $ext) {
+                    echo $ext . ', ';
+                }
+                echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
+            </li>
+
+            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                Git version:
+                <?php echo getGitVersion(); ?>
+            </li>
+
+            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+                Tar version:
+                <?php echo getTarVersion(); ?>
+            </li>
+
+            <li>
+                <p class="text-neutral-400 mb-1">
+                    <br>
+                    <span style="color: #eab308;">Important:</span>
+                    CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
+                    Please make sure you have these installed and running before you continue.
+                </p>
+            </li>
+
+        </ul>
+
+        <a href="?step=2" class="w-full flex justify-center">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
+                Lets go!
+            </button>
+        </a>
 
-    <?php
-}
+        <?php
+    }
+
+    // Timezone Config
+    if (isset($_GET['step']) && $_GET['step'] == 2) {
+        echo cardStart($title = "Timezone Configuration"); ?>
+
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="timezoneConfig">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-// Timezone Config
-if (isset($_GET['step']) && $_GET['step'] == 2) {
-    echo cardStart($title = "Timezone Configuration"); ?>
-
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="timezoneConfig">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="timezone">Timezone</label>
-                        <select id="timezone" name="timezone" required
-                                class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <?php
-                            foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
-                                if ($timezoneIdentifier === 'UTC') {
-                                    continue;
-                                }
-
-                                echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
-                            } ?>
-                        </select>
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="timezone">Timezone</label>
+                            <select id="timezone" name="timezone" required
+                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                                <?php
+                                foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
+                                    if ($timezoneIdentifier === 'UTC') {
+                                        continue;
+                                    }
+
+                                    echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
+                                } ?>
+                            </select>
+                        </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="timezoneConfig">Submit
-            </button>
-        </div>
-    </form>
-    <?php
-}
+            <div class="w-full flex justify-center">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="timezoneConfig">Submit
+                </button>
+            </div>
+        </form>
+        <?php
+    }
+
+    // DB Config
+    if (isset($_GET['step']) && $_GET['step'] == 3) {
+        echo cardStart($title = "Database Configuration"); ?>
 
-// DB Config
-if (isset($_GET['step']) && $_GET['step'] == 3) {
-    echo cardStart($title = "Database Configuration"); ?>
-
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasedriver">Database Driver</label>
-                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
-                               value="mysql"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
+
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databasedriver">Database Driver</label>
+                            <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
+                                   value="mysql"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasehost">Database Host</label>
-                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
-                               value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databasehost">Database Host</label>
+                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
+                                   value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseport">Database Port</label>
-                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
-                               value="3306"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databaseport">Database Port</label>
+                            <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
+                                   value="3306"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuser">Database User</label>
-                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
-                               value="ctrlpaneluser"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databaseuser">Database User</label>
+                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
+                                   value="ctrlpaneluser"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuserpass">Database User Password</label>
-                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
-                               required
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col mb-3">
+                            <label for="databaseuserpass">Database User Password</label>
+                            <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
+                                   required
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
-                </div>
 
-                <div class="form-group">
-                    <div class="flex flex-col">
-                        <label for="database">Database</label>
-                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <div class="form-group">
+                        <div class="flex flex-col">
+                            <label for="database">Database</label>
+                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
+                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="checkDB">Submit
-            </button>
-        </div>
-    </form>
+            <div class="w-full flex justify-center">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="checkDB">Submit
+                </button>
+            </div>
+        </form>
+
+        <?php
+    }
+
+    // APP_KEY Generation
+    if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
+
+        <?php echo cardStart($title = "Encryption Key Generation", $subtitle = "Lets generate some security keys!"); ?>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="generateKey">
+
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
+            <div class="w-full flex justify-center">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="generateKey">Submit
+                </button>
+            </div>
+        </form>
     <?php
-}
+    }
 
-// DB Migration & APP_KEY Generation
-if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
+    // DB Migration
+    if (isset($_GET['step']) && $_GET['step'] == 3.6) { ?>
 
-    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?>
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+        <?php echo cardStart($title = "Database Migration", $subtitle = "Lets feed your Database! <br> This process might take a while. Please do not refresh or close this page!"); ?>
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
 
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
+            <?php if (isset($_GET['message'])) {
+                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+            } ?>
 
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="feedDB">Submit
-            </button>
-        </div>
-    </form>
+            <div class="w-full flex justify-center">
+                <button
+                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                    name="feedDB">Submit
+                </button>
+            </div>
+        </form>
     <?php
     }
 

From 96b601e68599ae4b295739f3baafb2d3316bd546 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 29 Jun 2024 11:34:03 +0200
Subject: [PATCH 419/514] Update wrong log message

---
 public/install/forms.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 2fd18fe40..5539f022b 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -60,14 +60,14 @@
 }
 
 if (isset($_POST['generateKey'])) {
-    wh_log('Feeding the Database', 'debug');
+    wh_log('Start APP_KEY generation', 'debug');
 
     try {
         if (!str_contains(getenv('APP_KEY'), 'base64')) {
             $logs = run_console('php artisan key:generate --force');
             wh_log($logs, 'debug');
 
-            wh_log('Creating APP_KEY successful', 'debug');
+            wh_log('Created APP_KEY successful', 'debug');
             header('LOCATION: index.php?step=3.6');
         } else {
             wh_log('Key already exists. Skipping', 'debug');

From b3d31244da0e9df4569cd16325f97b2e48d85c26 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 9 Jul 2024 20:16:20 +0200
Subject: [PATCH 420/514] Remove dedicated create APP_KEY form and move logic
 to DB config

---
 public/install/forms.php | 12 +++++-------
 public/install/index.php | 22 +---------------------
 2 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index 5539f022b..a6739343e 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -55,11 +55,6 @@
         setenv($key, $param);
     }
 
-    wh_log('Database connection successful', 'debug');
-    header('LOCATION: index.php?step=3.5');
-}
-
-if (isset($_POST['generateKey'])) {
     wh_log('Start APP_KEY generation', 'debug');
 
     try {
@@ -68,14 +63,17 @@
             wh_log($logs, 'debug');
 
             wh_log('Created APP_KEY successful', 'debug');
-            header('LOCATION: index.php?step=3.6');
         } else {
             wh_log('Key already exists. Skipping', 'debug');
         }
     } catch (Throwable $th) {
         wh_log('Creating APP_KEY failed', 'error');
-        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        header("LOCATION: index.php?step=3&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        exit();
     }
+
+    wh_log('Database connection successful', 'debug');
+    header('LOCATION: index.php?step=3.5');
 }
 
 if (isset($_POST['feedDB'])) {
diff --git a/public/install/index.php b/public/install/index.php
index 629665423..a4d78b0fa 100644
--- a/public/install/index.php
+++ b/public/install/index.php
@@ -230,28 +230,8 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
         <?php
     }
 
-    // APP_KEY Generation
-    if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
-
-        <?php echo cardStart($title = "Encryption Key Generation", $subtitle = "Lets generate some security keys!"); ?>
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="generateKey">
-
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="generateKey">Submit
-                </button>
-            </div>
-        </form>
-    <?php
-    }
-
     // DB Migration
-    if (isset($_GET['step']) && $_GET['step'] == 3.6) { ?>
+    if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
 
         <?php echo cardStart($title = "Database Migration", $subtitle = "Lets feed your Database! <br> This process might take a while. Please do not refresh or close this page!"); ?>
         <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">

From a67e0abf393937d6202eb2b1db376ae78752a9cb Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Tue, 9 Jul 2024 20:21:29 +0200
Subject: [PATCH 421/514] Fix wrong next step number

---
 public/install/forms.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/install/forms.php b/public/install/forms.php
index a6739343e..8e4d5f49d 100644
--- a/public/install/forms.php
+++ b/public/install/forms.php
@@ -94,7 +94,7 @@
         header('LOCATION: index.php?step=4');
     } catch (Throwable $th) {
         wh_log('Feeding the Database failed', 'error');
-        header("LOCATION: index.php?step=3.6&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
     }
 }
 

From d082ca103ec663cfdeef87bc3df8a6f9aec60b05 Mon Sep 17 00:00:00 2001
From: Drylian <109999325+drylian@users.noreply.github.com>
Date: Thu, 18 Jul 2024 20:46:16 -0300
Subject: [PATCH 422/514] add encrypted function

---
 .../PaymentGateways/MercadoPago/MercadoPagoSettings.php    | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php
index f9b2059f7..f543b6f50 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoSettings.php
@@ -15,6 +15,13 @@ public static function group(): string
         return 'mercadopago';
     }
 
+    public static function encrypted(): array
+    {
+        return [
+            'access_token'
+        ];
+    }
+
     public static function getOptionInputData()
     {
         return [

From 9772321a4d426f729cc90b2779ff8b783793339d Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Thu, 13 Jun 2024 13:12:33 +0200
Subject: [PATCH 423/514] Fix wrong php typehint

---
 app/Settings/TicketSettings.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Settings/TicketSettings.php b/app/Settings/TicketSettings.php
index 89eec7270..4c7ab5a78 100644
--- a/app/Settings/TicketSettings.php
+++ b/app/Settings/TicketSettings.php
@@ -6,7 +6,7 @@
 
 class TicketSettings extends Settings
 {
-    public bool $enabled;
+    public ?bool $enabled;
     public ?string $information;
 
     public static function group(): string

From f72ffe451c79cd5ab90439bf8fd689522919e434 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 29 Jun 2024 11:31:43 +0200
Subject: [PATCH 424/514] Fix Installer migration failing to run because env
 encryption key is not loaded yet

---
 public/installer/src/forms/database.php       | 30 ++++++++++++++-----
 public/installer/views/database-migration.php |  4 +--
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index 24d5dc816..5d4917070 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -19,17 +19,38 @@
         $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     } catch (mysqli_sql_exception $e) {
         wh_log($e->getMessage(), 'error');
-        send_error_message($e->getMessage());
+        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
         exit();
     }
 
+
     foreach ($values as $key => $value) {
         $param = $_POST[$value];
+        // if ($key == "DB_PASSWORD") {
+        //    $param = '"' . $_POST[$value] . '"';
+        // }
         setenv($key, $param);
     }
 
+    wh_log('Start APP_KEY generation', 'debug');
+
+    try {
+        if (!str_contains(getenv('APP_KEY'), 'base64')) {
+            $logs = run_console('php artisan key:generate --force');
+            wh_log($logs, 'debug');
+
+            wh_log('Created APP_KEY successful', 'debug');
+        } else {
+            wh_log('Key already exists. Skipping', 'debug');
+        }
+    } catch (Throwable $th) {
+        wh_log('Creating APP_KEY failed', 'error');
+        header("LOCATION: index.php?step=3&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        exit();
+    }
+
     wh_log('Database connection successful', 'debug');
-    next_step();
+    header('LOCATION: index.php?step=3.5');
 }
 
 if (isset($_POST['feedDB'])) {
@@ -37,11 +58,6 @@
     $logs = '';
 
     try {
-        if (!str_contains(getenv('APP_KEY'), 'base64')) {
-            $logs .= run_console('php artisan key:generate --force');
-        } else {
-            $logs .= "Key already exists. Skipping\n";
-        }
         $logs .= run_console('php artisan storage:link');
         $logs .= run_console('php artisan migrate --seed --force');
         $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index 9962c25c1..85f0e6779 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -2,8 +2,8 @@
 <!-- top layout here -->
 
 <?php echo cardStart(
-    $title = "Database Migration and Encryption Key Generation",
-    $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"
+    $title = "Database Migration",
+    $subtitle = "Lets feed your Database! <br> This process might take a while. Please do not refresh or close this page!"
 ); ?>
 
 <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="feedDB">

From 0558118d65458e6616cb52cd15c40196c525f7d2 Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Sun, 21 Jul 2024 20:24:40 +0200
Subject: [PATCH 425/514] fix: conflicts fix

---
 public/installer/src/forms/database.php | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index 5d4917070..f474adfdf 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -19,16 +19,12 @@
         $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     } catch (mysqli_sql_exception $e) {
         wh_log($e->getMessage(), 'error');
-        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
+        send_error_message($e->getMessage());
         exit();
     }
 
-
     foreach ($values as $key => $value) {
         $param = $_POST[$value];
-        // if ($key == "DB_PASSWORD") {
-        //    $param = '"' . $_POST[$value] . '"';
-        // }
         setenv($key, $param);
     }
 
@@ -50,7 +46,7 @@
     }
 
     wh_log('Database connection successful', 'debug');
-    header('LOCATION: index.php?step=3.5');
+    next_step();
 }
 
 if (isset($_POST['feedDB'])) {

From bf1247d507faafd9b88fad362b3060fe75f78579 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 10:17:53 +0200
Subject: [PATCH 426/514] refactor: renamed install into installer and started
 to split the files

---
 app/Http/Middleware/InstallerLock.php         |   2 +-
 public/{install => installer}/dotenv.php      |   0
 public/{install => installer}/forms.php       |   0
 public/{install => installer}/functions.php   |   0
 public/{install => installer}/index.php       | 338 +++++++++---------
 .../phpmailer/Exception.php                   |   0
 .../phpmailer/PHPMailer.php                   |   0
 .../{install => installer}/phpmailer/SMTP.php |   0
 public/installer/src/forms/admin.php          |   0
 public/installer/src/forms/dashboard.php      |   0
 public/installer/src/forms/database.php       |   0
 public/installer/src/forms/pterodactyl.php    |   0
 public/installer/src/forms/redis.php          |   0
 public/installer/src/forms/smtp.php           |   0
 public/installer/src/forms/timezone.php       |   0
 public/installer/src/functions/database.php   |   0
 .../installer/src/functions/environment.php   |   0
 public/installer/src/functions/logging.php    |   0
 public/installer/src/functions/shell.php      |   0
 public/installer/src/functions/utils.php      |   0
 public/{install => installer}/styles.css      |   0
 .../{install => installer}/tailwind.config.js |   0
 .../tailwind_styles.css                       |   0
 public/installer/view/admin-creation.php      |   0
 .../view/dashboard-configuration.php          |   0
 .../installer/view/database-configuration.php |   0
 public/installer/view/database-migration.php  |   0
 public/installer/view/email-configuration.php |   0
 .../installer/view/installation-complete.php  |   0
 public/installer/view/mandatory-checks.php    |   0
 .../view/pterodactyl-configuration.php        |   0
 public/installer/view/redis-configuration.php |   0
 .../installer/view/timezone-configuration.php |   0
 33 files changed, 170 insertions(+), 170 deletions(-)
 rename public/{install => installer}/dotenv.php (100%)
 rename public/{install => installer}/forms.php (100%)
 rename public/{install => installer}/functions.php (100%)
 rename public/{install => installer}/index.php (65%)
 rename public/{install => installer}/phpmailer/Exception.php (100%)
 rename public/{install => installer}/phpmailer/PHPMailer.php (100%)
 rename public/{install => installer}/phpmailer/SMTP.php (100%)
 create mode 100644 public/installer/src/forms/admin.php
 create mode 100644 public/installer/src/forms/dashboard.php
 create mode 100644 public/installer/src/forms/database.php
 create mode 100644 public/installer/src/forms/pterodactyl.php
 create mode 100644 public/installer/src/forms/redis.php
 create mode 100644 public/installer/src/forms/smtp.php
 create mode 100644 public/installer/src/forms/timezone.php
 create mode 100644 public/installer/src/functions/database.php
 create mode 100644 public/installer/src/functions/environment.php
 create mode 100644 public/installer/src/functions/logging.php
 create mode 100644 public/installer/src/functions/shell.php
 create mode 100644 public/installer/src/functions/utils.php
 rename public/{install => installer}/styles.css (100%)
 rename public/{install => installer}/tailwind.config.js (100%)
 rename public/{install => installer}/tailwind_styles.css (100%)
 create mode 100644 public/installer/view/admin-creation.php
 create mode 100644 public/installer/view/dashboard-configuration.php
 create mode 100644 public/installer/view/database-configuration.php
 create mode 100644 public/installer/view/database-migration.php
 create mode 100644 public/installer/view/email-configuration.php
 create mode 100644 public/installer/view/installation-complete.php
 create mode 100644 public/installer/view/mandatory-checks.php
 create mode 100644 public/installer/view/pterodactyl-configuration.php
 create mode 100644 public/installer/view/redis-configuration.php
 create mode 100644 public/installer/view/timezone-configuration.php

diff --git a/app/Http/Middleware/InstallerLock.php b/app/Http/Middleware/InstallerLock.php
index 9390a598c..f6f09e3b5 100644
--- a/app/Http/Middleware/InstallerLock.php
+++ b/app/Http/Middleware/InstallerLock.php
@@ -17,7 +17,7 @@ class InstallerLock
     public function handle(Request $request, Closure $next)
     {
         if (!file_exists(base_path()."/install.lock")){
-            return redirect('/install');
+            return redirect('/installer');
         }
         return $next($request);
     }
diff --git a/public/install/dotenv.php b/public/installer/dotenv.php
similarity index 100%
rename from public/install/dotenv.php
rename to public/installer/dotenv.php
diff --git a/public/install/forms.php b/public/installer/forms.php
similarity index 100%
rename from public/install/forms.php
rename to public/installer/forms.php
diff --git a/public/install/functions.php b/public/installer/functions.php
similarity index 100%
rename from public/install/functions.php
rename to public/installer/functions.php
diff --git a/public/install/index.php b/public/installer/index.php
similarity index 65%
rename from public/install/index.php
rename to public/installer/index.php
index a4d78b0fa..5d73c2e2a 100644
--- a/public/install/index.php
+++ b/public/installer/index.php
@@ -1,7 +1,7 @@
 <?php
 include 'functions.php';
 
-if (file_exists('../../install.lock')) {
+if (file_exists('../../installer.lock')) {
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
@@ -21,7 +21,7 @@ function cardStart($title, $subtitle = null): string
 <head>
     <title>CtrlPanel.gg installer Script</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link href="/install/styles.css" rel="stylesheet">
+    <link href="/installer/styles.css" rel="stylesheet">
     <style>
         body {
             color-scheme: dark;
@@ -64,189 +64,189 @@ function cardStart($title, $subtitle = null): string
 
 <?php
 
-    // Getting started
-    if (!isset($_GET['step']) || $_GET['step'] == 1) {
-        ?>
-        <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
-
-        <ul class="list-none mb-2">
-
-            <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
-
-            <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-            </li>
-
-            <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-                Missing php-extentions:
-                <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-                foreach (checkExtensions() as $ext) {
-                    echo $ext . ', ';
-                }
-                echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
-            </li>
-
-            <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                Git version:
-                <?php echo getGitVersion(); ?>
-            </li>
-
-            <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-                Tar version:
-                <?php echo getTarVersion(); ?>
-            </li>
-
-            <li>
-                <p class="text-neutral-400 mb-1">
-                    <br>
-                    <span style="color: #eab308;">Important:</span>
-                    CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
-                    Please make sure you have these installed and running before you continue.
-                </p>
-            </li>
-
-        </ul>
-
-        <a href="?step=2" class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
-                Lets go!
-            </button>
-        </a>
-
-        <?php
-    }
-
-    // Timezone Config
-    if (isset($_GET['step']) && $_GET['step'] == 2) {
-        echo cardStart($title = "Timezone Configuration"); ?>
+// Getting started
+if (!isset($_GET['step']) || $_GET['step'] == 1) {
+    ?>
+    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
+
+    <ul class="list-none mb-2">
+
+        <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+
+        <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+        </li>
+
+        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+            Missing php-extentions:
+            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+            foreach (checkExtensions() as $ext) {
+                echo $ext . ', ';
+            }
+            echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
+        </li>
+
+        <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            Git version:
+            <?php echo getGitVersion(); ?>
+        </li>
+
+        <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+            Tar version:
+            <?php echo getTarVersion(); ?>
+        </li>
+
+        <li>
+            <p class="text-neutral-400 mb-1">
+                <br>
+                <span style="color: #eab308;">Important:</span>
+                CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
+                Please make sure you have these installed and running before you continue.
+            </p>
+        </li>
+
+    </ul>
+
+    <a href="?step=2" class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
+            Lets go!
+        </button>
+    </a>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="timezoneConfig">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+    <?php
+}
 
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="timezone">Timezone</label>
-                            <select id="timezone" name="timezone" required
-                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <?php
-                                foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
-                                    if ($timezoneIdentifier === 'UTC') {
-                                        continue;
-                                    }
-
-                                    echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
-                                } ?>
-                            </select>
-                        </div>
+// Timezone Config
+if (isset($_GET['step']) && $_GET['step'] == 2) {
+    echo cardStart($title = "Timezone Configuration"); ?>
+
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
+
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="timezone">Timezone</label>
+                        <select id="timezone" name="timezone" required
+                                class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                            <?php
+                            foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
+                                if ($timezoneIdentifier === 'UTC') {
+                                    continue;
+                                }
+
+                                echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
+                            } ?>
+                        </select>
                     </div>
                 </div>
             </div>
+        </div>
 
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="timezoneConfig">Submit
-                </button>
-            </div>
-        </form>
-        <?php
-    }
-
-    // DB Config
-    if (isset($_GET['step']) && $_GET['step'] == 3) {
-        echo cardStart($title = "Database Configuration"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+        <div class="w-full flex justify-center">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="timezoneConfig">Submit
+            </button>
+        </div>
+    </form>
+    <?php
+}
 
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databasedriver">Database Driver</label>
-                            <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
-                                   value="mysql"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+// DB Config
+if (isset($_GET['step']) && $_GET['step'] == 3) {
+    echo cardStart($title = "Database Configuration"); ?>
+
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
+
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databasedriver">Database Driver</label>
+                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
+                               value="mysql"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databasehost">Database Host</label>
-                            <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
-                                   value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databasehost">Database Host</label>
+                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
+                               value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseport">Database Port</label>
-                            <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
-                                   value="3306"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseport">Database Port</label>
+                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
+                               value="3306"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseuser">Database User</label>
-                            <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
-                                   value="ctrlpaneluser"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseuser">Database User</label>
+                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
+                               value="ctrlpaneluser"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="databaseuserpass">Database User Password</label>
-                            <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
-                                   required
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="flex flex-col mb-3">
+                        <label for="databaseuserpass">Database User Password</label>
+                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
+                               required
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
+                </div>
 
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="database">Database</label>
-                            <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
+                <div class="form-group">
+                    <div class="flex flex-col">
+                        <label for="database">Database</label>
+                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
+                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                     </div>
                 </div>
             </div>
+        </div>
 
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="checkDB">Submit
-                </button>
-            </div>
-        </form>
+        <div class="w-full flex justify-center">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="checkDB">Submit
+            </button>
+        </div>
+    </form>
 
-        <?php
-    }
+    <?php
+}
 
-    // DB Migration
-    if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
+// DB Migration & APP_KEY Generation
+if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
 
-        <?php echo cardStart($title = "Database Migration", $subtitle = "Lets feed your Database! <br> This process might take a while. Please do not refresh or close this page!"); ?>
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
+    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?>
+    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
 
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
+        <?php if (isset($_GET['message'])) {
+            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+        } ?>
 
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="feedDB">Submit
-                </button>
-            </div>
-        </form>
+        <div class="w-full flex justify-center">
+            <button
+                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="feedDB">Submit
+            </button>
+        </div>
+    </form>
     <?php
     }
 
@@ -254,7 +254,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 4) {
         echo cardStart($title = "Redis Configuration"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="redisSetup">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -303,7 +303,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 5) {
         echo cardStart($title = "Dashboard Configuration"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
 
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
@@ -346,7 +346,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 6) {
         echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -433,7 +433,7 @@ class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-60
     if (isset($_GET['step']) && $_GET['step'] == 7) {
         echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
             } ?>
@@ -484,7 +484,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
     if (isset($_GET['step']) && $_GET['step'] == 8) {
         echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
 
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
+        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
 
             <?php if (isset($_GET['message'])) {
                 echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
@@ -530,7 +530,7 @@ class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-s
 
     // Install Finished
     if (isset($_GET['step']) && $_GET['step'] == 9) {
-        $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
+        $lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
         fwrite($lockfile, 'locked');
         fclose($lockfile);
 
diff --git a/public/install/phpmailer/Exception.php b/public/installer/phpmailer/Exception.php
similarity index 100%
rename from public/install/phpmailer/Exception.php
rename to public/installer/phpmailer/Exception.php
diff --git a/public/install/phpmailer/PHPMailer.php b/public/installer/phpmailer/PHPMailer.php
similarity index 100%
rename from public/install/phpmailer/PHPMailer.php
rename to public/installer/phpmailer/PHPMailer.php
diff --git a/public/install/phpmailer/SMTP.php b/public/installer/phpmailer/SMTP.php
similarity index 100%
rename from public/install/phpmailer/SMTP.php
rename to public/installer/phpmailer/SMTP.php
diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/dashboard.php b/public/installer/src/forms/dashboard.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/pterodactyl.php b/public/installer/src/forms/pterodactyl.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/smtp.php b/public/installer/src/forms/smtp.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/forms/timezone.php b/public/installer/src/forms/timezone.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/database.php b/public/installer/src/functions/database.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/shell.php b/public/installer/src/functions/shell.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/install/styles.css b/public/installer/styles.css
similarity index 100%
rename from public/install/styles.css
rename to public/installer/styles.css
diff --git a/public/install/tailwind.config.js b/public/installer/tailwind.config.js
similarity index 100%
rename from public/install/tailwind.config.js
rename to public/installer/tailwind.config.js
diff --git a/public/install/tailwind_styles.css b/public/installer/tailwind_styles.css
similarity index 100%
rename from public/install/tailwind_styles.css
rename to public/installer/tailwind_styles.css
diff --git a/public/installer/view/admin-creation.php b/public/installer/view/admin-creation.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/dashboard-configuration.php b/public/installer/view/dashboard-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/database-configuration.php b/public/installer/view/database-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/database-migration.php b/public/installer/view/database-migration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/email-configuration.php b/public/installer/view/email-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/installation-complete.php b/public/installer/view/installation-complete.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/mandatory-checks.php b/public/installer/view/mandatory-checks.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/pterodactyl-configuration.php b/public/installer/view/pterodactyl-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/redis-configuration.php b/public/installer/view/redis-configuration.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/installer/view/timezone-configuration.php b/public/installer/view/timezone-configuration.php
new file mode 100644
index 000000000..e69de29bb

From cf7912dc132bce71a96543d756b212e32a296fa3 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 10:26:48 +0200
Subject: [PATCH 427/514] fix: renamed view to views folder in installer

---
 public/installer/{view => views}/admin-creation.php            | 0
 public/installer/{view => views}/dashboard-configuration.php   | 0
 public/installer/{view => views}/database-configuration.php    | 0
 public/installer/{view => views}/database-migration.php        | 0
 public/installer/{view => views}/email-configuration.php       | 0
 public/installer/{view => views}/installation-complete.php     | 0
 public/installer/{view => views}/mandatory-checks.php          | 0
 public/installer/{view => views}/pterodactyl-configuration.php | 0
 public/installer/{view => views}/redis-configuration.php       | 0
 public/installer/{view => views}/timezone-configuration.php    | 0
 10 files changed, 0 insertions(+), 0 deletions(-)
 rename public/installer/{view => views}/admin-creation.php (100%)
 rename public/installer/{view => views}/dashboard-configuration.php (100%)
 rename public/installer/{view => views}/database-configuration.php (100%)
 rename public/installer/{view => views}/database-migration.php (100%)
 rename public/installer/{view => views}/email-configuration.php (100%)
 rename public/installer/{view => views}/installation-complete.php (100%)
 rename public/installer/{view => views}/mandatory-checks.php (100%)
 rename public/installer/{view => views}/pterodactyl-configuration.php (100%)
 rename public/installer/{view => views}/redis-configuration.php (100%)
 rename public/installer/{view => views}/timezone-configuration.php (100%)

diff --git a/public/installer/view/admin-creation.php b/public/installer/views/admin-creation.php
similarity index 100%
rename from public/installer/view/admin-creation.php
rename to public/installer/views/admin-creation.php
diff --git a/public/installer/view/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
similarity index 100%
rename from public/installer/view/dashboard-configuration.php
rename to public/installer/views/dashboard-configuration.php
diff --git a/public/installer/view/database-configuration.php b/public/installer/views/database-configuration.php
similarity index 100%
rename from public/installer/view/database-configuration.php
rename to public/installer/views/database-configuration.php
diff --git a/public/installer/view/database-migration.php b/public/installer/views/database-migration.php
similarity index 100%
rename from public/installer/view/database-migration.php
rename to public/installer/views/database-migration.php
diff --git a/public/installer/view/email-configuration.php b/public/installer/views/email-configuration.php
similarity index 100%
rename from public/installer/view/email-configuration.php
rename to public/installer/views/email-configuration.php
diff --git a/public/installer/view/installation-complete.php b/public/installer/views/installation-complete.php
similarity index 100%
rename from public/installer/view/installation-complete.php
rename to public/installer/views/installation-complete.php
diff --git a/public/installer/view/mandatory-checks.php b/public/installer/views/mandatory-checks.php
similarity index 100%
rename from public/installer/view/mandatory-checks.php
rename to public/installer/views/mandatory-checks.php
diff --git a/public/installer/view/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
similarity index 100%
rename from public/installer/view/pterodactyl-configuration.php
rename to public/installer/views/pterodactyl-configuration.php
diff --git a/public/installer/view/redis-configuration.php b/public/installer/views/redis-configuration.php
similarity index 100%
rename from public/installer/view/redis-configuration.php
rename to public/installer/views/redis-configuration.php
diff --git a/public/installer/view/timezone-configuration.php b/public/installer/views/timezone-configuration.php
similarity index 100%
rename from public/installer/view/timezone-configuration.php
rename to public/installer/views/timezone-configuration.php

From da59b8fc199ab72f8a02614fa2eb699000eecb09 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 11:16:27 +0200
Subject: [PATCH 428/514] refactor: moved mailer files of installer in src

---
 public/installer/{ => src}/phpmailer/Exception.php | 0
 public/installer/{ => src}/phpmailer/PHPMailer.php | 0
 public/installer/{ => src}/phpmailer/SMTP.php      | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 rename public/installer/{ => src}/phpmailer/Exception.php (100%)
 rename public/installer/{ => src}/phpmailer/PHPMailer.php (100%)
 rename public/installer/{ => src}/phpmailer/SMTP.php (100%)

diff --git a/public/installer/phpmailer/Exception.php b/public/installer/src/phpmailer/Exception.php
similarity index 100%
rename from public/installer/phpmailer/Exception.php
rename to public/installer/src/phpmailer/Exception.php
diff --git a/public/installer/phpmailer/PHPMailer.php b/public/installer/src/phpmailer/PHPMailer.php
similarity index 100%
rename from public/installer/phpmailer/PHPMailer.php
rename to public/installer/src/phpmailer/PHPMailer.php
diff --git a/public/installer/phpmailer/SMTP.php b/public/installer/src/phpmailer/SMTP.php
similarity index 100%
rename from public/installer/phpmailer/SMTP.php
rename to public/installer/src/phpmailer/SMTP.php

From 98a3e388925b82af5e17e11973a91019db20e8c5 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 11:16:53 +0200
Subject: [PATCH 429/514] refactor: refactored views of installer

---
 config/database.php                           |   2 +-
 public/installer/forms.php                    |   8 +-
 public/installer/index.php                    | 588 ++----------------
 public/installer/views/admin-creation.php     |  48 ++
 .../views/dashboard-configuration.php         |  42 ++
 .../views/database-configuration.php          |  75 +++
 public/installer/views/database-migration.php |  23 +
 .../installer/views/email-configuration.php   |  80 +++
 .../installer/views/installation-complete.php |  22 +
 public/installer/views/layout-bottom.php      |   7 +
 public/installer/views/layout-top.php         |  59 ++
 public/installer/views/mandatory-checks.php   |  54 ++
 .../views/pterodactyl-configuration.php       |  52 ++
 .../installer/views/redis-configuration.php   |  51 ++
 .../views/timezone-configuration.php          |  42 ++
 15 files changed, 601 insertions(+), 552 deletions(-)
 create mode 100644 public/installer/views/layout-bottom.php
 create mode 100644 public/installer/views/layout-top.php

diff --git a/config/database.php b/config/database.php
index dc722b5fd..1917bc6a7 100644
--- a/config/database.php
+++ b/config/database.php
@@ -119,7 +119,7 @@
 
     'redis' => [
 
-        'client' => env('REDIS_CLIENT', 'phpredis'),
+        'client' => env('REDIS_CLIENT', 'predis'),
 
         'options' => [
             'cluster' => env('REDIS_CLUSTER', 'redis'),
diff --git a/public/installer/forms.php b/public/installer/forms.php
index 8e4d5f49d..6c8795a13 100644
--- a/public/installer/forms.php
+++ b/public/installer/forms.php
@@ -7,11 +7,9 @@
 use PHPMailer\PHPMailer\PHPMailer;
 use Predis\Client;
 
-require 'phpmailer/Exception.php';
-require 'phpmailer/PHPMailer.php';
-require 'phpmailer/SMTP.php';
-
-include 'functions.php';
+require './src/phpmailer/Exception.php';
+require './src/phpmailer/PHPMailer.php';
+require './src/phpmailer/SMTP.php';
 
 if (isset($_POST['timezoneConfig'])) {
     wh_log('Setting up Timezone', 'debug');
diff --git a/public/installer/index.php b/public/installer/index.php
index 5d73c2e2a..24ee47bbd 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,551 +1,47 @@
 <?php
-include 'functions.php';
 
-if (file_exists('../../installer.lock')) {
+// Include the function files
+require_once './src/functions/environment.php';
+require_once './src/functions/database.php';
+require_once './src/functions/shell.php';
+require_once './src/functions/logging.php';
+require_once './src/functions/utils.php';
+
+// Include the form files
+require_once './src/forms/timezone.php';
+require_once './src/forms/database.php';
+require_once './src/forms/redis.php';
+require_once './src/forms/dashboard.php';
+require_once './src/forms/smtp.php';
+require_once './src/forms/pterodactyl.php';
+require_once './src/forms/admin.php';
+
+require_once './functions.php';
+require_once './forms.php';
+
+if (file_exists('../../install.lock')) {
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
-function cardStart($title, $subtitle = null): string
-{
-    return "
-    <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
-        <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
-        <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
-            <h2 class='text-xl text-center mb-2'>$title</h2>"
-        . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
-}
-
-?>
-
-<html lang="en">
-<head>
-    <title>CtrlPanel.gg installer Script</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link href="/installer/styles.css" rel="stylesheet">
-    <style>
-        body {
-            color-scheme: dark;
-        }
-
-        .check {
-            display: flex;
-            gap: 5px;
-            align-items: center;
-            margin-bottom: 5px;
-        }
-
-        .check::before {
-            width: 20px;
-            height: 20px;
-            display: block;
-        }
-
-        .ok {
-            color: lightgreen;
-        }
-
-        /* Green Checkmark */
-        .ok::before {
-            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightgreen' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
-        }
-
-        .not-ok {
-            color: lightcoral;
-        }
-
-        /* Red Cross */
-        .not-ok::before {
-            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightcoral' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
-        }
-    </style>
-</head>
-
-<body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
-
-<?php
-
-// Getting started
-if (!isset($_GET['step']) || $_GET['step'] == 1) {
-    ?>
-    <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
-
-    <ul class="list-none mb-2">
-
-        <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
-
-        <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
-        </li>
-
-        <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
-            Missing php-extentions:
-            <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-            foreach (checkExtensions() as $ext) {
-                echo $ext . ', ';
-            }
-            echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
-        </li>
-
-        <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Git version:
-            <?php echo getGitVersion(); ?>
-        </li>
-
-        <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
-            Tar version:
-            <?php echo getTarVersion(); ?>
-        </li>
-
-        <li>
-            <p class="text-neutral-400 mb-1">
-                <br>
-                <span style="color: #eab308;">Important:</span>
-                CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
-                Please make sure you have these installed and running before you continue.
-            </p>
-        </li>
-
-    </ul>
-
-    <a href="?step=2" class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
-            Lets go!
-        </button>
-    </a>
-
-    <?php
-}
-
-// Timezone Config
-if (isset($_GET['step']) && $_GET['step'] == 2) {
-    echo cardStart($title = "Timezone Configuration"); ?>
-
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="timezone">Timezone</label>
-                        <select id="timezone" name="timezone" required
-                                class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <?php
-                            foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
-                                if ($timezoneIdentifier === 'UTC') {
-                                    continue;
-                                }
-
-                                echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
-                            } ?>
-                        </select>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="timezoneConfig">Submit
-            </button>
-        </div>
-    </form>
-    <?php
-}
-
-// DB Config
-if (isset($_GET['step']) && $_GET['step'] == 3) {
-    echo cardStart($title = "Database Configuration"); ?>
-
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="row">
-            <div class="col-md-12">
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasedriver">Database Driver</label>
-                        <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
-                               value="mysql"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databasehost">Database Host</label>
-                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
-                               value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseport">Database Port</label>
-                        <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
-                               value="3306"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuser">Database User</label>
-                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
-                               value="ctrlpaneluser"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <div class="flex flex-col mb-3">
-                        <label for="databaseuserpass">Database User Password</label>
-                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
-                               required
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-
-                <div class="form-group">
-                    <div class="flex flex-col">
-                        <label for="database">Database</label>
-                        <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
-                               class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="checkDB">Submit
-            </button>
-        </div>
-    </form>
-
-    <?php
-}
-
-// DB Migration & APP_KEY Generation
-if (isset($_GET['step']) && $_GET['step'] == 3.5) { ?>
-
-    <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?>
-    <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
-
-        <?php if (isset($_GET['message'])) {
-            echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-        } ?>
-
-        <div class="w-full flex justify-center">
-            <button
-                class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="feedDB">Submit
-            </button>
-        </div>
-    </form>
-    <?php
-    }
-
-    // Redis Config
-    if (isset($_GET['step']) && $_GET['step'] == 4) {
-        echo cardStart($title = "Redis Configuration"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="redishost">Redis Host</label>
-                            <input x-model="redishost" id="redishost" name="redishost" type="text" required
-                                   value="<?php echo(determineIfRunningInDocker() ? 'redis' : '127.0.0.1') ?>"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="redisport">Redis Port</label>
-                            <input x-model="redisport" id="redisport" name="redisport" type="number" required
-                                   value="6379"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="redispassword">Redis Password (optionally, only if configured)</label>
-                            <input x-model="redispassword" id="redispassword" name="redispassword" type="text"
-                                   placeholder="usually can be left blank"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="redisSetup">Submit
-                </button>
-            </div>
-        </form>
-
-        <?php
-    }
-
-    // Dashboard Config
-    if (isset($_GET['step']) && $_GET['step'] == 5) {
-        echo cardStart($title = "Dashboard Configuration"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
-
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="database">Dashboard URL</label>
-                            <input id="url" name="url" type="text" required
-                                   value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="name">Dashboard Name</label>
-                            <input id="name" name="name" type="text" required value="CtrlPanel"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                </div>
-            </div>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="checkGeneral">Submit
-                </button>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Email Config
-    if (isset($_GET['step']) && $_GET['step'] == 6) {
-        echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="method">E-Mail Protocol</label>
-                            <select id="method" name="method" required
-                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <option value="smtp" selected>SMTP</option>
-                            </select>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="host">Your Mailer-Host</label>
-                            <input id="host" name="host" type="text" required value="smtp.google.com"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="port">Your Mail Port</label>
-                            <input id="port" name="port" type="number" required value="567"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="user">Your Mail User</label>
-                            <input id="user" name="user" type="text" required value="info@mydomain.com"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="pass">Your Mail-User Password</label>
-                            <input id="pass" name="pass" type="password" required value=""
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="encryption">Your Mail encryption method</label>
-                            <select id="encryption" name="encryption" required
-                                    class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                                <option value="tls" selected>TLS</option>
-                                <option value="ssl">SSL</option>
-                                <option value="null">None</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-
-            <div class="flex w-full justify-around mt-4 gap-8 px-8">
-                <button type="submit"
-                        class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                        name="checkSMTP">Submit
-                </button>
-
-                <a href="?step=7" class="w-full">
-                    <button type="button"
-                            class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
-                        Skip For Now
-                    </button>
-                </a>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Pterodactyl Config
-    if (isset($_GET['step']) && $_GET['step'] == 7) {
-        echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-
-                            <label for="url">Pterodactyl URL</label>
-                            <input id="url" name="url" type="text" required placeholder="https://ptero.example.com"
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col mb-3">
-                            <label for="key">Application API Key</label>
-                            <input id="key" name="key" type="text" required value=""
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br/> The key needs all
-                                        Read & Write permissions! </span>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <div class="flex flex-col">
-                            <label for="clientkey">Admin User Client API Key</label>
-                            <input id="clientkey" name="clientkey" type="text" required value=""
-                                   class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                            <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br/> Your Account
-                                        needs to be an Admin!</span>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="checkPtero">Submit
-                </button>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Admin Creation Form
-    if (isset($_GET['step']) && $_GET['step'] == 8) {
-        echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
-
-        <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
-
-            <?php if (isset($_GET['message'])) {
-                echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
-            } ?>
-
-
-            <div class="form-group">
-                <div class="flex flex-col mb-3">
-                    <label for="pteroID">Pterodactyl User ID </label>
-                    <input id="pteroID" name="pteroID" type="text" required value="1"
-                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
-                </div>
-            </div>
-
-            <div class="form-group">
-                <div class="flex flex-col mb-3">
-                    <label for="pass">Password</label>
-                    <input id="pass" name="pass" type="password" required value="" minlength="8"
-                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                    <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
-                </div>
-            </div>
-            <div class="form-group">
-                <div class="flex flex-col">
-                    <label for="repass">Confirm Password</label>
-                    <input id="repass" name="repass" type="password" required value="" minlength="8"
-                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
-                </div>
-            </div>
-
-            <div class="w-full flex justify-center">
-                <button
-                    class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                    name="createUser">Submit
-                </button>
-            </div>
-        </form>
-
-
-        <?php
-    }
-
-    // Install Finished
-    if (isset($_GET['step']) && $_GET['step'] == 9) {
-        $lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
-        fwrite($lockfile, 'locked');
-        fclose($lockfile);
-
-        echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
-        ?>
-
-        <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
-            <button
-                class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
-                Lets Go!
-            </button>
-        </a>
-
-        <?php
-    }
-    ?>
-</body>
-</html>
+$viewNames = [
+    1 => 'mandatory-checks',
+    2 => 'timezone-configuration',
+    3 => 'database-configuration',
+    4 => 'database-migration',
+    5 => 'redis-configuration',
+    6 => 'dashboard-configuration',
+    7 => 'email-configuration',
+    8 => 'pterodactyl-configuration',
+    9 => 'admin-creation',
+    10 => 'installation-complete',
+];
+
+$step = isset($_GET['step']) ? $_GET['step'] : 1;
+$viewName = $viewNames[$step];  // Get the appropriate view name
+
+// Load the layout and the specific view file
+include './views/layout-top.php';
+include "./views/{$viewName}.php";
+include './views/layout-bottom.php';
+
+?>
\ No newline at end of file
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index e69de29bb..b2eb9fa4f 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -0,0 +1,48 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "First Admin Creation",
+    $subtitle = "Lets create the first admin user!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="form-group">
+        <div class="flex flex-col mb-3">
+            <label for="pteroID">Pterodactyl User ID </label>
+            <input id="pteroID" name="pteroID" type="text" required value="1"
+                class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+            <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
+        </div>
+    </div>
+
+    <div class="form-group">
+        <div class="flex flex-col mb-3">
+            <label for="pass">Password</label>
+            <input id="pass" name="pass" type="password" required value="" minlength="8"
+                class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+            <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="flex flex-col">
+            <label for="repass">Confirm Password</label>
+            <input id="repass" name="repass" type="password" required value="" minlength="8"
+                class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="createUser">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index e69de29bb..642b0ddf5 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -0,0 +1,42 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Dashboard Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="database">Dashboard URL</label>
+                    <input id="url" name="url" type="text" required
+                            value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="name">Dashboard Name</label>
+                    <input id="name" name="name" type="text" required value="CtrlPanel"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="checkGeneral">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index e69de29bb..5aa96dd20 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -0,0 +1,75 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Database Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databasedriver">Database Driver</label>
+                    <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required
+                           value="mysql"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databasehost">Database Host</label>
+                    <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
+                           value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databaseport">Database Port</label>
+                    <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required
+                           value="3306"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databaseuser">Database User</label>
+                    <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required
+                           value="ctrlpaneluser"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="databaseuserpass">Database User Password</label>
+                    <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text"
+                           required
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="database">Database</label>
+                    <input x-model="database" id="database" name="database" type="text" required value="ctrlpanel"
+                           class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="checkDB">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index e69de29bb..cf12ba40c 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -0,0 +1,23 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Database Migration and Encryption Key Generation",
+    $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="feedDB">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index e69de29bb..a7545fdae 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -0,0 +1,80 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "E-Mail Configuration",
+    $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="method">E-Mail Protocol</label>
+                    <select id="method" name="method" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <option value="smtp" selected>SMTP</option>
+                    </select>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="host">Your Mailer-Host</label>
+                    <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="port">Your Mail Port</label>
+                    <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="user">Your Mail User</label>
+                    <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="pass">Your Mail-User Password</label>
+                    <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="encryption">Your Mail encryption method</label>
+                    <select id="encryption" name="encryption" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <option value="tls" selected>TLS</option>
+                        <option value="ssl">SSL</option>
+                        <option value="null">None</option>
+                    </select>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="flex w-full justify-around mt-4 gap-8 px-8">
+        <button type="submit"
+                class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+                name="checkSMTP">Submit
+        </button>
+
+        <a href="?step=7" class="w-full">
+            <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
+                Skip For Now
+            </button>
+        </a>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/installation-complete.php b/public/installer/views/installation-complete.php
index e69de29bb..c9e04d23d 100644
--- a/public/installer/views/installation-complete.php
+++ b/public/installer/views/installation-complete.php
@@ -0,0 +1,22 @@
+
+<!-- top layout here -->
+
+<?php
+$lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
+fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
+fclose($lockfile);
+
+echo cardStart(
+    $title = "Installation Complete!",
+    $subtitle = "You may navigate to your Dashboard now and log in!"
+);
+?>
+
+<a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
+    <button
+        class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
+        Lets Go!
+    </button>
+</a>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/layout-bottom.php b/public/installer/views/layout-bottom.php
new file mode 100644
index 000000000..35bfcba04
--- /dev/null
+++ b/public/installer/views/layout-bottom.php
@@ -0,0 +1,7 @@
+
+<!-- top layout here -->
+
+<!-- any middle view here -->
+
+    </body>
+</html>
diff --git a/public/installer/views/layout-top.php b/public/installer/views/layout-top.php
new file mode 100644
index 000000000..3d2b89382
--- /dev/null
+++ b/public/installer/views/layout-top.php
@@ -0,0 +1,59 @@
+<html lang="en">
+<head>
+    <title>CtrlPanel.gg installer Script</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="/installer/styles.css" rel="stylesheet">
+    <style>
+        body {
+            color-scheme: dark;
+        }
+
+        .check {
+            display: flex;
+            gap: 5px;
+            align-items: center;
+            margin-bottom: 5px;
+        }
+
+        .check::before {
+            width: 20px;
+            height: 20px;
+            display: block;
+        }
+
+        .ok {
+            color: lightgreen;
+        }
+
+        /* Green Checkmark */
+        .ok::before {
+            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightgreen' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
+        }
+
+        .not-ok {
+            color: lightcoral;
+        }
+
+        /* Red Cross */
+        .not-ok::before {
+            content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightcoral' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
+        }
+    </style>
+</head>
+
+<body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
+    <?php
+        function cardStart($title, $subtitle = null): string
+        {
+            return "
+            <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
+                <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
+                <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
+                    <h2 class='text-xl text-center mb-2'>$title</h2>"
+                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
+        }
+    ?>
+
+<!-- any middle view here -->
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/mandatory-checks.php b/public/installer/views/mandatory-checks.php
index e69de29bb..039f378c4 100644
--- a/public/installer/views/mandatory-checks.php
+++ b/public/installer/views/mandatory-checks.php
@@ -0,0 +1,54 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Mandatory Checks before Installation",
+    $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"
+); ?>
+
+<ul class="list-none mb-2">
+
+    <li class="<?php echo checkWriteable() ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
+
+    <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+        php version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)
+    </li>
+
+    <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check">
+        Missing php-extentions:
+        <?php echo count(checkExtensions()) == 0 ? 'none' : '';
+        foreach (checkExtensions() as $ext) {
+            echo $ext . ', ';
+        }
+        echo count(checkExtensions()) === 0 ? '' : '(Proceed anyway)'; ?>
+    </li>
+
+    <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+        Git version:
+        <?php echo getGitVersion(); ?>
+    </li>
+
+    <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check">
+        Tar version:
+        <?php echo getTarVersion(); ?>
+    </li>
+
+    <li>
+        <p class="text-neutral-400 mb-1">
+            <br>
+            <span style="color: #eab308;">Important:</span>
+            CtrlPanel.gg requires a MySQL-Database, Redis-Server, and Pterodactyl-Panel to work.<br>
+            Please make sure you have these installed and running before you continue.
+        </p>
+    </li>
+
+</ul>
+
+<a href="?step=2" class="w-full flex justify-center">
+    <button
+        class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
+        Lets go!
+    </button>
+</a>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index e69de29bb..47ca4acda 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -0,0 +1,52 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Pterodactyl Configuration",
+    $subtitle = "Lets get some info about your Pterodactyl Installation!"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="url">Pterodactyl URL</label>
+                    <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="key">Application API Key</label>
+                    <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">
+                    [Found at: ptero.example.com/admin/api] <br/>
+                    The key needs all Read & Write permissions! </span>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col">
+                    <label for="clientkey">Admin User Client API Key</label>
+                    <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <span class="text-neutral-400">
+                    [Found at: ptero.example.com/account/api] <br/>
+                    Your Account needs to be an Admin!</span>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="checkPtero">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index e69de29bb..76bc67380 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -0,0 +1,51 @@
+
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Redis Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="redishost">Redis Host</label>
+                    <input x-model="redishost" id="redishost" name="redishost" type="text" required
+                            value="<?php echo(determineIfRunningInDocker() ? 'redis' : '127.0.0.1') ?>"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="redisport">Redis Port</label>
+                    <input x-model="redisport" id="redisport" name="redisport" type="number" required
+                            value="6379"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="redispassword">Redis Password (optionally, only if configured)</label>
+                    <input x-model="redispassword" id="redispassword" name="redispassword" type="text"
+                            placeholder="usually can be left blank"
+                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="redisSetup">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index e69de29bb..0d2228773 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -0,0 +1,42 @@
+<!-- top layout here -->
+
+<?php echo cardStart(
+    $title = "Timezone Configuration"
+); ?>
+
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="form-group">
+                <div class="flex flex-col mb-3">
+                    <label for="timezone">Timezone</label>
+                    <select id="timezone" name="timezone" required
+                            class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <?php
+                        foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
+                            if ($timezoneIdentifier === 'UTC') {
+                                continue;
+                            }
+
+                            echo '<option value="' . $timezoneIdentifier . '">' . $timezoneIdentifier . '</option>';
+                        } ?>
+                    </select>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="w-full flex justify-center">
+        <button
+            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
+            name="timezoneConfig">Submit
+        </button>
+    </div>
+</form>
+
+<!-- bottom layout here -->
\ No newline at end of file

From cdb955bb147108d59f104ffc262ca1840bf5b8e5 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 11:17:55 +0200
Subject: [PATCH 430/514] fix: changed database oops reverting back change

---
 config/database.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/database.php b/config/database.php
index 1917bc6a7..dc722b5fd 100644
--- a/config/database.php
+++ b/config/database.php
@@ -119,7 +119,7 @@
 
     'redis' => [
 
-        'client' => env('REDIS_CLIENT', 'predis'),
+        'client' => env('REDIS_CLIENT', 'phpredis'),
 
         'options' => [
             'cluster' => env('REDIS_CLUSTER', 'redis'),

From db52d1e895e02775005c78433b303bea1f81e4f4 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Thu, 13 Jun 2024 15:14:28 +0200
Subject: [PATCH 431/514] refactor: too many things, refactored the form and
 functions and added better step and error handling

---
 public/installer/forms.php                    | 384 ------------------
 public/installer/functions.php                | 280 -------------
 public/installer/index.php                    |  51 ++-
 public/installer/src/forms/admin.php          |  96 +++++
 public/installer/src/forms/dashboard.php      |  29 ++
 public/installer/src/forms/database.php       |  62 +++
 public/installer/src/forms/pterodactyl.php    |  80 ++++
 public/installer/src/forms/redis.php          |  32 ++
 public/installer/src/forms/smtp.php           |  71 ++++
 public/installer/src/forms/timezone.php       |  13 +
 public/installer/src/functions/database.php   |   0
 .../installer/src/functions/environment.php   | 132 ++++++
 public/installer/src/functions/installer.php  |  16 +
 public/installer/src/functions/logging.php    |  45 ++
 public/installer/src/functions/shell.php      |  41 ++
 public/installer/src/functions/utils.php      |  41 ++
 public/installer/views/admin-creation.php     |   6 +-
 .../views/dashboard-configuration.php         |   6 +-
 .../views/database-configuration.php          |   6 +-
 public/installer/views/database-migration.php |   6 +-
 .../installer/views/email-configuration.php   |   6 +-
 .../views/pterodactyl-configuration.php       |   6 +-
 .../installer/views/redis-configuration.php   |   6 +-
 .../views/timezone-configuration.php          |   6 +-
 24 files changed, 721 insertions(+), 700 deletions(-)
 delete mode 100644 public/installer/forms.php
 delete mode 100644 public/installer/functions.php
 delete mode 100644 public/installer/src/functions/database.php
 create mode 100644 public/installer/src/functions/installer.php

diff --git a/public/installer/forms.php b/public/installer/forms.php
deleted file mode 100644
index 6c8795a13..000000000
--- a/public/installer/forms.php
+++ /dev/null
@@ -1,384 +0,0 @@
-<?php
-ini_set('display_errors', 1);
-ini_set('display_startup_errors', 1);
-error_reporting(E_ALL);
-
-use PHPMailer\PHPMailer\Exception;
-use PHPMailer\PHPMailer\PHPMailer;
-use Predis\Client;
-
-require './src/phpmailer/Exception.php';
-require './src/phpmailer/PHPMailer.php';
-require './src/phpmailer/SMTP.php';
-
-if (isset($_POST['timezoneConfig'])) {
-    wh_log('Setting up Timezone', 'debug');
-    $timezone = $_POST['timezone'];
-
-    setenv('APP_TIMEZONE', $timezone);
-
-    wh_log('Timezone set: ' . $timezone, 'debug');
-    header('LOCATION: index.php?step=3');
-}
-
-mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);
-
-if (isset($_POST['checkDB'])) {
-    $values = [
-        //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
-        'DB_HOST' => 'databasehost',
-        'DB_DATABASE' => 'database',
-        'DB_USERNAME' => 'databaseuser',
-        'DB_PASSWORD' => 'databaseuserpass',
-        'DB_PORT' => 'databaseport',
-        'DB_CONNECTION' => 'databasedriver',
-    ];
-
-    wh_log('Trying to connect to the Database', 'debug');
-
-    try {
-        $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
-    } catch (mysqli_sql_exception $e) {
-        wh_log($e->getMessage(), 'error');
-        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
-        exit();
-    }
-
-
-    foreach ($values as $key => $value) {
-        $param = $_POST[$value];
-        // if ($key == "DB_PASSWORD") {
-        //    $param = '"' . $_POST[$value] . '"';
-        // }
-        setenv($key, $param);
-    }
-
-    wh_log('Start APP_KEY generation', 'debug');
-
-    try {
-        if (!str_contains(getenv('APP_KEY'), 'base64')) {
-            $logs = run_console('php artisan key:generate --force');
-            wh_log($logs, 'debug');
-
-            wh_log('Created APP_KEY successful', 'debug');
-        } else {
-            wh_log('Key already exists. Skipping', 'debug');
-        }
-    } catch (Throwable $th) {
-        wh_log('Creating APP_KEY failed', 'error');
-        header("LOCATION: index.php?step=3&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
-        exit();
-    }
-
-    wh_log('Database connection successful', 'debug');
-    header('LOCATION: index.php?step=3.5');
-}
-
-if (isset($_POST['feedDB'])) {
-    wh_log('Feeding the Database', 'debug');
-    $logs = '';
-
-    try {
-        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
-        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
-        $logs .= run_console('php artisan storage:link');
-        $logs .= run_console('php artisan migrate --seed --force');
-        $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
-        $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
-
-        wh_log($logs, 'debug');
-
-        wh_log('Feeding the Database successful', 'debug');
-        header('LOCATION: index.php?step=4');
-    } catch (Throwable $th) {
-        wh_log('Feeding the Database failed', 'error');
-        header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
-    }
-}
-
-if (isset($_POST['redisSetup'])) {
-    wh_log('Setting up Redis', 'debug');
-    $redisHost = $_POST['redishost'];
-    $redisPort = $_POST['redisport'];
-    $redisPassword = $_POST['redispassword'];
-
-    $redisClient = new Client([
-        'host'     => $redisHost,
-        'port'     => $redisPort,
-        'password' => $redisPassword,
-        'timeout'  => 1.0,
-    ]);
-
-    try {
-        $redisClient->ping();
-
-        setenv('MEMCACHED_HOST', $redisHost);
-        setenv('REDIS_HOST', $redisHost);
-        setenv('REDIS_PORT', $redisPort);
-        setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
-
-        wh_log('Redis connection successful. Settings updated.', 'debug');
-        header('LOCATION: index.php?step=5');
-    } catch (Throwable $th) {
-        wh_log('Redis connection failed. Settings updated.', 'debug');
-        header("LOCATION: index.php?step=4&message=Please check your credentials!<br>" . $th->getMessage());
-    }
-}
-
-if (isset($_POST['checkGeneral'])) {
-    wh_log('setting app settings', 'debug');
-    $appname = '"' . $_POST['name'] . '"';
-    $appurl = $_POST['url'];
-
-    $parsedUrl = parse_url($appurl);
-
-    if (!isset($parsedUrl['scheme'])) {
-        header('LOCATION: index.php?step=5&message=Please set an URL Scheme like "https://"!');
-        exit();
-    }
-
-    if (!isset($parsedUrl['host'])) {
-        header('LOCATION: index.php?step=5&message=Please set an valid URL host like "https://ctrlpanel.example.com"!');
-        exit();
-    }
-
-    $appurl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
-
-    setenv('APP_NAME', $appname);
-    setenv('APP_URL', $appurl);
-
-    wh_log('App settings set', 'debug');
-    header('LOCATION: index.php?step=6');
-}
-
-if (isset($_POST['checkSMTP'])) {
-    wh_log('Checking SMTP Settings', 'debug');
-    try {
-        $mail = new PHPMailer(true);
-
-        //Server settings
-        // Send using SMTP
-        $mail->isSMTP();
-        $mail->Host = $_POST['host'];
-        // Enable SMTP authentication
-        $mail->SMTPAuth = true;
-        $mail->Username = $_POST['user'];
-        $mail->Password = $_POST['pass'];
-        $mail->SMTPSecure = $_POST['encryption'];
-        $mail->Port = (int) $_POST['port'];
-
-        // Test E-mail metadata
-        $mail->setFrom($_POST['user'], $_POST['user']);
-        $mail->addAddress($_POST['user'], $_POST['user']);
-
-        // Content
-        // Set email format to HTML
-        $mail->isHTML(true);
-        $mail->Subject = 'It Worked! - Test E-Mail from Ctrlpanel.gg';
-        $mail->Body = 'Your E-Mail Settings are correct!';
-
-        $mail->send();
-    } catch (Exception $e) {
-        wh_log($mail->ErrorInfo, 'error');
-        header('LOCATION: index.php?step=6&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
-        exit();
-    }
-
-    wh_log('SMTP Settings are correct', 'debug');
-    wh_log('Updating Database', 'debug');
-    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
-    if ($db->connect_error) {
-        wh_log($db->connect_error, 'error');
-        header('LOCATION: index.php?step=6&message=Could not connect to the Database: ');
-        exit();
-    }
-    $values = [
-        'mail_mailer' => $_POST['method'],
-        'mail_host' => $_POST['host'],
-        'mail_port' => $_POST['port'],
-        'mail_username' => $_POST['user'],
-        'mail_password' => $_POST['pass'],
-        'mail_encryption' => $_POST['encryption'],
-        'mail_from_address' => $_POST['user'],
-    ];
-
-    foreach ($values as $key => $value) {
-        run_console("php artisan settings:set 'MailSettings' '$key' '$value'");
-    }
-
-    wh_log('Database updated', 'debug');
-    header('LOCATION: index.php?step=7');
-}
-
-if (isset($_POST['checkPtero'])) {
-    wh_log('Checking Pterodactyl Settings', 'debug');
-
-    $url = $_POST['url'];
-    $key = $_POST['key'];
-    $clientkey = $_POST['clientkey'];
-
-    $parsedUrl = parse_url($url);
-
-    if (!isset($parsedUrl['scheme'])) {
-        header('LOCATION: index.php?step=7&message=Please set an URL Scheme like "https://"!');
-        exit();
-    }
-
-    if (!isset($parsedUrl['host'])) {
-        header('LOCATION: index.php?step=7&message=Please set an valid URL host like "https://panel.example.com"!');
-        exit();
-    }
-
-    $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
-
-    $callpteroURL = $url . '/api/client/account';
-    $call = curl_init();
-
-    curl_setopt($call, CURLOPT_URL, $callpteroURL);
-    curl_setopt($call, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($call, CURLOPT_HTTPHEADER, [
-        'Accept: Application/vnd.pterodactyl.v1+json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $clientkey,
-    ]);
-    $callresponse = curl_exec($call);
-    $callresult = json_decode($callresponse, true);
-    curl_close($call);
-
-    $pteroURL = $url . '/api/application/users';
-    $ch = curl_init();
-
-    curl_setopt($ch, CURLOPT_URL, $pteroURL);
-    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: Application/vnd.pterodactyl.v1+json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $key,
-    ]);
-    $response = curl_exec($ch);
-    $result = json_decode($response, true);
-    curl_close($ch);
-
-    if (!is_array($result)) {
-        wh_log('No array in response found', 'error');
-        header('LOCATION: index.php?step=7&message=An unknown Error occured, please try again!');
-    }
-
-    if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
-        wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
-        header('LOCATION: index.php?step=7&message=Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!');
-        exit();
-    }
-
-    if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
-        wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
-        header('LOCATION: index.php?step=7&message=Your ClientAPI Key is wrong or the account is not an admin!');
-        exit();
-    }
-
-    try {
-        run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
-        run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
-        run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
-        wh_log('Database updated', 'debug');
-        header('LOCATION: index.php?step=8');
-    } catch (Throwable $th) {
-        wh_log("Setting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
-        exit();
-    }
-}
-
-if (isset($_POST['createUser'])) {
-    wh_log('Getting Pterodactyl User', 'debug');
-
-    try {
-        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
-    } catch (Throwable $th) {
-        wh_log($th->getMessage(), 'error');
-        header('LOCATION: index.php?step=8&message=Could not connect to the Database');
-        exit();
-    }
-
-    $pteroID = $_POST['pteroID'];
-    $pass = $_POST['pass'];
-    $repass = $_POST['repass'];
-
-    try {
-        $panelUrl = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
-        $adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
-    } catch (Throwable $th) {
-        wh_log("Getting Pterodactyl information failed.", 'error');
-        header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
-        exit();
-    }
-
-    $panelApiUrl = $panelUrl . '/api/application/users/' . $pteroID;
-
-    $ch = curl_init();
-
-    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
-    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: application/json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $adminToken,
-    ]);
-    $response = curl_exec($ch);
-    $result = json_decode($response, true);
-    curl_close($ch);
-
-    if ($pass !== $repass) {
-        header('LOCATION: index.php?step=8&message=The Passwords did not match!');
-        exit();
-    }
-
-    if (array_key_exists('errors', $result)) {
-        header('LOCATION: index.php?step=8&message=Could not find the user with pterodactyl ID ' . $pteroID);
-        exit();
-    }
-
-    $mail = $result['attributes']['email'];
-    $name = $result['attributes']['username'];
-    $pass = password_hash($pass, PASSWORD_DEFAULT);
-
-    $ch = curl_init();
-
-    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
-    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: application/json',
-        'Content-Type: application/json',
-        'Authorization: Bearer ' . $adminToken,
-    ]);
-    curl_setopt($ch, CURLOPT_POSTFIELDS, [
-        'email' => $mail,
-        'username' => $name,
-        'first_name' => $name,
-        'last_name' => $name,
-        'password' => $pass,
-    ]);
-    $response = curl_exec($ch);
-    $result = json_decode($response, true);
-    curl_close($ch);
-
-    $random = generateRandomString();
-
-    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
-    $query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
-    try {
-        $db->query($query1);
-        $db->query($query2);
-
-        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
-        header('LOCATION: index.php?step=9');
-    } catch (Throwable $th) {
-        wh_log($th->getMessage(), 'error');
-        if (str_contains($th->getMessage(), 'Duplicate entry')) {
-            header('LOCATION: index.php?step=8&message=User already exists in CtrlPanel\'s Database.');
-        } else {
-            header('LOCATION: index.php?step=8&message=Something went wrong when communicating with the Database.');
-        }
-        exit();
-    }
-}
diff --git a/public/installer/functions.php b/public/installer/functions.php
deleted file mode 100644
index e450e8cc1..000000000
--- a/public/installer/functions.php
+++ /dev/null
@@ -1,280 +0,0 @@
-<?php
-require '../../vendor/autoload.php';
-require 'dotenv.php';
-
-use DevCoder\DotEnv;
-use Illuminate\Encryption\Encrypter;
-use Illuminate\Support\Str;
-use Monolog\Formatter\LineFormatter;
-use Monolog\Handler\StreamHandler;
-use Monolog\Logger;
-
-if (!file_exists('../../.env')) {
-    echo run_console('cp .env.example .env');
-}
-
-(new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
-
-$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
-
-$requirements = [
-    'minPhp' => '8.1',
-    'maxPhp' => '8.4', // This version is not supported
-    'mysql' => '5.7.22',
-];
-
-/**
- * Check if the minimum PHP version is present
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function checkPhpVersion(): string
-{
-    global $requirements;
-
-    wh_log('php version: ' . phpversion(), 'debug');
-    if (version_compare(phpversion(), $requirements['minPhp'], '>=') && version_compare(phpversion(), $requirements['maxPhp'], '<=')) {
-        return 'OK';
-    }
-
-    return 'not OK';
-}
-
-/**
- * Check if the environment file is writable
- * @return bool Returns true on writable and false on not writable.
- */
-function checkWriteable(): bool
-{
-    return is_writable('../../.env');
-}
-
-/**
- * Check if zip is installed using a shell command
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function getZipVersion(): string
-{
-    wh_log('attempting to get zip version', 'debug');
-    $output = shell_exec('zip  -v') ?? '';
-    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? 0;
-    wh_log('zip version: ' . $versionoutput, 'debug');
-
-    return $versionoutput != 0 ? 'OK' : 'not OK';
-}
-
-/**
- * Check if git is installed using a shell command
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function getGitVersion(): string
-{
-    wh_log('attempting to get git version', 'debug');
-    $output = shell_exec('git  --version') ?? '';
-    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? 0;
-    wh_log('git version: ' . $versionoutput, 'debug');
-
-    return $versionoutput != 0 ? 'OK' : 'not OK';
-}
-
-/**
- * Check if tar is installed using a shell command
- * @return string 'OK' on success and 'not OK' on failure.
- */
-function getTarVersion(): string
-{
-    wh_log('attempting to get tar version', 'debug');
-    $output = shell_exec('tar  --version') ?? '';
-    preg_match('@[0-9]+\.[0-9]+@', $output, $version);
-
-    $versionoutput = $version[0] ?? 0;
-    wh_log('tar version: ' . $versionoutput, 'debug');
-
-    return $versionoutput != 0 ? 'OK' : 'not OK';
-}
-
-/**
- * Check all extensions to see if they have loaded or not
- * @return array Returns an array of extensions that failed to load.
- */
-function checkExtensions(): array
-{
-    global $required_extensions;
-
-    wh_log('checking extensions', 'debug');
-
-    $not_ok = [];
-    $extentions = get_loaded_extensions();
-
-    foreach ($required_extensions as $ext) {
-        if (!preg_grep('/^(?=.*' . $ext . ').*$/', $extentions)) {
-            array_push($not_ok, $ext);
-        }
-    }
-
-    wh_log('loaded extensions:', 'debug', $extentions);
-    wh_log('failed extensions:', 'debug', $not_ok);
-    return $not_ok;
-}
-
-function removeQuotes($string)
-{
-    return str_replace('"', "", $string);
-}
-
-/**
- * Sets the environment variable into the env file
- * @param string $envKey The environment key to set or modify
- * @param string $envValue The environment variable to set
- * @return bool true on success or false on failure.
- */
-function setenv($envKey, $envValue)
-{
-    $envFile = dirname(__FILE__, 3) . '/.env';
-    $str = file_get_contents($envFile);
-
-    $str .= "\n"; // In case the searched variable is in the last line without \n
-    $keyPosition = strpos($str, "{$envKey}=");
-    $endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
-    $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
-    $str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
-    $str = substr($str, 0, -1);
-
-    $fp = fopen($envFile, 'w');
-    fwrite($fp, $str);
-    fclose($fp);
-}
-
-/**
- * Encrypt the given value
- * @param mixed $value The variable to be encrypted
- * @param bool $serialize If the encryption should be serialized
- * @return string Returns the encrypted variable.
- */
-function encryptSettingsValue(mixed $value, $serialize = true): string
-{
-    $appKey = getenv('APP_KEY');
-    $appKey = base64_decode(Str::after($appKey, 'base64:'));
-    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
-    $encryptedKey = $encrypter->encrypt($value, $serialize);
-
-    return $encryptedKey;
-}
-
-/**
- * Decrypt the given value
- * @param mixed $payload The payload to be decrypted
- * @param bool $unserialize If the encryption should be unserialized
- * @return mixed Returns the decrypted variable on success, throws otherwise.
- */
-
-function decryptSettingsValue(mixed $payload, $unserialize = true)
-{
-    $appKey = getenv('APP_KEY');
-    $appKey = base64_decode(Str::after($appKey, 'base64:'));
-    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
-    $decryptedKey = $encrypter->decrypt($payload, $unserialize);
-
-    return $decryptedKey;
-}
-
-/**
- * Run a shell command
- * @param string $command The command string to run
- * @param array|null $descriptors [optional]<p>
- * An indexed array where the key represents the descriptor number and the value represents how PHP will pass that descriptor to the child process. 0 is stdin, 1 is stdout, while 2 is stderr.
- * Default descriptors when null are 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']
- * </p>
- * @param string|null $cwd [optional] <p>
- * The initial working dir for the command. This must be an
- * absolute directory path, or null
- * if you want to use the default value (the working dir of the current
- * PHP process)
- * </p>
- * @param array|null $options [optional] <p>
- * Allows you to specify additional options.
- * @link https://www.php.net/manual/en/function.proc-open.php proc_open
- * </p>
- * @return false|string|null Returns the result from the command.
- */
-function run_console(string $command, array $descriptors = null, string $cwd = null, array $options = null)
-{
-    wh_log('running command: ' . $command, 'debug');
-
-    $path = dirname(__FILE__, 3);
-    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
-    $output = stream_get_contents($pipes[1]);
-    $exit_code = proc_close($handle);
-
-    if ($exit_code > 0) {
-        wh_log('command result: ' . $output, 'error');
-        throw new Exception("There was an error after running command `$command`", $exit_code);
-        return $output;
-    } else {
-        return $output;
-    }
-}
-
-/**
- * Log to the default laravel.log file
- * @param string $message The message to log
- * @param string $level The log level to use (debug, info, warning, error, critical)
- * @param array $context [optional] The context to log extra information
- * @return void
- */
-function wh_log(string $message, string $level = 'info', array $context = []): void
-{
-    $formatter = new LineFormatter(null, null, true, true);
-    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG);
-    $stream->setFormatter($formatter);
-
-    $log = new Logger('CtrlPanel');
-    $log->pushHandler($stream);
-
-    switch (strtolower($level)) {
-        case 'debug': // Only log debug messages if APP_DEBUG is true
-            if (getenv('APP_DEBUG') === false) return;
-            $log->debug($message, $context);
-            break;
-        case 'info':
-            $log->info($message, $context);
-            break;
-        case 'warning':
-            $log->warning($message, $context);
-            break;
-        case 'error':
-            $log->error($message, $context);
-            break;
-        case 'critical':
-            $log->critical($message, $context);
-            break;
-    }
-    // Prevent memory leaks by resetting the logger
-    $log->reset();
-}
-
-/**
- * Generate a random string
- * @param int $length The length of the random string
- * @return string The randomly generated string.
- */
-function generateRandomString(int $length = 8): string
-{
-    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-    $charactersLength = strlen($characters);
-    $randomString = '';
-    for ($i = 0; $i < $length; $i++) {
-        $randomString .= $characters[rand(0, $charactersLength - 1)];
-    }
-
-    return $randomString;
-}
-
-function determineIfRunningInDocker(): bool
-{
-    return file_exists('/.dockerenv');
-}
diff --git a/public/installer/index.php b/public/installer/index.php
index 24ee47bbd..4feed33b6 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,28 +1,43 @@
 <?php
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
+error_reporting(E_ALL);
+
+session_start();
+
+use DevCoder\DotEnv;
+// use Illuminate\Encryption\Encrypter;
+// use Illuminate\Support\Str;
+
+require '../../vendor/autoload.php';
+require 'dotenv.php';
 
 // Include the function files
+require_once './src/functions/installer.php'; // very important
 require_once './src/functions/environment.php';
-require_once './src/functions/database.php';
 require_once './src/functions/shell.php';
 require_once './src/functions/logging.php';
 require_once './src/functions/utils.php';
 
 // Include the form files
-require_once './src/forms/timezone.php';
-require_once './src/forms/database.php';
-require_once './src/forms/redis.php';
-require_once './src/forms/dashboard.php';
-require_once './src/forms/smtp.php';
-require_once './src/forms/pterodactyl.php';
-require_once './src/forms/admin.php';
-
-require_once './functions.php';
-require_once './forms.php';
+include './src/forms/timezone.php';
+include './src/forms/database.php';
+include './src/forms/redis.php';
+include './src/forms/dashboard.php';
+include './src/forms/smtp.php';
+include './src/forms/pterodactyl.php';
+include './src/forms/admin.php';
 
 if (file_exists('../../install.lock')) {
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
+if (!file_exists('../../.env')) {
+    echo run_console('cp .env.example .env');
+}
+
+(new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
+
 $viewNames = [
     1 => 'mandatory-checks',
     2 => 'timezone-configuration',
@@ -36,7 +51,16 @@
     10 => 'installation-complete',
 ];
 
-$step = isset($_GET['step']) ? $_GET['step'] : 1;
+// Prioritize $_GET['step'], then session, then default to 1
+$step = isset($_GET['step'])
+    ? (int)$_GET['step']  // Convert to integer for safety
+    : (isset($_SESSION['installation_step'])
+        ? $_SESSION['installation_step']
+        : 1);
+
+// Update session with the current step
+$_SESSION['installation_step'] = $step;
+
 $viewName = $viewNames[$step];  // Get the appropriate view name
 
 // Load the layout and the specific view file
@@ -44,4 +68,7 @@
 include "./views/{$viewName}.php";
 include './views/layout-bottom.php';
 
+// setting / reseting the error message
+$_SESSION['error-message'] = null;
+
 ?>
\ No newline at end of file
diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
index e69de29bb..9d0df6229 100644
--- a/public/installer/src/forms/admin.php
+++ b/public/installer/src/forms/admin.php
@@ -0,0 +1,96 @@
+<?php
+
+if (isset($_POST['createUser'])) {
+    wh_log('Getting Pterodactyl User', 'debug');
+
+    try {
+        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
+    } catch (Throwable $th) {
+        wh_log($th->getMessage(), 'error');
+        send_error_message("Could not connect to the Database");
+        exit();
+    }
+
+    $pteroID = $_POST['pteroID'];
+    $pass = $_POST['pass'];
+    $repass = $_POST['repass'];
+
+    try {
+        $panelUrl = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
+        $adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
+    } catch (Throwable $th) {
+        wh_log("Getting Pterodactyl information failed.", 'error');
+        send_error_message($th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        exit();
+    }
+
+    $panelApiUrl = $panelUrl . '/api/application/users/' . $pteroID;
+
+    $ch = curl_init();
+
+    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, [
+        'Accept: application/json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $adminToken,
+    ]);
+    $response = curl_exec($ch);
+    $result = json_decode($response, true);
+    curl_close($ch);
+
+    if ($pass !== $repass) {
+        send_error_message("The Passwords did not match!");
+        exit();
+    }
+
+    if (array_key_exists('errors', $result)) {
+        send_error_message("Could not find the user with pterodactyl ID" . $pteroID);
+        exit();
+    }
+
+    $mail = $result['attributes']['email'];
+    $name = $result['attributes']['username'];
+    $pass = password_hash($pass, PASSWORD_DEFAULT);
+
+    $ch = curl_init();
+
+    curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, [
+        'Accept: application/json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $adminToken,
+    ]);
+    curl_setopt($ch, CURLOPT_POSTFIELDS, [
+        'email' => $mail,
+        'username' => $name,
+        'first_name' => $name,
+        'last_name' => $name,
+        'password' => $pass,
+    ]);
+    $response = curl_exec($ch);
+    $result = json_decode($response, true);
+    curl_close($ch);
+
+    $random = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 8); // random referal
+
+    $query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
+    $query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
+    try {
+        $db->query($query1);
+        $db->query($query2);
+
+        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
+        next_step();
+    } catch (Throwable $th) {
+        wh_log($th->getMessage(), 'error');
+        if (str_contains($th->getMessage(), 'Duplicate entry')) {
+            send_error_message("User already exists in CtrlPanel\'s Database");
+        } else {
+            send_error_message("Something went wrong when communicating with the Database.");
+        }
+        exit();
+    }
+}
+?>
diff --git a/public/installer/src/forms/dashboard.php b/public/installer/src/forms/dashboard.php
index e69de29bb..2229d4133 100644
--- a/public/installer/src/forms/dashboard.php
+++ b/public/installer/src/forms/dashboard.php
@@ -0,0 +1,29 @@
+<?php
+
+
+if (isset($_POST['checkGeneral'])) {
+    wh_log('setting app settings', 'debug');
+    $appname = '"' . $_POST['name'] . '"';
+    $appurl = $_POST['url'];
+
+    $parsedUrl = parse_url($appurl);
+
+    if (!isset($parsedUrl['scheme'])) {
+        send_error_message("Please set an URL Scheme like 'https://'!");
+        exit();
+    }
+
+    if (!isset($parsedUrl['host'])) {
+        send_error_message("Please set an valid URL host like 'https://ctrlpanel.example.com'!");
+        exit();
+    }
+
+    $appurl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
+
+    setenv('APP_NAME', $appname);
+    setenv('APP_URL', $appurl);
+
+    wh_log('App settings set', 'debug');
+    next_step();
+}
+?>
\ No newline at end of file
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index e69de29bb..8e0bdb615 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -0,0 +1,62 @@
+<?php
+
+mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);
+
+if (isset($_POST['checkDB'])) {
+    $values = [
+        //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
+        'DB_HOST' => 'databasehost',
+        'DB_DATABASE' => 'database',
+        'DB_USERNAME' => 'databaseuser',
+        'DB_PASSWORD' => 'databaseuserpass',
+        'DB_PORT' => 'databaseport',
+        'DB_CONNECTION' => 'databasedriver',
+    ];
+
+    wh_log('Trying to connect to the Database', 'debug');
+
+    try {
+        $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
+    } catch (mysqli_sql_exception $e) {
+        wh_log($e->getMessage(), 'error');
+        send_error_message($e->getMessage());
+        exit();
+    }
+
+    foreach ($values as $key => $value) {
+        $param = $_POST[$value];
+        setenv($key, $param);
+    }
+
+    wh_log('Database connection successful', 'debug');
+    next_step();
+}
+
+if (isset($_POST['feedDB'])) {
+    wh_log('Feeding the Database', 'debug');
+    $logs = '';
+
+    try {
+        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
+        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
+        if (!str_contains(getenv('APP_KEY'), 'base64')) {
+            $logs .= run_console('php artisan key:generate --force');
+        } else {
+            $logs .= "Key already exists. Skipping\n";
+        }
+        $logs .= run_console('php artisan storage:link');
+        $logs .= run_console('php artisan migrate --seed --force');
+        $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
+        $logs .= run_console('php artisan db:seed --class=PermissionsSeeder --force');
+
+        wh_log($logs, 'debug');
+
+        wh_log('Feeding the Database successful', 'debug');
+        next_step();
+    } catch (Throwable $th) {
+        wh_log('Feeding the Database failed', 'error');
+        send_error_message("Feeding the Database failed");
+    }
+}
+
+?>
diff --git a/public/installer/src/forms/pterodactyl.php b/public/installer/src/forms/pterodactyl.php
index e69de29bb..d4c24dd94 100644
--- a/public/installer/src/forms/pterodactyl.php
+++ b/public/installer/src/forms/pterodactyl.php
@@ -0,0 +1,80 @@
+<?php
+if (isset($_POST['checkPtero'])) {
+    wh_log('Checking Pterodactyl Settings', 'debug');
+
+    $url = $_POST['url'];
+    $key = $_POST['key'];
+    $clientkey = $_POST['clientkey'];
+
+    $parsedUrl = parse_url($url);
+
+    if (!isset($parsedUrl['scheme'])) {
+        send_error_message("Please set an URL Scheme like 'https://'!");
+        exit();
+    }
+
+    if (!isset($parsedUrl['host'])) {
+        send_error_message("Please set an valid URL host like 'https://panel.example.com'!");
+        exit();
+    }
+
+    $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
+
+    $callpteroURL = $url . '/api/client/account';
+    $call = curl_init();
+
+    curl_setopt($call, CURLOPT_URL, $callpteroURL);
+    curl_setopt($call, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($call, CURLOPT_HTTPHEADER, [
+        'Accept: Application/vnd.pterodactyl.v1+json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $clientkey,
+    ]);
+    $callresponse = curl_exec($call);
+    $callresult = json_decode($callresponse, true);
+    curl_close($call);
+
+    $pteroURL = $url . '/api/application/users';
+    $ch = curl_init();
+
+    curl_setopt($ch, CURLOPT_URL, $pteroURL);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, [
+        'Accept: Application/vnd.pterodactyl.v1+json',
+        'Content-Type: application/json',
+        'Authorization: Bearer ' . $key,
+    ]);
+    $response = curl_exec($ch);
+    $result = json_decode($response, true);
+    curl_close($ch);
+
+    if (!is_array($result)) {
+        wh_log('No array in response found', 'error');
+        send_error_message("An unknown Error occured, please try again!");
+    }
+
+    if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
+        wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
+        send_error_message("Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!");
+        exit();
+    }
+
+    if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
+        wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
+        send_error_message("Your ClientAPI Key is wrong or the account is not an admin!");
+        exit();
+    }
+
+    try {
+        run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
+        run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
+        run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
+        wh_log('Database updated', 'debug');
+        next_step();
+    } catch (Throwable $th) {
+        wh_log("Setting Pterodactyl information failed.", 'error');
+        send_error_message($th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
+        exit();
+    }
+}
+?>
\ No newline at end of file
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
index e69de29bb..6837df3ae 100644
--- a/public/installer/src/forms/redis.php
+++ b/public/installer/src/forms/redis.php
@@ -0,0 +1,32 @@
+<?php
+
+
+if (isset($_POST['redisSetup'])) {
+    wh_log('Setting up Redis', 'debug');
+    $redisHost = $_POST['redishost'];
+    $redisPort = $_POST['redisport'];
+    $redisPassword = $_POST['redispassword'];
+
+    $redisClient = new Client([
+        'host'     => $redisHost,
+        'port'     => $redisPort,
+        'password' => $redisPassword,
+        'timeout'  => 1.0,
+    ]);
+
+    try {
+        $redisClient->ping();
+
+        setenv('MEMCACHED_HOST', $redisHost);
+        setenv('REDIS_HOST', $redisHost);
+        setenv('REDIS_PORT', $redisPort);
+        setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));
+
+        wh_log('Redis connection successful. Settings updated.', 'debug');
+        next_step();
+    } catch (Throwable $th) {
+        wh_log('Redis connection failed. Settings updated.', 'debug');
+        send_error_message("Please check your credentials!<br>" . $th->getMessage());
+    }
+}
+?>
diff --git a/public/installer/src/forms/smtp.php b/public/installer/src/forms/smtp.php
index e69de29bb..0ec801da9 100644
--- a/public/installer/src/forms/smtp.php
+++ b/public/installer/src/forms/smtp.php
@@ -0,0 +1,71 @@
+<?php
+
+use PHPMailer\PHPMailer\Exception;
+use PHPMailer\PHPMailer\PHPMailer;
+use Predis\Client;
+
+require './src/phpmailer/Exception.php';
+require './src/phpmailer/PHPMailer.php';
+require './src/phpmailer/SMTP.php';
+
+
+if (isset($_POST['checkSMTP'])) {
+    wh_log('Checking SMTP Settings', 'debug');
+    try {
+        $mail = new PHPMailer(true);
+
+        //Server settings
+        // Send using SMTP
+        $mail->isSMTP();
+        $mail->Host = $_POST['host'];
+        // Enable SMTP authentication
+        $mail->SMTPAuth = true;
+        $mail->Username = $_POST['user'];
+        $mail->Password = $_POST['pass'];
+        $mail->SMTPSecure = $_POST['encryption'];
+        $mail->Port = (int) $_POST['port'];
+
+        // Test E-mail metadata
+        $mail->setFrom($_POST['user'], $_POST['user']);
+        $mail->addAddress($_POST['user'], $_POST['user']);
+
+        // Content
+        // Set email format to HTML
+        $mail->isHTML(true);
+        $mail->Subject = 'It Worked! - Test E-Mail from Ctrlpanel.gg';
+        $mail->Body = 'Your E-Mail Settings are correct!';
+
+        $mail->send();
+    } catch (Exception $e) {
+        wh_log($mail->ErrorInfo, 'error');
+        send_error_message("Something went wrong while sending test E-Mail!<br>" . $mail->ErrorInfo);
+        exit();
+    }
+
+    wh_log('SMTP Settings are correct', 'debug');
+    wh_log('Updating Database', 'debug');
+    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
+    if ($db->connect_error) {
+        wh_log($db->connect_error, 'error');
+        send_error_message("Could not connect to the Database");
+        exit();
+    }
+    $values = [
+        'mail_mailer' => $_POST['method'],
+        'mail_host' => $_POST['host'],
+        'mail_port' => $_POST['port'],
+        'mail_username' => $_POST['user'],
+        'mail_password' => $_POST['pass'],
+        'mail_encryption' => $_POST['encryption'],
+        'mail_from_address' => $_POST['user'],
+    ];
+
+    foreach ($values as $key => $value) {
+        run_console("php artisan settings:set 'MailSettings' '$key' '$value'");
+    }
+
+    wh_log('Database updated', 'debug');
+    next_step();
+}
+
+?>
\ No newline at end of file
diff --git a/public/installer/src/forms/timezone.php b/public/installer/src/forms/timezone.php
index e69de29bb..b3ff5fa2c 100644
--- a/public/installer/src/forms/timezone.php
+++ b/public/installer/src/forms/timezone.php
@@ -0,0 +1,13 @@
+<?php
+
+if (isset($_POST['timezoneConfig'])) {
+    wh_log('Setting up Timezone', 'debug');
+    $timezone = $_POST['timezone'];
+
+    setenv('APP_TIMEZONE', $timezone);
+
+    wh_log('Timezone set: ' . $timezone, 'debug');
+    next_step();
+}
+
+?>
\ No newline at end of file
diff --git a/public/installer/src/functions/database.php b/public/installer/src/functions/database.php
deleted file mode 100644
index e69de29bb..000000000
diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
index e69de29bb..3ae262c39 100644
--- a/public/installer/src/functions/environment.php
+++ b/public/installer/src/functions/environment.php
@@ -0,0 +1,132 @@
+<?php
+
+/**
+* Sets the environment variable into the env file
+ * @param string $envKey The environment key to set or modify
+ * @param string $envValue The environment variable to set
+ * @return bool true on success or false on failure.
+ */
+function setenv($envKey, $envValue)
+{
+    $envFile = dirname(__FILE__, 3) . '/.env';
+    $str = file_get_contents($envFile);
+
+    $str .= "\n"; // In case the searched variable is in the last line without \n
+    $keyPosition = strpos($str, "{$envKey}=");
+    $endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
+    $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
+    $str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
+    $str = substr($str, 0, -1);
+
+    $fp = fopen($envFile, 'w');
+    fwrite($fp, $str);
+    fclose($fp);
+}
+
+
+$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
+
+/**
+ * Check all extensions to see if they have loaded or not
+ * @return array Returns an array of extensions that failed to load.
+ */
+function checkExtensions(): array
+{
+    global $required_extensions;
+
+    wh_log('checking extensions', 'debug');
+
+    $not_ok = [];
+    $extentions = get_loaded_extensions();
+
+    foreach ($required_extensions as $ext) {
+        if (!preg_grep('/^(?=.*' . $ext . ').*$/', $extentions)) {
+            array_push($not_ok, $ext);
+        }
+    }
+
+    wh_log('loaded extensions:', 'debug', $extentions);
+    wh_log('failed extensions:', 'debug', $not_ok);
+    return $not_ok;
+}
+
+$requirements = [
+    'minPhp' => '8.1',
+    'maxPhp' => '8.4', // This version is not supported
+    'mysql' => '5.7.22',
+];
+
+/**
+ * Check if the minimum PHP version is present
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function checkPhpVersion(): string
+{
+    global $requirements;
+
+    wh_log('php version: ' . phpversion(), 'debug');
+    if (version_compare(phpversion(), $requirements['minPhp'], '>=') && version_compare(phpversion(), $requirements['maxPhp'], '<=')) {
+        return 'OK';
+    }
+
+    return 'not OK';
+}
+
+/**
+ * Check if zip is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getZipVersion(): string
+{
+    wh_log('attempting to get zip version', 'debug');
+    $output = shell_exec('zip  -v') ?? '';
+    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
+
+    $versionoutput = $version[0] ?? 0;
+    wh_log('zip version: ' . $versionoutput, 'debug');
+
+    return $versionoutput != 0 ? 'OK' : 'not OK';
+}
+
+/**
+ * Check if git is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getGitVersion(): string
+{
+    wh_log('attempting to get git version', 'debug');
+    $output = shell_exec('git  --version') ?? '';
+    preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
+
+    $versionoutput = $version[0] ?? 0;
+    wh_log('git version: ' . $versionoutput, 'debug');
+
+    return $versionoutput != 0 ? 'OK' : 'not OK';
+}
+
+/**
+ * Check if tar is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getTarVersion(): string
+{
+    wh_log('attempting to get tar version', 'debug');
+    $output = shell_exec('tar  --version') ?? '';
+    preg_match('@[0-9]+\.[0-9]+@', $output, $version);
+
+    $versionoutput = $version[0] ?? 0;
+    wh_log('tar version: ' . $versionoutput, 'debug');
+
+    return $versionoutput != 0 ? 'OK' : 'not OK';
+}
+
+/**
+ * Check if the environment file is writable
+ * @return bool Returns true on writable and false on not writable.
+ */
+function checkWriteable(): bool
+{
+    return is_writable('../../.env');
+}
+
+?>
diff --git a/public/installer/src/functions/installer.php b/public/installer/src/functions/installer.php
new file mode 100644
index 000000000..24cbf5954
--- /dev/null
+++ b/public/installer/src/functions/installer.php
@@ -0,0 +1,16 @@
+<?php
+
+function send_error_message(string $message): void
+{
+    $_SESSION['error-message'] = $message;
+    header("LOCATION: index.php");
+    exit();
+}
+
+function next_step(): void
+{
+    $_SESSION['installation_step']++;
+    header("LOCATION: index.php");
+}
+
+?>
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
index e69de29bb..f8151c4ec 100644
--- a/public/installer/src/functions/logging.php
+++ b/public/installer/src/functions/logging.php
@@ -0,0 +1,45 @@
+<?php
+
+use Monolog\Formatter\LineFormatter;
+use Monolog\Handler\StreamHandler;
+use Monolog\Logger;
+
+/**
+ * Log to the default laravel.log file
+ * @param string $message The message to log
+ * @param string $level The log level to use (debug, info, warning, error, critical)
+ * @param array $context [optional] The context to log extra information
+ * @return void
+ */
+function wh_log(string $message, string $level = 'info', array $context = []): void
+{
+    $formatter = new LineFormatter(null, null, true, true);
+    $stream = new StreamHandler(dirname(__FILE__, 3) . '../../storage/logs/installer.log', Logger::DEBUG);
+    $stream->setFormatter($formatter);
+
+    $log = new Logger('CtrlPanel');
+    $log->pushHandler($stream);
+
+    switch (strtolower($level)) {
+        case 'debug': // Only log debug messages if APP_DEBUG is true
+            if (getenv('APP_DEBUG') === false) return;
+            $log->debug($message, $context);
+            break;
+        case 'info':
+            $log->info($message, $context);
+            break;
+        case 'warning':
+            $log->warning($message, $context);
+            break;
+        case 'error':
+            $log->error($message, $context);
+            break;
+        case 'critical':
+            $log->critical($message, $context);
+            break;
+    }
+    // Prevent memory leaks by resetting the logger
+    $log->reset();
+}
+
+?>
diff --git a/public/installer/src/functions/shell.php b/public/installer/src/functions/shell.php
index e69de29bb..c0ebb8e62 100644
--- a/public/installer/src/functions/shell.php
+++ b/public/installer/src/functions/shell.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * Run a shell command
+ * @param string $command The command string to run
+ * @param array|null $descriptors [optional]<p>
+ * An indexed array where the key represents the descriptor number and the value represents how PHP will pass that descriptor to the child process. 0 is stdin, 1 is stdout, while 2 is stderr.
+ * Default descriptors when null are 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']
+ * </p>
+ * @param string|null $cwd [optional] <p>
+ * The initial working dir for the command. This must be an
+ * absolute directory path, or null
+ * if you want to use the default value (the working dir of the current
+ * PHP process)
+ * </p>
+ * @param array|null $options [optional] <p>
+ * Allows you to specify additional options.
+ * @link https://www.php.net/manual/en/function.proc-open.php proc_open
+ * </p>
+ * @return false|string|null Returns the result from the command.
+ */
+function run_console(string $command, array $descriptors = null, string $cwd = null, array $options = null)
+{
+    wh_log('running command: ' . $command, 'debug');
+
+    $path = dirname(__FILE__, 3);
+    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
+    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
+    $output = stream_get_contents($pipes[1]);
+    $exit_code = proc_close($handle);
+
+    if ($exit_code > 0) {
+        wh_log('command result: ' . $output, 'error');
+        throw new Exception("There was an error after running command `$command`", $exit_code);
+        return $output;
+    } else {
+        return $output;
+    }
+}
+
+?>
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
index e69de29bb..381064027 100644
--- a/public/installer/src/functions/utils.php
+++ b/public/installer/src/functions/utils.php
@@ -0,0 +1,41 @@
+<?php
+
+function determineIfRunningInDocker(): bool
+{
+    return file_exists('/.dockerenv');
+}
+
+/**
+ * Encrypt the given value
+ * @param mixed $value The variable to be encrypted
+ * @param bool $serialize If the encryption should be serialized
+ * @return string Returns the encrypted variable.
+ */
+function encryptSettingsValue(mixed $value, $serialize = true): string
+{
+    $appKey = getenv('APP_KEY');
+    $appKey = base64_decode(Str::after($appKey, 'base64:'));
+    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
+    $encryptedKey = $encrypter->encrypt($value, $serialize);
+
+    return $encryptedKey;
+}
+
+/**
+ * Decrypt the given value
+ * @param mixed $payload The payload to be decrypted
+ * @param bool $unserialize If the encryption should be unserialized
+ * @return mixed Returns the decrypted variable on success, throws otherwise.
+ */
+
+function decryptSettingsValue(mixed $payload, $unserialize = true)
+{
+    $appKey = getenv('APP_KEY');
+    $appKey = base64_decode(Str::after($appKey, 'base64:'));
+    $encrypter = new Encrypter($appKey, 'AES-256-CBC');
+    $decryptedKey = $encrypter->decrypt($payload, $unserialize);
+
+    return $decryptedKey;
+}
+
+?>
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index b2eb9fa4f..19fe8c83e 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -6,10 +6,10 @@
     $subtitle = "Lets create the first admin user!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="createUser">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="createUser">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="form-group">
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index 642b0ddf5..76e6fc0b8 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -5,10 +5,10 @@
     $title = "Dashboard Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkGeneral">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkGeneral">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index 5aa96dd20..623e92838 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -5,10 +5,10 @@
     $title = "Database Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkDB">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkDB">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index cf12ba40c..cace87f77 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -6,10 +6,10 @@
     $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="feedDB">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="feedDB">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="w-full flex justify-center">
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index a7545fdae..195a4ad91 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -6,10 +6,10 @@
     $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkSMTP">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkSMTP">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index 47ca4acda..83100192f 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -6,10 +6,10 @@
     $subtitle = "Lets get some info about your Pterodactyl Installation!"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="checkPtero">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="checkPtero">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index 76bc67380..24ad5d3b5 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -5,10 +5,10 @@
     $title = "Redis Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="redisSetup">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="redisSetup">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 0d2228773..4d57cfb1b 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -4,10 +4,10 @@
     $title = "Timezone Configuration"
 ); ?>
 
-<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/forms.php" name="timezoneConfig">
+<form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="timezoneConfig">
 
-    <?php if (isset($_GET['message'])) {
-        echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
+    <?php if (isset($_SESSION['error-message'])) {
+        echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
     <div class="row">

From 4feec9b7deb8d44af4620efe3fcc0a58ddbbdab0 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 14 Jun 2024 00:00:19 +0200
Subject: [PATCH 432/514] refactor: refactored a lot of thing in the installer
 and added progress bar and next and previous button, and a footer and fixed
 some bugs

---
 public/installer/index.php                    |  71 +-
 public/installer/src/forms/admin.php          |   1 +
 public/installer/src/forms/dashboard.php      |   4 +-
 public/installer/src/forms/database.php       |   2 -
 public/installer/src/forms/redis.php          |   2 +-
 .../installer/src/functions/environment.php   |   5 +-
 public/installer/src/functions/installer.php  |   2 +-
 public/installer/src/functions/logging.php    |   2 +-
 public/installer/src/functions/shell.php      |   2 +-
 public/installer/src/functions/utils.php      |  10 +-
 public/installer/styles.css                   | 968 +++++++++++++++++-
 public/installer/views/admin-creation.php     |  27 +-
 .../views/dashboard-configuration.php         |  27 +-
 .../views/database-configuration.php          |  27 +-
 public/installer/views/database-migration.php |  27 +-
 .../installer/views/email-configuration.php   |  31 +-
 .../installer/views/installation-complete.php |   2 +-
 public/installer/views/layout-bottom.php      |   5 +
 public/installer/views/layout-top.php         |  35 +-
 public/installer/views/mandatory-checks.php   |  32 +-
 .../views/pterodactyl-configuration.php       |  27 +-
 .../installer/views/redis-configuration.php   |  27 +-
 .../views/timezone-configuration.php          |  32 +-
 23 files changed, 1271 insertions(+), 97 deletions(-)

diff --git a/public/installer/index.php b/public/installer/index.php
index 4feed33b6..a51c67455 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,4 +1,5 @@
 <?php
+// repport all error
 ini_set('display_errors', 1);
 ini_set('display_startup_errors', 1);
 error_reporting(E_ALL);
@@ -6,17 +7,16 @@
 session_start();
 
 use DevCoder\DotEnv;
-// use Illuminate\Encryption\Encrypter;
-// use Illuminate\Support\Str;
 
-require '../../vendor/autoload.php';
-require 'dotenv.php';
+// Include systems
+require_once '../../vendor/autoload.php';
+require_once 'dotenv.php';
+require_once './src/functions/installer.php';
 
 // Include the function files
-require_once './src/functions/installer.php'; // very important
+require_once './src/functions/logging.php';
 require_once './src/functions/environment.php';
 require_once './src/functions/shell.php';
-require_once './src/functions/logging.php';
 require_once './src/functions/utils.php';
 
 // Include the form files
@@ -33,35 +33,52 @@
 }
 
 if (!file_exists('../../.env')) {
-    echo run_console('cp .env.example .env');
+    echo run_console('cp ../../.env.example ../../.env');
 }
 
+// load all the .env value in php env
 (new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
 
-$viewNames = [
-    1 => 'mandatory-checks',
-    2 => 'timezone-configuration',
-    3 => 'database-configuration',
-    4 => 'database-migration',
-    5 => 'redis-configuration',
-    6 => 'dashboard-configuration',
-    7 => 'email-configuration',
-    8 => 'pterodactyl-configuration',
-    9 => 'admin-creation',
-    10 => 'installation-complete',
+$stepConfig = [
+    1 => ['view' => 'mandatory-checks', 'is_revertable' => false],
+    2 => ['view' => 'timezone-configuration', 'is_revertable' => true],
+    3 => ['view' => 'database-configuration', 'is_revertable' => true],
+    4 => ['view' => 'database-migration', 'is_revertable' => false],
+    5 => ['view' => 'redis-configuration', 'is_revertable' => true],
+    6 => ['view' => 'dashboard-configuration', 'is_revertable' => true],
+    7 => ['view' => 'email-configuration', 'is_revertable' => true],
+    8 => ['view' => 'pterodactyl-configuration', 'is_revertable' => false],
+    9 => ['view' => 'admin-creation', 'is_revertable' => false],
+    10 => ['view' => 'installation-complete', 'is_revertable' => false],
 ];
 
-// Prioritize $_GET['step'], then session, then default to 1
-$step = isset($_GET['step'])
-    ? (int)$_GET['step']  // Convert to integer for safety
-    : (isset($_SESSION['installation_step'])
-        ? $_SESSION['installation_step']
-        : 1);
+$_SESSION['last_installation_step'] = count($stepConfig);
+
+// Initialize or get the current step:
+if (!isset($_SESSION['current_installation_step'])) {
+    // Session variable is not set, initialize it in the SESSION
+    $_SESSION['current_installation_step'] = 1;
+}
+
+if (isset($_GET['step'])) {
+    $stepValue = $_GET['step'];
+
+    if (is_numeric($stepValue) && $stepValue >= 1 && $stepValue <= $_SESSION['last_installation_step']) {
+        // Step is valid numeric within range:
+        $_SESSION['current_installation_step'] = $stepValue;
+    } elseif (strtolower($stepValue) === 'next' && $_SESSION['current_installation_step'] < $_SESSION['last_installation_step']) {
+        // Move to next step:
+        $_SESSION['current_installation_step']++;
+    } elseif (strtolower($stepValue) === 'previous' && $_SESSION['current_installation_step'] > 1) {
+        // Move to previous step:
+        $_SESSION['current_installation_step']--;
+    }
+}
 
-// Update session with the current step
-$_SESSION['installation_step'] = $step;
+$viewName = $stepConfig[$_SESSION['current_installation_step']]['view'];
 
-$viewName = $viewNames[$step];  // Get the appropriate view name
+// Set previous button availability based on step reversibility
+$_SESSION['is_previous_button_available'] = $_SESSION['current_installation_step'] > 1 && $stepConfig[$_SESSION['current_installation_step'] - 1]['is_revertable'];
 
 // Load the layout and the specific view file
 include './views/layout-top.php';
diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
index 9d0df6229..b909f9451 100644
--- a/public/installer/src/forms/admin.php
+++ b/public/installer/src/forms/admin.php
@@ -93,4 +93,5 @@
         exit();
     }
 }
+
 ?>
diff --git a/public/installer/src/forms/dashboard.php b/public/installer/src/forms/dashboard.php
index 2229d4133..79804edd6 100644
--- a/public/installer/src/forms/dashboard.php
+++ b/public/installer/src/forms/dashboard.php
@@ -1,6 +1,5 @@
 <?php
 
-
 if (isset($_POST['checkGeneral'])) {
     wh_log('setting app settings', 'debug');
     $appname = '"' . $_POST['name'] . '"';
@@ -26,4 +25,5 @@
     wh_log('App settings set', 'debug');
     next_step();
 }
-?>
\ No newline at end of file
+
+?>
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index 8e0bdb615..24d5dc816 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -37,8 +37,6 @@
     $logs = '';
 
     try {
-        //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
-        //$logs .= run_console('composer install --no-dev --optimize-autoloader');
         if (!str_contains(getenv('APP_KEY'), 'base64')) {
             $logs .= run_console('php artisan key:generate --force');
         } else {
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
index 6837df3ae..3e9ece35a 100644
--- a/public/installer/src/forms/redis.php
+++ b/public/installer/src/forms/redis.php
@@ -1,6 +1,5 @@
 <?php
 
-
 if (isset($_POST['redisSetup'])) {
     wh_log('Setting up Redis', 'debug');
     $redisHost = $_POST['redishost'];
@@ -29,4 +28,5 @@
         send_error_message("Please check your credentials!<br>" . $th->getMessage());
     }
 }
+
 ?>
diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
index 3ae262c39..c98223212 100644
--- a/public/installer/src/functions/environment.php
+++ b/public/installer/src/functions/environment.php
@@ -8,7 +8,9 @@
  */
 function setenv($envKey, $envValue)
 {
-    $envFile = dirname(__FILE__, 3) . '/.env';
+    $rootDirectory = dirname(__DIR__, 4);
+    $envFile = $rootDirectory . '/.env';
+
     $str = file_get_contents($envFile);
 
     $str .= "\n"; // In case the searched variable is in the last line without \n
@@ -23,7 +25,6 @@ function setenv($envKey, $envValue)
     fclose($fp);
 }
 
-
 $required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl', 'redis'];
 
 /**
diff --git a/public/installer/src/functions/installer.php b/public/installer/src/functions/installer.php
index 24cbf5954..169931ea4 100644
--- a/public/installer/src/functions/installer.php
+++ b/public/installer/src/functions/installer.php
@@ -9,7 +9,7 @@ function send_error_message(string $message): void
 
 function next_step(): void
 {
-    $_SESSION['installation_step']++;
+    $_SESSION['current_installation_step']++;
     header("LOCATION: index.php");
 }
 
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
index f8151c4ec..3960ca11f 100644
--- a/public/installer/src/functions/logging.php
+++ b/public/installer/src/functions/logging.php
@@ -14,7 +14,7 @@
 function wh_log(string $message, string $level = 'info', array $context = []): void
 {
     $formatter = new LineFormatter(null, null, true, true);
-    $stream = new StreamHandler(dirname(__FILE__, 3) . '../../storage/logs/installer.log', Logger::DEBUG);
+    $stream = new StreamHandler(dirname(__DIR__, 4) . '/storage/logs/installer.log', Logger::DEBUG);
     $stream->setFormatter($formatter);
 
     $log = new Logger('CtrlPanel');
diff --git a/public/installer/src/functions/shell.php b/public/installer/src/functions/shell.php
index c0ebb8e62..7a72fcedf 100644
--- a/public/installer/src/functions/shell.php
+++ b/public/installer/src/functions/shell.php
@@ -23,7 +23,7 @@ function run_console(string $command, array $descriptors = null, string $cwd = n
 {
     wh_log('running command: ' . $command, 'debug');
 
-    $path = dirname(__FILE__, 3);
+    $path = dirname(__DIR__, 4);
     $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
     $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
     $output = stream_get_contents($pipes[1]);
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
index 381064027..8f13bb69a 100644
--- a/public/installer/src/functions/utils.php
+++ b/public/installer/src/functions/utils.php
@@ -1,9 +1,6 @@
 <?php
 
-function determineIfRunningInDocker(): bool
-{
-    return file_exists('/.dockerenv');
-}
+use Illuminate\Encryption\Encrypter;
 
 /**
  * Encrypt the given value
@@ -38,4 +35,9 @@ function decryptSettingsValue(mixed $payload, $unserialize = true)
     return $decryptedKey;
 }
 
+function determineIfRunningInDocker(): bool
+{
+    return file_exists('/.dockerenv');
+}
+
 ?>
diff --git a/public/installer/styles.css b/public/installer/styles.css
index 22f5b596a..b7db03605 100644
--- a/public/installer/styles.css
+++ b/public/installer/styles.css
@@ -1 +1,967 @@
-/*! tailwindcss v3.3.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#94a3b8}input::placeholder,textarea::placeholder{opacity:1;color:#94a3b8}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.absolute{position:absolute}.relative{position:relative}.m-0{margin:0}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.box-border{box-sizing:border-box}.block{display:block}.inline{display:inline}.flex{display:flex}.hidden{display:none}.w-1\/3{width:33.333333%}.w-full{width:100%}.min-w-fit{min-width:-moz-fit-content;min-width:fit-content}.list-none{list-style-type:none}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-around{justify-content:space-around}.gap-4{gap:1rem}.gap-8{gap:2rem}.rounded-2xl{border-radius:1rem}.rounded-md{border-radius:.375rem}.border-2{border-width:2px}.border-4{border-width:4px}.border-\[\#2E373B\]{--tw-border-opacity:1;border-color:rgb(46 55 59/var(--tw-border-opacity))}.border-transparent{border-color:#0000}.bg-\[\#1D2125\]{--tw-bg-opacity:1;background-color:rgb(29 33 37/var(--tw-bg-opacity))}.bg-\[\#242A2E\]{--tw-bg-opacity:1;background-color:rgb(36 42 46/var(--tw-bg-opacity))}.bg-green-500\/90{background-color:#22c55ee6}.bg-sky-500{--tw-bg-opacity:1;background-color:rgb(14 165 233/var(--tw-bg-opacity))}.bg-yellow-500\/90{background-color:#eab308e6}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.pt-3{padding-top:.75rem}.text-center{text-align:center}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-neutral-400{--tw-text-opacity:1;color:rgb(163 163 163/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.shadow-green-400{--tw-shadow-color:#4ade80;--tw-shadow:var(--tw-shadow-colored)}.shadow-sky-400{--tw-shadow-color:#38bdf8;--tw-shadow:var(--tw-shadow-colored)}.shadow-yellow-400{--tw-shadow-color:#facc15;--tw-shadow:var(--tw-shadow-colored)}.outline-none{outline:2px solid #0000;outline-offset:2px}.\[hostname\:port\]{hostname:port}.hover\:bg-green-600:hover{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity))}.hover\:bg-sky-600:hover{--tw-bg-opacity:1;background-color:rgb(2 132 199/var(--tw-bg-opacity))}.hover\:bg-yellow-600:hover{--tw-bg-opacity:1;background-color:rgb(202 138 4/var(--tw-bg-opacity))}.focus\:border-sky-500:focus{--tw-border-opacity:1;border-color:rgb(14 165 233/var(--tw-border-opacity))}.focus\:outline:focus{outline-style:solid}.focus\:outline-2:focus{outline-width:2px}.focus\:outline-offset-2:focus{outline-offset:2px}.focus\:outline-green-500:focus{outline-color:#22c55e}.focus\:outline-sky-500:focus{outline-color:#0ea5e9}.focus\:outline-yellow-600:focus{outline-color:#ca8a04}@media (min-width:640px){.sm\:w-auto{width:auto}.sm\:min-w-\[550px\]{min-width:550px}}
\ No newline at end of file
+/* 
+ * You need to have `tailwindcss` packages installed for these commands to work.
+ * 
+ * Build: `tailwindcss -i tailwind_styles.css -o styles.css -m`
+ * Dev: `tailwindcss -i tailwind_styles.css -o styles.css --watch` 
+ */
+
+/* 
+ ! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com 
+ */
+
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+
+*,
+::before,
+::after {
+  box-sizing: border-box;
+  /* 1 */
+  border-width: 0;
+  /* 2 */
+  border-style: solid;
+  /* 2 */
+  border-color: #e2e8f0;
+  /* 2 */
+}
+
+::before,
+::after {
+  --tw-content: '';
+}
+
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+5. Use the user's configured `sans` font-feature-settings by default.
+6. Use the user's configured `sans` font-variation-settings by default.
+7. Disable tap highlights on iOS
+*/
+
+html,
+:host {
+  line-height: 1.5;
+  /* 1 */
+  -webkit-text-size-adjust: 100%;
+  /* 2 */
+  -moz-tab-size: 4;
+  /* 3 */
+  -o-tab-size: 4;
+     tab-size: 4;
+  /* 3 */
+  font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+  /* 4 */
+  font-feature-settings: normal;
+  /* 5 */
+  font-variation-settings: normal;
+  /* 6 */
+  -webkit-tap-highlight-color: transparent;
+  /* 7 */
+}
+
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+
+body {
+  margin: 0;
+  /* 1 */
+  line-height: inherit;
+  /* 2 */
+}
+
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+
+hr {
+  height: 0;
+  /* 1 */
+  color: inherit;
+  /* 2 */
+  border-top-width: 1px;
+  /* 3 */
+}
+
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr:where([title]) {
+  -webkit-text-decoration: underline dotted;
+          text-decoration: underline dotted;
+}
+
+/*
+Remove the default font size and weight for headings.
+*/
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-size: inherit;
+  font-weight: inherit;
+}
+
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+
+a {
+  color: inherit;
+  text-decoration: inherit;
+}
+
+/*
+Add the correct font weight in Edge and Safari.
+*/
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/*
+1. Use the user's configured `mono` font-family by default.
+2. Use the user's configured `mono` font-feature-settings by default.
+3. Use the user's configured `mono` font-variation-settings by default.
+4. Correct the odd `em` font sizing in all browsers.
+*/
+
+code,
+kbd,
+samp,
+pre {
+  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+  /* 1 */
+  font-feature-settings: normal;
+  /* 2 */
+  font-variation-settings: normal;
+  /* 3 */
+  font-size: 1em;
+  /* 4 */
+}
+
+/*
+Add the correct font size in all browsers.
+*/
+
+small {
+  font-size: 80%;
+}
+
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+
+table {
+  text-indent: 0;
+  /* 1 */
+  border-color: inherit;
+  /* 2 */
+  border-collapse: collapse;
+  /* 3 */
+}
+
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit;
+  /* 1 */
+  font-feature-settings: inherit;
+  /* 1 */
+  font-variation-settings: inherit;
+  /* 1 */
+  font-size: 100%;
+  /* 1 */
+  font-weight: inherit;
+  /* 1 */
+  line-height: inherit;
+  /* 1 */
+  letter-spacing: inherit;
+  /* 1 */
+  color: inherit;
+  /* 1 */
+  margin: 0;
+  /* 2 */
+  padding: 0;
+  /* 3 */
+}
+
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+  text-transform: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+
+button,
+input:where([type='button']),
+input:where([type='reset']),
+input:where([type='submit']) {
+  -webkit-appearance: button;
+  /* 1 */
+  background-color: transparent;
+  /* 2 */
+  background-image: none;
+  /* 2 */
+}
+
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+
+:-moz-focusring {
+  outline: auto;
+}
+
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+
+:-moz-ui-invalid {
+  box-shadow: none;
+}
+
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+  vertical-align: baseline;
+}
+
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type='search'] {
+  -webkit-appearance: textfield;
+  /* 1 */
+  outline-offset: -2px;
+  /* 2 */
+}
+
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button;
+  /* 1 */
+  font: inherit;
+  /* 2 */
+}
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+  display: list-item;
+}
+
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+  margin: 0;
+}
+
+fieldset {
+  margin: 0;
+  padding: 0;
+}
+
+legend {
+  padding: 0;
+}
+
+ol,
+ul,
+menu {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+/*
+Reset default styling for dialogs.
+*/
+
+dialog {
+  padding: 0;
+}
+
+/*
+Prevent resizing textareas horizontally by default.
+*/
+
+textarea {
+  resize: vertical;
+}
+
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+
+input::-moz-placeholder, textarea::-moz-placeholder {
+  opacity: 1;
+  /* 1 */
+  color: #94a3b8;
+  /* 2 */
+}
+
+input::placeholder,
+textarea::placeholder {
+  opacity: 1;
+  /* 1 */
+  color: #94a3b8;
+  /* 2 */
+}
+
+/*
+Set the default cursor for buttons.
+*/
+
+button,
+[role="button"] {
+  cursor: pointer;
+}
+
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+
+:disabled {
+  cursor: default;
+}
+
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+   This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+  display: block;
+  /* 1 */
+  vertical-align: middle;
+  /* 2 */
+}
+
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+
+img,
+video {
+  max-width: 100%;
+  height: auto;
+}
+
+/* Make elements with the HTML hidden attribute stay hidden by default */
+
+[hidden] {
+  display: none;
+}
+
+*, ::before, ::after {
+  --tw-border-spacing-x: 0;
+  --tw-border-spacing-y: 0;
+  --tw-translate-x: 0;
+  --tw-translate-y: 0;
+  --tw-rotate: 0;
+  --tw-skew-x: 0;
+  --tw-skew-y: 0;
+  --tw-scale-x: 1;
+  --tw-scale-y: 1;
+  --tw-pan-x:  ;
+  --tw-pan-y:  ;
+  --tw-pinch-zoom:  ;
+  --tw-scroll-snap-strictness: proximity;
+  --tw-gradient-from-position:  ;
+  --tw-gradient-via-position:  ;
+  --tw-gradient-to-position:  ;
+  --tw-ordinal:  ;
+  --tw-slashed-zero:  ;
+  --tw-numeric-figure:  ;
+  --tw-numeric-spacing:  ;
+  --tw-numeric-fraction:  ;
+  --tw-ring-inset:  ;
+  --tw-ring-offset-width: 0px;
+  --tw-ring-offset-color: #fff;
+  --tw-ring-color: rgb(59 130 246 / 0.5);
+  --tw-ring-offset-shadow: 0 0 #0000;
+  --tw-ring-shadow: 0 0 #0000;
+  --tw-shadow: 0 0 #0000;
+  --tw-shadow-colored: 0 0 #0000;
+  --tw-blur:  ;
+  --tw-brightness:  ;
+  --tw-contrast:  ;
+  --tw-grayscale:  ;
+  --tw-hue-rotate:  ;
+  --tw-invert:  ;
+  --tw-saturate:  ;
+  --tw-sepia:  ;
+  --tw-drop-shadow:  ;
+  --tw-backdrop-blur:  ;
+  --tw-backdrop-brightness:  ;
+  --tw-backdrop-contrast:  ;
+  --tw-backdrop-grayscale:  ;
+  --tw-backdrop-hue-rotate:  ;
+  --tw-backdrop-invert:  ;
+  --tw-backdrop-opacity:  ;
+  --tw-backdrop-saturate:  ;
+  --tw-backdrop-sepia:  ;
+  --tw-contain-size:  ;
+  --tw-contain-layout:  ;
+  --tw-contain-paint:  ;
+  --tw-contain-style:  ;
+}
+
+::backdrop {
+  --tw-border-spacing-x: 0;
+  --tw-border-spacing-y: 0;
+  --tw-translate-x: 0;
+  --tw-translate-y: 0;
+  --tw-rotate: 0;
+  --tw-skew-x: 0;
+  --tw-skew-y: 0;
+  --tw-scale-x: 1;
+  --tw-scale-y: 1;
+  --tw-pan-x:  ;
+  --tw-pan-y:  ;
+  --tw-pinch-zoom:  ;
+  --tw-scroll-snap-strictness: proximity;
+  --tw-gradient-from-position:  ;
+  --tw-gradient-via-position:  ;
+  --tw-gradient-to-position:  ;
+  --tw-ordinal:  ;
+  --tw-slashed-zero:  ;
+  --tw-numeric-figure:  ;
+  --tw-numeric-spacing:  ;
+  --tw-numeric-fraction:  ;
+  --tw-ring-inset:  ;
+  --tw-ring-offset-width: 0px;
+  --tw-ring-offset-color: #fff;
+  --tw-ring-color: rgb(59 130 246 / 0.5);
+  --tw-ring-offset-shadow: 0 0 #0000;
+  --tw-ring-shadow: 0 0 #0000;
+  --tw-shadow: 0 0 #0000;
+  --tw-shadow-colored: 0 0 #0000;
+  --tw-blur:  ;
+  --tw-brightness:  ;
+  --tw-contrast:  ;
+  --tw-grayscale:  ;
+  --tw-hue-rotate:  ;
+  --tw-invert:  ;
+  --tw-saturate:  ;
+  --tw-sepia:  ;
+  --tw-drop-shadow:  ;
+  --tw-backdrop-blur:  ;
+  --tw-backdrop-brightness:  ;
+  --tw-backdrop-contrast:  ;
+  --tw-backdrop-grayscale:  ;
+  --tw-backdrop-hue-rotate:  ;
+  --tw-backdrop-invert:  ;
+  --tw-backdrop-opacity:  ;
+  --tw-backdrop-saturate:  ;
+  --tw-backdrop-sepia:  ;
+  --tw-contain-size:  ;
+  --tw-contain-layout:  ;
+  --tw-contain-paint:  ;
+  --tw-contain-style:  ;
+}
+
+.container {
+  width: 100%;
+}
+
+@media (min-width: 640px) {
+  .container {
+    max-width: 640px;
+  }
+}
+
+@media (min-width: 768px) {
+  .container {
+    max-width: 768px;
+  }
+}
+
+@media (min-width: 1024px) {
+  .container {
+    max-width: 1024px;
+  }
+}
+
+@media (min-width: 1280px) {
+  .container {
+    max-width: 1280px;
+  }
+}
+
+@media (min-width: 1536px) {
+  .container {
+    max-width: 1536px;
+  }
+}
+
+.static {
+  position: static;
+}
+
+.fixed {
+  position: fixed;
+}
+
+.absolute {
+  position: absolute;
+}
+
+.relative {
+  position: relative;
+}
+
+.bottom-0 {
+  bottom: 0px;
+}
+
+.m-0 {
+  margin: 0px;
+}
+
+.mx-2 {
+  margin-left: 0.5rem;
+  margin-right: 0.5rem;
+}
+
+.my-6 {
+  margin-top: 1.5rem;
+  margin-bottom: 1.5rem;
+}
+
+.mb-1 {
+  margin-bottom: 0.25rem;
+}
+
+.mb-2 {
+  margin-bottom: 0.5rem;
+}
+
+.mb-3 {
+  margin-bottom: 0.75rem;
+}
+
+.mt-2 {
+  margin-top: 0.5rem;
+}
+
+.mt-4 {
+  margin-top: 1rem;
+}
+
+.box-border {
+  box-sizing: border-box;
+}
+
+.block {
+  display: block;
+}
+
+.inline {
+  display: inline;
+}
+
+.flex {
+  display: flex;
+}
+
+.hidden {
+  display: none;
+}
+
+.w-full {
+  width: 100%;
+}
+
+.cursor-not-allowed {
+  cursor: not-allowed;
+}
+
+.list-none {
+  list-style-type: none;
+}
+
+.flex-col {
+  flex-direction: column;
+}
+
+.items-center {
+  align-items: center;
+}
+
+.justify-center {
+  justify-content: center;
+}
+
+.justify-between {
+  justify-content: space-between;
+}
+
+.gap-4 {
+  gap: 1rem;
+}
+
+.rounded-2xl {
+  border-radius: 1rem;
+}
+
+.rounded-full {
+  border-radius: 9999px;
+}
+
+.rounded-md {
+  border-radius: 0.375rem;
+}
+
+.border {
+  border-width: 1px;
+}
+
+.border-2 {
+  border-width: 2px;
+}
+
+.border-4 {
+  border-width: 4px;
+}
+
+.border-\[\#2E373B\] {
+  --tw-border-opacity: 1;
+  border-color: rgb(46 55 59 / var(--tw-border-opacity));
+}
+
+.border-transparent {
+  border-color: transparent;
+}
+
+.bg-\[\#1D2125\] {
+  --tw-bg-opacity: 1;
+  background-color: rgb(29 33 37 / var(--tw-bg-opacity));
+}
+
+.bg-\[\#242A2E\] {
+  --tw-bg-opacity: 1;
+  background-color: rgb(36 42 46 / var(--tw-bg-opacity));
+}
+
+.bg-gray-200 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(226 232 240 / var(--tw-bg-opacity));
+}
+
+.bg-gray-800 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(30 41 59 / var(--tw-bg-opacity));
+}
+
+.bg-green-500\/90 {
+  background-color: rgb(34 197 94 / 0.9);
+}
+
+.bg-red-300 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(252 165 165 / var(--tw-bg-opacity));
+}
+
+.bg-sky-500 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(14 165 233 / var(--tw-bg-opacity));
+}
+
+.bg-sky-600 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
+}
+
+.bg-yellow-500\/90 {
+  background-color: rgb(234 179 8 / 0.9);
+}
+
+.bg-opacity-20 {
+  --tw-bg-opacity: 0.2;
+}
+
+.p-0 {
+  padding: 0px;
+}
+
+.p-0\.5 {
+  padding: 0.125rem;
+}
+
+.p-6 {
+  padding: 1.5rem;
+}
+
+.px-2 {
+  padding-left: 0.5rem;
+  padding-right: 0.5rem;
+}
+
+.px-4 {
+  padding-left: 1rem;
+  padding-right: 1rem;
+}
+
+.py-1 {
+  padding-top: 0.25rem;
+  padding-bottom: 0.25rem;
+}
+
+.py-2 {
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+}
+
+.pt-3 {
+  padding-top: 0.75rem;
+}
+
+.text-center {
+  text-align: center;
+}
+
+.text-3xl {
+  font-size: 1.875rem;
+  line-height: 2.25rem;
+}
+
+.text-xl {
+  font-size: 1.25rem;
+  line-height: 1.75rem;
+}
+
+.text-xs {
+  font-size: 0.75rem;
+  line-height: 1rem;
+}
+
+.font-bold {
+  font-weight: 700;
+}
+
+.font-medium {
+  font-weight: 500;
+}
+
+.leading-none {
+  line-height: 1;
+}
+
+.text-gray-500 {
+  --tw-text-opacity: 1;
+  color: rgb(100 116 139 / var(--tw-text-opacity));
+}
+
+.text-neutral-400 {
+  --tw-text-opacity: 1;
+  color: rgb(163 163 163 / var(--tw-text-opacity));
+}
+
+.text-sky-100 {
+  --tw-text-opacity: 1;
+  color: rgb(224 242 254 / var(--tw-text-opacity));
+}
+
+.text-white {
+  --tw-text-opacity: 1;
+  color: rgb(255 255 255 / var(--tw-text-opacity));
+}
+
+.shadow-inner {
+  --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
+  --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
+  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-green-400 {
+  --tw-shadow-color: #4ade80;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-red-200 {
+  --tw-shadow-color: #fecaca;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-sky-400 {
+  --tw-shadow-color: #38bdf8;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-yellow-400 {
+  --tw-shadow-color: #facc15;
+  --tw-shadow: var(--tw-shadow-colored);
+}
+
+.outline-none {
+  outline: 2px solid transparent;
+  outline-offset: 2px;
+}
+
+.\[hostname\:port\] {
+  hostname: port;
+}
+
+.hover\:bg-green-600:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(22 163 74 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-red-400:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(248 113 113 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-sky-600:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-yellow-600:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(202 138 4 / var(--tw-bg-opacity));
+}
+
+.focus\:border-sky-500:focus {
+  --tw-border-opacity: 1;
+  border-color: rgb(14 165 233 / var(--tw-border-opacity));
+}
+
+.focus\:outline:focus {
+  outline-style: solid;
+}
+
+.focus\:outline-2:focus {
+  outline-width: 2px;
+}
+
+.focus\:outline-offset-2:focus {
+  outline-offset: 2px;
+}
+
+.focus\:outline-green-500:focus {
+  outline-color: #22c55e;
+}
+
+.focus\:outline-red-500:focus {
+  outline-color: #ef4444;
+}
+
+.focus\:outline-sky-500:focus {
+  outline-color: #0ea5e9;
+}
+
+.focus\:outline-yellow-600:focus {
+  outline-color: #ca8a04;
+}
+
+@media (min-width: 640px) {
+  .sm\:w-auto {
+    width: auto;
+  }
+
+  .sm\:min-w-\[550px\] {
+    min-width: 550px;
+  }
+}
\ No newline at end of file
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index 19fe8c83e..ef528555f 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -37,10 +37,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="createUser">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index 76e6fc0b8..856f8df45 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -31,10 +31,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="checkGeneral">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index 623e92838..ca34a4a00 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -64,10 +64,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="checkDB">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index cace87f77..9962c25c1 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -12,10 +12,29 @@
         echo "<p class='not-ok check'>" . $_SESSION['error-message'] . '</p>';
     } ?>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="feedDB">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index 195a4ad91..55ea14363 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -63,17 +63,36 @@
         </div>
     </div>
 
-    <div class="flex w-full justify-around mt-4 gap-8 px-8">
-        <button type="submit"
-                class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-                name="checkSMTP">Submit
-        </button>
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
 
-        <a href="?step=7" class="w-full">
+        <a href="?step=next">
             <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">
                 Skip For Now
             </button>
         </a>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">
+            Next &#8594;
+        </button>
     </div>
 </form>
 
diff --git a/public/installer/views/installation-complete.php b/public/installer/views/installation-complete.php
index c9e04d23d..027784714 100644
--- a/public/installer/views/installation-complete.php
+++ b/public/installer/views/installation-complete.php
@@ -2,7 +2,7 @@
 <!-- top layout here -->
 
 <?php
-$lockfile = fopen('../../installer.lock', 'w') or exit('Unable to open file!');
+$lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
 fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
 fclose($lockfile);
 
diff --git a/public/installer/views/layout-bottom.php b/public/installer/views/layout-bottom.php
index 35bfcba04..944ac0107 100644
--- a/public/installer/views/layout-bottom.php
+++ b/public/installer/views/layout-bottom.php
@@ -3,5 +3,10 @@
 
 <!-- any middle view here -->
 
+
+    <footer class="fixed bottom-0 w-full bg-gray-800 bg-opacity-20 text-center py-2 text-xs">
+        &copy; 2024 CtrlPanel | installer v2.0.0
+    </footer>
+
     </body>
 </html>
diff --git a/public/installer/views/layout-top.php b/public/installer/views/layout-top.php
index 3d2b89382..42003869b 100644
--- a/public/installer/views/layout-top.php
+++ b/public/installer/views/layout-top.php
@@ -42,18 +42,31 @@
 </head>
 
 <body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
-    <?php
-        function cardStart($title, $subtitle = null): string
-        {
-            return "
-            <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
-                <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
-                <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
-                    <h2 class='text-xl text-center mb-2'>$title</h2>"
-                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
-        }
-    ?>
+<?php
+
+
+    function cardStart($title, $subtitle = null): string
+    {
+        // Get total number of steps (you'll need to define this)
+        $totalSteps = $_SESSION['last_installation_step']; // Assuming you have your $viewNames array defined
 
+        // Get current step from session (or default to 1 if not set)
+        $currentStep = $_SESSION['current_installation_step'] ?? 1;
+
+        // Calculate progress percentage
+        $progressValue = round(($currentStep / $totalSteps) * 100);
+
+        return "
+        <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
+            <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
+            <div class='border-2 border-[#2E373B] bg-[#242A2E] rounded-2xl mx-2'>
+                <div class='bg-sky-600 text-xs font-medium text-sky-100 text-center p-0.5 leading-none rounded-full' style='width: {$progressValue}%'>Step {$currentStep}</div>
+            </div>
+            <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
+                <h2 class='text-xl text-center mb-2'>$title</h2>"
+                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
+}
+?>
 <!-- any middle view here -->
 
 <!-- bottom layout here -->
diff --git a/public/installer/views/mandatory-checks.php b/public/installer/views/mandatory-checks.php
index 039f378c4..4713c4581 100644
--- a/public/installer/views/mandatory-checks.php
+++ b/public/installer/views/mandatory-checks.php
@@ -44,11 +44,31 @@
 
 </ul>
 
-<a href="?step=2" class="w-full flex justify-center">
-    <button
-        class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
-        Lets go!
-    </button>
-</a>
+<hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+<div class="w-full flex justify-between items-center mt-4">
+    <?php
+    if ($_SESSION['is_previous_button_available'] == true) {
+        ?>
+        <a href="?step=previous">
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                &#8592; Back
+            </button>
+        </a>
+        <?php
+    } else {
+        ?>
+        <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            &#8592; Back
+        </button>
+        <?php
+    }
+    ?>
+    <a href="?step=next">
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="mandatory">
+            Next &#8594;
+        </button>
+    </a>
+</div>
 
 <!-- bottom layout here -->
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index 83100192f..5d74bd444 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -41,10 +41,29 @@
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="checkPtero">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index 24ad5d3b5..04e4586d3 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -40,10 +40,29 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="redisSetup">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="redisSetup">
+            Next &#8594;
         </button>
     </div>
 </form>
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 4d57cfb1b..7806c76b2 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -15,8 +15,7 @@
             <div class="form-group">
                 <div class="flex flex-col mb-3">
                     <label for="timezone">Timezone</label>
-                    <select id="timezone" name="timezone" required
-                            class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                    <select id="timezone" name="timezone" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                         <?php
                         foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
                             if ($timezoneIdentifier === 'UTC') {
@@ -31,12 +30,31 @@ class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         </div>
     </div>
 
-    <div class="w-full flex justify-center">
-        <button
-            class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500"
-            name="timezoneConfig">Submit
+    <hr style="border: none; height: 3px; background-color: rgba(0, 0, 0, 0.3); border-bottom: 1px; border-radius: 1px; ; margin-top: 30px !important; margin-bottom: 30px">
+
+    <div class="w-full flex justify-between items-center mt-4">
+        <?php
+        if ($_SESSION['is_previous_button_available'] == true) {
+            ?>
+            <a href="?step=previous">
+                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                    &#8592; Back
+                </button>
+            </a>
+            <?php
+        } else {
+            ?>
+            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+                &#8592; Back
+            </button>
+            <?php
+        }
+        ?>
+
+        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="timezoneConfig">
+            Next &#8594;
         </button>
     </div>
 </form>
 
-<!-- bottom layout here -->
\ No newline at end of file
+<!-- bottom layout here -->

From d71d0e89118f28a6ef7fa84321abaf70e42d4755 Mon Sep 17 00:00:00 2001
From: S0ly <matis.mounic@epitech.eu>
Date: Fri, 14 Jun 2024 00:06:04 +0200
Subject: [PATCH 433/514] docs: updated the .env.exemple

---
 .env.example | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/.env.example b/.env.example
index 46f1a273a..813110b54 100644
--- a/.env.example
+++ b/.env.example
@@ -1,25 +1,40 @@
+# ⚠️ CAUTION: Advanced Configuration ⚠️
+#
+# This file (.env) stores sensitive environment variables.
+# Modifying these values can significantly impact your application's behavior.
+#
+# Proceed with caution:
+#  - Only edit if you have a clear understanding of the specific variable and its purpose.
+#  - Use the control panel or installer for most configuration changes whenever possible.
+#  - Keep a backup of this file before making any modifications.
+#
+# Need Help? Consult the documentation or contact support before making changes.
+
 ### --- App Settings --- ###
 APP_NAME=CtrlPanel.gg
 APP_ENV=production
 APP_KEY=
 APP_DEBUG=false
 APP_URL=http://localhost
-APP_TIMEZONE=UTC # List with timezones https://www.php.net/manual/en/timezones.php
+APP_TIMEZONE=UTC
 ### --- App Settings End --- ###
 
 ### --- Database Settings (required) --- ###
+# SQL
 DB_CONNECTION=mysql
 DB_HOST=127.0.0.1
 DB_PORT=3306
 DB_DATABASE=dashboard
 DB_USERNAME=dashboarduser
 DB_PASSWORD=
-### --- Database Settings End --- ###
 
-### --- Google Recaptcha Settings --- ###
-RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
-RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
-### --- Google Recaptcha Settings End --- ###
+# No-SQL
+MEMCACHED_HOST=127.0.0.1
+
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+### --- Database Settings End --- ###
 
 ### --- Mail Server Settings --- ###
 MAIL_MAILER=smtp
@@ -55,15 +70,10 @@ PUSHER_APP_ID=
 PUSHER_APP_KEY=
 PUSHER_APP_SECRET=
 PUSHER_APP_CLUSTER=mt1
-### --- External Services Credentials End --- ###
-
-### --- Additional Configuration --- ###
-MEMCACHED_HOST=127.0.0.1
-
-REDIS_HOST=127.0.0.1
-REDIS_PASSWORD=null
-REDIS_PORT=6379
 
 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
-### --- Additional Configuration End --- ###
+
+RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
+RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
+### --- External Services Credentials End --- ###

From 7a260797b0d1157b94b61c462bef578815fd3101 Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sat, 29 Jun 2024 11:31:43 +0200
Subject: [PATCH 434/514] Fix Installer migration failing to run because env
 encryption key is not loaded yet

---
 public/installer/src/forms/database.php       | 30 ++++++++++++++-----
 public/installer/views/database-migration.php |  4 +--
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index 24d5dc816..5d4917070 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -19,17 +19,38 @@
         $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     } catch (mysqli_sql_exception $e) {
         wh_log($e->getMessage(), 'error');
-        send_error_message($e->getMessage());
+        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
         exit();
     }
 
+
     foreach ($values as $key => $value) {
         $param = $_POST[$value];
+        // if ($key == "DB_PASSWORD") {
+        //    $param = '"' . $_POST[$value] . '"';
+        // }
         setenv($key, $param);
     }
 
+    wh_log('Start APP_KEY generation', 'debug');
+
+    try {
+        if (!str_contains(getenv('APP_KEY'), 'base64')) {
+            $logs = run_console('php artisan key:generate --force');
+            wh_log($logs, 'debug');
+
+            wh_log('Created APP_KEY successful', 'debug');
+        } else {
+            wh_log('Key already exists. Skipping', 'debug');
+        }
+    } catch (Throwable $th) {
+        wh_log('Creating APP_KEY failed', 'error');
+        header("LOCATION: index.php?step=3&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
+        exit();
+    }
+
     wh_log('Database connection successful', 'debug');
-    next_step();
+    header('LOCATION: index.php?step=3.5');
 }
 
 if (isset($_POST['feedDB'])) {
@@ -37,11 +58,6 @@
     $logs = '';
 
     try {
-        if (!str_contains(getenv('APP_KEY'), 'base64')) {
-            $logs .= run_console('php artisan key:generate --force');
-        } else {
-            $logs .= "Key already exists. Skipping\n";
-        }
         $logs .= run_console('php artisan storage:link');
         $logs .= run_console('php artisan migrate --seed --force');
         $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index 9962c25c1..85f0e6779 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -2,8 +2,8 @@
 <!-- top layout here -->
 
 <?php echo cardStart(
-    $title = "Database Migration and Encryption Key Generation",
-    $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"
+    $title = "Database Migration",
+    $subtitle = "Lets feed your Database! <br> This process might take a while. Please do not refresh or close this page!"
 ); ?>
 
 <form method="POST" enctype="multipart/form-data" class="m-0" action="/installer/index.php" name="feedDB">

From 3c077b047b5b466e3bb9290265f4d789abb9d2fd Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Sun, 21 Jul 2024 20:24:40 +0200
Subject: [PATCH 435/514] fix: conflicts fix

---
 public/installer/src/forms/database.php | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index 5d4917070..f474adfdf 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -19,16 +19,12 @@
         $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     } catch (mysqli_sql_exception $e) {
         wh_log($e->getMessage(), 'error');
-        header('LOCATION: index.php?step=3&message=' . $e->getMessage());
+        send_error_message($e->getMessage());
         exit();
     }
 
-
     foreach ($values as $key => $value) {
         $param = $_POST[$value];
-        // if ($key == "DB_PASSWORD") {
-        //    $param = '"' . $_POST[$value] . '"';
-        // }
         setenv($key, $param);
     }
 
@@ -50,7 +46,7 @@
     }
 
     wh_log('Database connection successful', 'debug');
-    header('LOCATION: index.php?step=3.5');
+    next_step();
 }
 
 if (isset($_POST['feedDB'])) {

From f48baa96694479878591653b2450d796d43f2209 Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Wed, 24 Jul 2024 16:10:28 +0200
Subject: [PATCH 436/514] fix: nuable bool in tickersettings

---
 app/Settings/TicketSettings.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Settings/TicketSettings.php b/app/Settings/TicketSettings.php
index 4c7ab5a78..89eec7270 100644
--- a/app/Settings/TicketSettings.php
+++ b/app/Settings/TicketSettings.php
@@ -6,7 +6,7 @@
 
 class TicketSettings extends Settings
 {
-    public ?bool $enabled;
+    public bool $enabled;
     public ?string $information;
 
     public static function group(): string

From b988ade83cddbb11fa78a1778dccfc57717319a8 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 13:14:53 -0600
Subject: [PATCH 437/514] fix: Installer

---
 public/installer/src/forms/admin.php       | 4 ++++
 public/installer/src/forms/database.php    | 4 ++++
 public/installer/src/forms/redis.php       | 2 ++
 public/installer/src/forms/smtp.php        | 3 +++
 public/installer/src/functions/logging.php | 3 +++
 public/installer/src/functions/utils.php   | 3 +++
 6 files changed, 19 insertions(+)

diff --git a/public/installer/src/forms/admin.php b/public/installer/src/forms/admin.php
index b909f9451..5626e5dc3 100644
--- a/public/installer/src/forms/admin.php
+++ b/public/installer/src/forms/admin.php
@@ -1,5 +1,9 @@
 <?php
 
+use DevCoder\DotEnv;
+
+(new DotEnv(dirname(__FILE__, 5) . '/.env'))->load();
+
 if (isset($_POST['createUser'])) {
     wh_log('Getting Pterodactyl User', 'debug');
 
diff --git a/public/installer/src/forms/database.php b/public/installer/src/forms/database.php
index f474adfdf..cace72f5a 100644
--- a/public/installer/src/forms/database.php
+++ b/public/installer/src/forms/database.php
@@ -1,5 +1,9 @@
 <?php
 
+use DevCoder\DotEnv;
+
+(new DotEnv(dirname(__FILE__, 5) . '/.env'))->load();
+
 mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);
 
 if (isset($_POST['checkDB'])) {
diff --git a/public/installer/src/forms/redis.php b/public/installer/src/forms/redis.php
index 3e9ece35a..882c8ff05 100644
--- a/public/installer/src/forms/redis.php
+++ b/public/installer/src/forms/redis.php
@@ -1,5 +1,7 @@
 <?php
 
+use Predis\Client;
+
 if (isset($_POST['redisSetup'])) {
     wh_log('Setting up Redis', 'debug');
     $redisHost = $_POST['redishost'];
diff --git a/public/installer/src/forms/smtp.php b/public/installer/src/forms/smtp.php
index 0ec801da9..b2165d7b1 100644
--- a/public/installer/src/forms/smtp.php
+++ b/public/installer/src/forms/smtp.php
@@ -1,9 +1,12 @@
 <?php
 
+use DevCoder\DotEnv;
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\PHPMailer;
 use Predis\Client;
 
+(new DotEnv(dirname(__FILE__, 5) . '/.env'))->load();
+
 require './src/phpmailer/Exception.php';
 require './src/phpmailer/PHPMailer.php';
 require './src/phpmailer/SMTP.php';
diff --git a/public/installer/src/functions/logging.php b/public/installer/src/functions/logging.php
index 3960ca11f..70324ccd9 100644
--- a/public/installer/src/functions/logging.php
+++ b/public/installer/src/functions/logging.php
@@ -1,9 +1,12 @@
 <?php
 
+use DevCoder\DotEnv;
 use Monolog\Formatter\LineFormatter;
 use Monolog\Handler\StreamHandler;
 use Monolog\Logger;
 
+(new DotEnv(dirname(__FILE__, 5) . '/.env'))->load();
+
 /**
  * Log to the default laravel.log file
  * @param string $message The message to log
diff --git a/public/installer/src/functions/utils.php b/public/installer/src/functions/utils.php
index 8f13bb69a..5c13ec524 100644
--- a/public/installer/src/functions/utils.php
+++ b/public/installer/src/functions/utils.php
@@ -1,7 +1,10 @@
 <?php
 
+use DevCoder\DotEnv;
 use Illuminate\Encryption\Encrypter;
 
+(new DotEnv(dirname(__FILE__, 5) . '/.env'))->load();
+
 /**
  * Encrypt the given value
  * @param mixed $value The variable to be encrypted

From 2f41651e3809541c19f8e55678c27992332e89ee Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:16:44 -0600
Subject: [PATCH 438/514] feat: Update dependencies

---
 composer.json | 51 +++++++++++++++++++++++++--------------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/composer.json b/composer.json
index f36209e19..231988a4e 100644
--- a/composer.json
+++ b/composer.json
@@ -8,51 +8,50 @@
     ],
     "license": "MIT",
     "require": {
-        "php": "^8.1",
+        "php": "^8.2",
         "ext-intl": "*",
         "ext-mysqli": "*",
         "ext-curl": "*",
-        "biscolab/laravel-recaptcha": "^5.4",
-        "doctrine/dbal": "^3.5.3",
+        "biscolab/laravel-recaptcha": "^6.1",
+        "doctrine/dbal": "^4.0.4",
         "guzzlehttp/guzzle": "^7.5",
         "hidehalo/nanoid-php": "^1.1.12",
-        "kkomelin/laravel-translatable-string-exporter": "^1.18",
-        "laravel/framework": "^9.50.2",
-        "laravel/tinker": "^2.8",
-        "laravel/ui": "^3.4.6",
-        "laraveldaily/laravel-invoices": "^3.0.2",
-        "league/flysystem-aws-s3-v3": "^3.12.2",
+        "kkomelin/laravel-translatable-string-exporter": "^1.22",
+        "laravel/framework": "^11.17",
+        "laravel/tinker": "^2.9",
+        "laravel/ui": "^4.5.2",
+        "laraveldaily/laravel-invoices": "^4.0.0",
+        "league/flysystem-aws-s3-v3": "^3.28.0",
         "paypal/paypal-checkout-sdk": "^1.0.2",
-        "paypal/rest-api-sdk-php": "^1.14.0",
         "predis/predis": "*",
-        "qirolab/laravel-themer": "^2.0.2",
+        "qirolab/laravel-themer": "^2.3.3",
         "socialiteproviders/discord": "^4.1.2",
-        "spatie/laravel-activitylog": "^4.7.3",
-        "spatie/laravel-permission": "^5.10",
-        "spatie/laravel-query-builder": "^5.1.2",
-        "spatie/laravel-settings": "^2.7",
-        "spatie/laravel-validation-rules": "^3.2.2",
+        "spatie/laravel-activitylog": "^4.8.0",
+        "spatie/laravel-permission": "^6.9",
+        "spatie/laravel-query-builder": "^6.0.1",
+        "spatie/laravel-settings": "^3.3",
+        "spatie/laravel-validation-rules": "^3.4.0",
         "stripe/stripe-php": "^7.128",
-        "symfony/http-client": "^6.2.6",
-        "symfony/intl": "^6.2.5",
-        "symfony/mailgun-mailer": "^6.2.5",
-        "yajra/laravel-datatables-oracle": "^9.21.2"
+        "symfony/http-client": "^7.1.2",
+        "symfony/intl": "^7.1.1",
+        "symfony/mailgun-mailer": "^7.1.2",
+        "yajra/laravel-datatables-oracle": "^11.1.3"
     },
     "require-dev": {
-        "barryvdh/laravel-debugbar": "^3.7",
+        "barryvdh/laravel-debugbar": "^3.13",
         "fakerphp/faker": "^1.21",
-        "laravel/sail": "^1.19",
+        "laravel/sail": "^1.31",
         "mockery/mockery": "^1.5.1",
-        "nunomaduro/collision": "^6.4",
-        "phpunit/phpunit": "^9.6",
-        "spatie/laravel-ignition": "^1.6"
+        "nunomaduro/collision": "^8.3",
+        "phpunit/phpunit": "^11.2",
+        "spatie/laravel-ignition": "^2.8"
     },
     "config": {
         "optimize-autoloader": true,
         "preferred-install": "dist",
         "sort-packages": true,
         "platform": {
-            "php": "8.1"
+            "php": "8.2"
         }
     },
     "extra": {

From 68e451b4ed5f50871cacc37d8a5e143df87d10cb Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:16:58 -0600
Subject: [PATCH 439/514] feat: Change Middlewares to Middleware

---
 app/Http/Kernel.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index cd7cef5fb..c334a067b 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -72,9 +72,9 @@ class Kernel extends HttpKernel
         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
         'api.token' => ApiAuthToken::class,
         'checkSuspended' => CheckSuspended::class,
-        'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
-        'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
-        'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
+        'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
+        'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
+        'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
     ];
 
 }

From fcb3cdfe30f0d18b0cc24637480a0184969146a1 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:17:21 -0600
Subject: [PATCH 440/514] fix: Change unsignedFloat to float & unsigned

---
 database/migrations/2014_10_12_000000_create_users_table.php  | 2 +-
 .../migrations/2021_07_09_190453_create_vouchers_table.php    | 2 +-
 .../2021_07_10_062140_update_credits_to_users_table.php       | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
index c28f40d8e..b619113e6 100644
--- a/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -19,7 +19,7 @@ public function up()
             $table->id();
             $table->string('name');
             $table->string('role')->default('member');
-            $table->unsignedFloat('credits')->default(250);
+            $table->float('credits')->default(250)->unsigned();
             $table->unsignedInteger('server_limit')->default(1);
             $table->unsignedInteger('pterodactyl_id')->nullable();
             $table->longText('avatar')->nullable();
diff --git a/database/migrations/2021_07_09_190453_create_vouchers_table.php b/database/migrations/2021_07_09_190453_create_vouchers_table.php
index 481674b38..5be8937e4 100644
--- a/database/migrations/2021_07_09_190453_create_vouchers_table.php
+++ b/database/migrations/2021_07_09_190453_create_vouchers_table.php
@@ -17,7 +17,7 @@ public function up()
             $table->id();
             $table->string('code', 36)->unique();
             $table->string('memo')->nullable();
-            $table->unsignedFloat('credits', 10);
+            $table->float('credits', 10)->unsigned();
             $table->unsignedInteger('uses')->default(1);
             $table->timestamp('expires_at')->nullable();
             $table->timestamps();
diff --git a/database/migrations/2021_07_10_062140_update_credits_to_users_table.php b/database/migrations/2021_07_10_062140_update_credits_to_users_table.php
index ef4e069d7..bf106b371 100644
--- a/database/migrations/2021_07_10_062140_update_credits_to_users_table.php
+++ b/database/migrations/2021_07_10_062140_update_credits_to_users_table.php
@@ -14,7 +14,7 @@
     public function up()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->unsignedFloat('credits', 10)->change();
+            $table->float('credits', 10)->change()->unsigned();
         });
     }
 
@@ -26,7 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->unsignedFloat('credits')->change();
+            $table->float('credits')->change()->unsigned();
         });
     }
 };

From 621485976ad2674273850869affaf570395e6b48 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:17:34 -0600
Subject: [PATCH 441/514] fix: Decimal

---
 database/migrations/2022_07_12_051152_decimals-in-price.php     | 2 +-
 .../2023_05_08_094402_update_user_credits_datatype.php          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/database/migrations/2022_07_12_051152_decimals-in-price.php b/database/migrations/2022_07_12_051152_decimals-in-price.php
index cf1a35b4c..da5c6582d 100644
--- a/database/migrations/2022_07_12_051152_decimals-in-price.php
+++ b/database/migrations/2022_07_12_051152_decimals-in-price.php
@@ -14,7 +14,7 @@
     public function up()
     {
         Schema::table('products', function (Blueprint $table) {
-            $table->decimal('price', ['11', '2'])->change();
+            $table->decimal('price', 11, 2)->change();
         });
     }
 
diff --git a/database/migrations/2023_05_08_094402_update_user_credits_datatype.php b/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
index db0acb2f1..57a350377 100644
--- a/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
+++ b/database/migrations/2023_05_08_094402_update_user_credits_datatype.php
@@ -26,7 +26,7 @@ public function up()
     public function down()
     {
         Schema::table('users', function (Blueprint $table) {
-            $table->decimal('credits', ['11', '2'])->change();
+            $table->decimal('credits', 11, 2)->change();
         });
     }
 }

From d815adfbb669fc443b0e1594aa7ab1c76e96cf7d Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:17:48 -0600
Subject: [PATCH 442/514] fix: Spatie Permission

---
 ..._04_29_232942_create_permission_tables.php | 27 +++++++++----------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/database/migrations/2023_04_29_232942_create_permission_tables.php b/database/migrations/2023_04_29_232942_create_permission_tables.php
index 01f845157..499e5fa8a 100644
--- a/database/migrations/2023_04_29_232942_create_permission_tables.php
+++ b/database/migrations/2023_04_29_232942_create_permission_tables.php
@@ -3,7 +3,6 @@
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Migrations\Migration;
-use Spatie\Permission\PermissionRegistrar;
 
 class CreatePermissionTables extends Migration
 {
@@ -52,13 +51,13 @@ public function up()
         });
 
         Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
-            $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission);
+            $table->unsignedBigInteger('permission_id');
 
             $table->string('model_type');
             $table->unsignedBigInteger($columnNames['model_morph_key']);
             $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
 
-            $table->foreign(PermissionRegistrar::$pivotPermission)
+            $table->foreign('permission_id')
                 ->references('id') // permission id
                 ->on($tableNames['permissions'])
                 ->onDelete('cascade');
@@ -66,23 +65,23 @@ public function up()
                 $table->unsignedBigInteger($columnNames['team_foreign_key']);
                 $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
 
-                $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
+                $table->primary([$columnNames['team_foreign_key'], 'permission_id', $columnNames['model_morph_key'], 'model_type'],
                     'model_has_permissions_permission_model_type_primary');
             } else {
-                $table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
+                $table->primary(['permission_id', $columnNames['model_morph_key'], 'model_type'],
                     'model_has_permissions_permission_model_type_primary');
             }
 
         });
 
         Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
-            $table->unsignedBigInteger(PermissionRegistrar::$pivotRole);
+            $table->unsignedBigInteger('role_id');
 
             $table->string('model_type');
             $table->unsignedBigInteger($columnNames['model_morph_key']);
             $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
 
-            $table->foreign(PermissionRegistrar::$pivotRole)
+            $table->foreign('role_id')
                 ->references('id') // role id
                 ->on($tableNames['roles'])
                 ->onDelete('cascade');
@@ -90,29 +89,29 @@ public function up()
                 $table->unsignedBigInteger($columnNames['team_foreign_key']);
                 $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
 
-                $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
+                $table->primary([$columnNames['team_foreign_key'], 'role_id', $columnNames['model_morph_key'], 'model_type'],
                     'model_has_roles_role_model_type_primary');
             } else {
-                $table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
+                $table->primary(['role_id', $columnNames['model_morph_key'], 'model_type'],
                     'model_has_roles_role_model_type_primary');
             }
         });
 
         Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
-            $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission);
-            $table->unsignedBigInteger(PermissionRegistrar::$pivotRole);
+            $table->unsignedBigInteger('permission_id');
+            $table->unsignedBigInteger('role_id');
 
-            $table->foreign(PermissionRegistrar::$pivotPermission)
+            $table->foreign('permission_id')
                 ->references('id') // permission id
                 ->on($tableNames['permissions'])
                 ->onDelete('cascade');
 
-            $table->foreign(PermissionRegistrar::$pivotRole)
+            $table->foreign('role_id')
                 ->references('id') // role id
                 ->on($tableNames['roles'])
                 ->onDelete('cascade');
 
-            $table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary');
+            $table->primary(['permission_id', 'role_id'], 'role_has_permissions_permission_id_role_id_primary');
         });
 
         app('cache')

From e98e06936bb4c0687c95d3706ffe172b3d844f10 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:18:28 -0600
Subject: [PATCH 443/514] fix: Added missing default

---
 .../2023_05_08_092704_add_billing_period_to_products.php        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/database/migrations/2023_05_08_092704_add_billing_period_to_products.php b/database/migrations/2023_05_08_092704_add_billing_period_to_products.php
index c4a7ac9ac..7936e7fda 100644
--- a/database/migrations/2023_05_08_092704_add_billing_period_to_products.php
+++ b/database/migrations/2023_05_08_092704_add_billing_period_to_products.php
@@ -23,7 +23,7 @@ public function up()
 
             $table->string('billing_period')->default("hourly");
             $table->decimal('price', 15, 4)->change();
-            $table->decimal('minimum_credits', 15, 4)->change();
+            $table->decimal('minimum_credits', 15, 4)->default(-1)->change();
         });
 
         DB::statement('UPDATE products SET billing_period="hourly"');

From e814b91030d13bfb99e2281d4ef22f1d2022bf76 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:18:40 -0600
Subject: [PATCH 444/514] feat: Added missing default

---
 ...ault_value_to_locked_in_settings_table.php | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php

diff --git a/database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php b/database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php
new file mode 100644
index 000000000..47881fc15
--- /dev/null
+++ b/database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up(): void
+    {
+        Schema::table('settings', function (Blueprint $table) {
+            $table->boolean('locked')->default(false)->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down(): void
+    {
+        Schema::table('settings', function (Blueprint $table) {
+            $table->boolean('locked')->default(null)->change();
+        });
+    }
+};

From e3f44f190a4f62cc7a274528ae676fbb50c8e33f Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 18:18:58 -0600
Subject: [PATCH 445/514] feat: Added missing nullable & text

---
 ...add_required_nullable_and_text_columns.php | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php

diff --git a/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php b/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php
new file mode 100644
index 000000000..41f2c6c0f
--- /dev/null
+++ b/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php
@@ -0,0 +1,46 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('locations', function (Blueprint $table) {
+            $table->text('description')->nullable()->change();
+        });
+        Schema::table('nodes', function (Blueprint $table) {
+            $table->text('description')->nullable()->change();
+        });
+        Schema::table('nests', function (Blueprint $table) {
+            $table->text('description')->nullable()->change();
+        });
+        Schema::table('eggs', function (Blueprint $table) {
+            $table->text('description')->nullable()->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('locations', function (Blueprint $table) {
+            $table->string('description')->change();
+        });
+        Schema::table('nodes', function (Blueprint $table) {
+            $table->string('description')->change();
+        });
+        Schema::table('nests', function (Blueprint $table) {
+            $table->string('description')->change();
+        });
+        Schema::table('eggs', function (Blueprint $table) {
+            $table->string('description')->change();
+        });
+    }
+};
\ No newline at end of file

From 734a1c628211b0155e8a23167612f2c7c9399dcd Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 24 Jul 2024 21:02:24 -0600
Subject: [PATCH 446/514] feat: Re implemented PermissionRegister

---
 ..._04_29_232942_create_permission_tables.php | 27 ++++++++++---------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/database/migrations/2023_04_29_232942_create_permission_tables.php b/database/migrations/2023_04_29_232942_create_permission_tables.php
index 499e5fa8a..ef728fec0 100644
--- a/database/migrations/2023_04_29_232942_create_permission_tables.php
+++ b/database/migrations/2023_04_29_232942_create_permission_tables.php
@@ -3,6 +3,7 @@
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Migrations\Migration;
+use Spatie\Permission\PermissionRegistrar;
 
 class CreatePermissionTables extends Migration
 {
@@ -51,13 +52,13 @@ public function up()
         });
 
         Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
-            $table->unsignedBigInteger('permission_id');
+            $table->unsignedBigInteger(app(PermissionRegistrar::class)->pivotPermission);
 
             $table->string('model_type');
             $table->unsignedBigInteger($columnNames['model_morph_key']);
             $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
 
-            $table->foreign('permission_id')
+            $table->foreign(app(PermissionRegistrar::class)->pivotPermission)
                 ->references('id') // permission id
                 ->on($tableNames['permissions'])
                 ->onDelete('cascade');
@@ -65,23 +66,23 @@ public function up()
                 $table->unsignedBigInteger($columnNames['team_foreign_key']);
                 $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
 
-                $table->primary([$columnNames['team_foreign_key'], 'permission_id', $columnNames['model_morph_key'], 'model_type'],
+                $table->primary([$columnNames['team_foreign_key'], app(PermissionRegistrar::class)->pivotPermission, $columnNames['model_morph_key'], 'model_type'],
                     'model_has_permissions_permission_model_type_primary');
             } else {
-                $table->primary(['permission_id', $columnNames['model_morph_key'], 'model_type'],
+                $table->primary([app(PermissionRegistrar::class)->pivotPermission, $columnNames['model_morph_key'], 'model_type'],
                     'model_has_permissions_permission_model_type_primary');
             }
 
         });
 
         Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
-            $table->unsignedBigInteger('role_id');
+            $table->unsignedBigInteger(app(PermissionRegistrar::class)->pivotRole);
 
             $table->string('model_type');
             $table->unsignedBigInteger($columnNames['model_morph_key']);
             $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
 
-            $table->foreign('role_id')
+            $table->foreign(app(PermissionRegistrar::class)->pivotRole)
                 ->references('id') // role id
                 ->on($tableNames['roles'])
                 ->onDelete('cascade');
@@ -89,29 +90,29 @@ public function up()
                 $table->unsignedBigInteger($columnNames['team_foreign_key']);
                 $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
 
-                $table->primary([$columnNames['team_foreign_key'], 'role_id', $columnNames['model_morph_key'], 'model_type'],
+                $table->primary([$columnNames['team_foreign_key'], app(PermissionRegistrar::class)->pivotRole, $columnNames['model_morph_key'], 'model_type'],
                     'model_has_roles_role_model_type_primary');
             } else {
-                $table->primary(['role_id', $columnNames['model_morph_key'], 'model_type'],
+                $table->primary([app(PermissionRegistrar::class)->pivotRole, $columnNames['model_morph_key'], 'model_type'],
                     'model_has_roles_role_model_type_primary');
             }
         });
 
         Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
-            $table->unsignedBigInteger('permission_id');
-            $table->unsignedBigInteger('role_id');
+            $table->unsignedBigInteger(app(PermissionRegistrar::class)->pivotPermission);
+            $table->unsignedBigInteger(app(PermissionRegistrar::class)->pivotRole);
 
-            $table->foreign('permission_id')
+            $table->foreign(app(PermissionRegistrar::class)->pivotPermission)
                 ->references('id') // permission id
                 ->on($tableNames['permissions'])
                 ->onDelete('cascade');
 
-            $table->foreign('role_id')
+            $table->foreign(app(PermissionRegistrar::class)->pivotRole)
                 ->references('id') // role id
                 ->on($tableNames['roles'])
                 ->onDelete('cascade');
 
-            $table->primary(['permission_id', 'role_id'], 'role_has_permissions_permission_id_role_id_primary');
+            $table->primary([app(PermissionRegistrar::class)->pivotPermission, app(PermissionRegistrar::class)->pivotRole], 'role_has_permissions_permission_id_role_id_primary');
         });
 
         app('cache')

From df35503b177227317626bc87526d8fc2f9f3ce1e Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 10:09:14 -0600
Subject: [PATCH 447/514] fix: Store & Update role

---
 app/Http/Controllers/Admin/RoleController.php | 6 ++++--
 app/Http/Controllers/Api/RoleController.php   | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index b2c685f44..9d9518555 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -72,7 +72,8 @@ public function store(Request $request): RedirectResponse
         ]);
 
         if ($request->permissions) {
-            $role->givePermissionTo($request->permissions);
+            $collectedPermissions = collect($request->permissions)->map(fn($val)=>(int)$val);
+            $role->givePermissionTo($collectedPermissions);
         }
 
         return redirect()
@@ -123,7 +124,8 @@ public function update(Request $request, Role $role)
 
         if ($request->permissions) {
             if($role->id != 1){ //disable admin permissions change
-                $role->syncPermissions($request->permissions);
+                $collectedPermissions = collect($request->permissions)->map(fn($val)=>(int)$val);
+                $role->syncPermissions($collectedPermissions);
             }
         }
 
diff --git a/app/Http/Controllers/Api/RoleController.php b/app/Http/Controllers/Api/RoleController.php
index ac44c240f..1deca23fe 100644
--- a/app/Http/Controllers/Api/RoleController.php
+++ b/app/Http/Controllers/Api/RoleController.php
@@ -68,7 +68,8 @@ public function store(Request $request)
 
         if ($request->permissions) {
             $permissions = explode(",",$request->permissions);
-            foreach($permissions as $permission){
+            $collectedPermissions = collect($permissions)->map(fn($val)=>(int)$val);
+            foreach($collectedPermissions as $permission){
                 $role->givePermissionTo($permission);
             }
         }
@@ -124,7 +125,8 @@ public function update(Request $request, int $id)
 
         if ($request->permissions) {
             $permissions = explode(",",$request->permissions);
-                $role->syncPermissions($permissions);
+            $collectedPermissions = collect($permissions)->map(fn($val)=>(int)$val);
+            $role->syncPermissions($collectedPermissions);
         }
 
 

From 1ee50cc8497320c02cc4e81d9c37e4485777dd6c Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 10:09:31 -0600
Subject: [PATCH 448/514] fix: User update & store rol

---
 app/Http/Controllers/Admin/UserController.php | 3 ++-
 app/Http/Controllers/Api/UserController.php   | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 69e3cbd8b..57fc53cd2 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -159,7 +159,8 @@ public function update(Request $request, User $user)
 
         //update roles
         if ($request->roles && $this->can(self::CHANGE_ROLE_PERMISSION)) {
-            $user->syncRoles($request->roles);
+            $collectedRoles = collect($request->roles)->map(fn($val)=>(int)$val);
+            $user->syncRoles($collectedRoles);
         }
 
         if (isset($this->pterodactyl->getUser($request->input('pterodactyl_id'))['errors'])) {
diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php
index cb7a1bb79..3f2a281f7 100644
--- a/app/Http/Controllers/Api/UserController.php
+++ b/app/Http/Controllers/Api/UserController.php
@@ -106,7 +106,8 @@ public function update(Request $request, int $id)
             ]);
         }
         if($request->has("role")){
-            $user->syncRoles($request->role);
+            $collectedRoles = collect($request->role)->map(fn($val)=>(int)$val);
+            $user->syncRoles($collectedRoles);
         }
         $user->update($request->except('role'));
 

From b4baf79ec5762a8145fb371e0e5896e6933519cc Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 10:09:50 -0600
Subject: [PATCH 449/514] feat: Removed default value migration

---
 ...ault_value_to_locked_in_settings_table.php | 32 -------------------
 1 file changed, 32 deletions(-)
 delete mode 100644 database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php

diff --git a/database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php b/database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php
deleted file mode 100644
index 47881fc15..000000000
--- a/database/migrations/2024_07_24_150126_add_default_value_to_locked_in_settings_table.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-use Illuminate\Database\Migrations\Migration;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Support\Facades\Schema;
-
-return new class extends Migration
-{
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up(): void
-    {
-        Schema::table('settings', function (Blueprint $table) {
-            $table->boolean('locked')->default(false)->change();
-        });
-    }
-
-    /**
-     * Reverse the migrations.
-     *
-     * @return void
-     */
-    public function down(): void
-    {
-        Schema::table('settings', function (Blueprint $table) {
-            $table->boolean('locked')->default(null)->change();
-        });
-    }
-};

From 6d6c20a8f680c6fc89c5b1e78d993bc34a1a93f6 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 10:10:51 -0600
Subject: [PATCH 450/514] feat: Added migration

---
 ...712_update_settings_default_and_unique.php | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 database/migrations/2024_07_25_083712_update_settings_default_and_unique.php

diff --git a/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php b/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php
new file mode 100644
index 000000000..e4b421781
--- /dev/null
+++ b/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('settings', function (Blueprint $table): void {
+            $table->boolean('locked')->default(false)->change();
+            $table->unique(['group', 'name']);
+            $table->dropIndex(['group']);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('settings', function (Blueprint $table): void {
+            $table->boolean('locked')->default(null)->change();
+            $table->dropUnique(['group', 'name']);
+            $table->index('group');
+        });
+    }
+};

From 727d6351383c6077214aece09f47aba6d71ac876 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 10:15:58 -0600
Subject: [PATCH 451/514] feat: Removed void

---
 .../2024_07_25_083712_update_settings_default_and_unique.php  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php b/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php
index e4b421781..ad81ce1ee 100644
--- a/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php
+++ b/database/migrations/2024_07_25_083712_update_settings_default_and_unique.php
@@ -11,7 +11,7 @@
      */
     public function up(): void
     {
-        Schema::table('settings', function (Blueprint $table): void {
+        Schema::table('settings', function (Blueprint $table) {
             $table->boolean('locked')->default(false)->change();
             $table->unique(['group', 'name']);
             $table->dropIndex(['group']);
@@ -23,7 +23,7 @@ public function up(): void
      */
     public function down(): void
     {
-        Schema::table('settings', function (Blueprint $table): void {
+        Schema::table('settings', function (Blueprint $table) {
             $table->boolean('locked')->default(null)->change();
             $table->dropUnique(['group', 'name']);
             $table->index('group');

From b5f6b0d30f2e69633198de03b5cbc92cd417f85e Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 13:54:25 -0600
Subject: [PATCH 452/514] fix: Showing roles & Design

---
 .../default/views/admin/roles/index.blade.php | 136 +++++++++---------
 1 file changed, 66 insertions(+), 70 deletions(-)

diff --git a/themes/default/views/admin/roles/index.blade.php b/themes/default/views/admin/roles/index.blade.php
index 4391f662b..0486f6279 100644
--- a/themes/default/views/admin/roles/index.blade.php
+++ b/themes/default/views/admin/roles/index.blade.php
@@ -11,92 +11,88 @@
             <div class="col-sm-6">
                 <ol class="breadcrumb float-sm-right">
                     <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                    <li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.roles.index')}}">{{__('Roles List')}}</a></li>
+                    <li class="breadcrumb-item"><a class="text-muted"
+                            href="{{route('admin.roles.index')}}">{{__('Roles List')}}</a></li>
                 </ol>
             </div>
         </div>
     </div>
 </section>
 
-    <div class="py-4 main">
-
-        @can('admin.roles.write')
-            <div class="my-3 d-flex justify-content-end">
-                <a href="{{route('admin.roles.create')}}" class="btn btn-primary"><i
-                        class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
-            </div>
-        @endcan
-
-        <div class="border-0 shadow card card-body table-wrapper table-responsive">
-            <h2 class="mb-4 h5">{{ __('Roles') }}</h2>
-
 <section class="content">
     <div class="container-fluid">
+
         <div class="card">
+
             <div class="card-header">
                 <div class="d-flex justify-content-between">
                     <h5 class="card-title"><i class="mr-2 fas fa-user-check"></i>{{__('Roles List')}}</h5>
+                    @can('admin.roles.write')
+                        <a href="{{route('admin.roles.create')}}" class="float-right btn btn-primary"><i
+                                class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
+                    @endcan
                 </div>
-                @can('admin.roles.write')
-                    <a href="{{route('admin.roles.create')}}" class="float-right btn btn-primary"><i class="fa fas fa-shield-alt pe-2"></i>{{__('Create role')}}</a>
-                @endcan
             </div>
+
             <div class="card-body table-responsive">
-                <div class="card-body table-responsive">
-                    <table id="datatable" class="table table-striped">
-                        <thead>
-                            <tr>
-                                <th>{{__("ID")}}</th>
-                                <th>{{__("Name")}}</th>
-                                <th>{{__("User count")}}</th>
-                                <th>{{__("Permissions count")}}</th>
-                                <th>{{__("Power")}}</th>
-                                <th>{{__("Actions")}}</th>
-                            </tr>
-                        </thead>
-                        <tbody>
-                        </tbody>
-                    </table>
 
-                </div>
-            </div>
+                <table id="datatable" class="table table-striped">
+                    <thead>
+                        <tr>
+                            <th>{{__("ID")}}</th>
+                            <th>{{__("Name")}}</th>
+                            <th>{{__("User count")}}</th>
+                            <th>{{__("Permissions count")}}</th>
+                            <th>{{__("Power")}}</th>
+                            <th>{{__("Actions")}}</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                    </tbody>
+                </table>
 
+            </div>
         </div>
-    </div>
-    @endsection
-    <script>
-        document.addEventListener("DOMContentLoaded", function() {
-            $('#datatable').DataTable({
-                language: {
-                    url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
-                },
-                processing: true,
-                serverSide: true, //increases loading times too much? change back to "true" if it does
-                stateSave: true,
-                ajax: "{{route('admin.roles.datatable')}}",
-                columns: [{
-                        data: 'id'
-                    },
-                    {
-                        data: 'name'
-                    },
-                    {
-                        data: 'users_count'
-                    },
-                    {
-                        data: 'permissions_count'
-                    },
-                    {
-                        data: 'power'
-                    },
-                    {
-                        data: 'actions',
-                        sortable: false
-                    }
-                ],
-                fnDrawCallback: function(oSettings) {
-                    $('[data-toggle="popover"]').popover();
-                }
-            });
 
-    </script>
+
+    </div>
+    <!-- END CUSTOM CONTENT -->
+</section>
+<!-- END CONTENT -->
+<script>
+    document.addEventListener("DOMContentLoaded", function () {
+        $('#datatable').DataTable({
+            language: {
+                url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
+            },
+            processing: true,
+            serverSide: true, //increases loading times too much? change back to "true" if it does
+            stateSave: true,
+            ajax: "{{route('admin.roles.datatable')}}",
+            columns: [{
+                data: 'id'
+            },
+            {
+                data: 'name'
+            },
+            {
+                data: 'users_count'
+            },
+            {
+                data: 'permissions_count'
+            },
+            {
+                data: 'power'
+            },
+            {
+                data: 'actions',
+                sortable: false
+            }
+            ],
+            fnDrawCallback: function (oSettings) {
+                $('[data-toggle="popover"]').popover();
+            }
+        });
+    });
+</script>
+@endsection

From 8fa57efc025ad935f9182ae2e705b41b674859a3 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Thu, 25 Jul 2024 14:05:09 -0600
Subject: [PATCH 453/514] feat: Added power update

---
 app/Http/Controllers/Admin/RoleController.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 9d9518555..3ce5ad5bb 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -136,7 +136,8 @@ public function update(Request $request, Role $role)
         //}else{
             $role->update([
                 'name' => $request->name,
-                'color' => $request->color
+                'color' => $request->color,
+                'power' => $request->power
             ]);
         //}
 

From f739fa1352c3c3f8a53e73d46d7ab82baff96c2e Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 27 Jul 2024 18:35:14 -0600
Subject: [PATCH 454/514] fix: Permission name

---
 config/permissions_web.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/permissions_web.php b/config/permissions_web.php
index b4037aac2..1e67f65fc 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -13,7 +13,7 @@
     'Delete Role' => 'admin.roles.delete',
 
 
-    'View Tickets' => 'admin.ticket.read',
+    'View Tickets' => 'admin.tickets.read',
     'Manage Ticket' => 'admin.tickets.write',
     'Receive Ticket Notifications' => 'admin.tickets.get_notification',
 

From d2b88a5694dbc086bd55cca0b8a9e9ecd2d112ea Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 27 Jul 2024 20:23:23 -0600
Subject: [PATCH 455/514] feat: Update roles theme

---
 .../default/views/admin/roles/edit.blade.php  | 45 ++++++++++++++-----
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/themes/default/views/admin/roles/edit.blade.php b/themes/default/views/admin/roles/edit.blade.php
index 76dfc3cdd..5af3378d1 100644
--- a/themes/default/views/admin/roles/edit.blade.php
+++ b/themes/default/views/admin/roles/edit.blade.php
@@ -1,12 +1,36 @@
 @extends('layouts.main')
 
 @section('content')
-    <div class="py-4 main">
-
-        <div class="border-0 shadow card card-body table-wrapper table-responsive">
-            <h2 class="mb-4 h5">{{ isset($role) ?  __('Edit role') : __('Create role') }}</h2>
-
-            <form method="post"
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="mb-2 row">
+                <div class="col-sm-6">
+                    <h1>{{ isset($role) ?  __('Edit role') : __('Create role') }}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('admin.settings.index') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.roles.index') }}">{{ __('Roles List') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ isset($role) ?  route('admin.roles.edit', $role->id) : route('admin.roles.create') }}">{{ isset($role) ?  __('Edit role') : __('Create role') }}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+
+    <section class="content">
+        <div class="container-fluid">
+            <div class="card">
+                <div class="card-header">
+                    <div class="d-flex justify-content-between">
+                        <h5 class="card-title"><i class="mr-2 fas fa-user-check"></i>{{ isset($role) ?  __('Edit role') : __('Create role') }}</h5>
+                    </div>
+                </div>
+                <div class="card-body">
+                        <div class="p-0 col-12">
+                            <form method="post"
                   action="{{isset($role) ? route('admin.roles.update', $role->id) : route('admin.roles.store')}}">
                 @csrf
                 @isset($role)
@@ -54,10 +78,12 @@
                     <button name="submit" type="submit" class="btn btn-primary">{{__('Submit')}}</button>
                 </div>
             </form>
-
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
-
-    </div>
+    </section>
 
     <script>
         document.addEventListener('DOMContentLoaded', (event) => {
@@ -67,4 +93,3 @@
         })
     </script>
 @endsection
-

From 998876ba0372043e72b870dee9c981721efb6326 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Mon, 29 Jul 2024 10:14:46 -0600
Subject: [PATCH 456/514] fix: Ticket middleware

---
 routes/web.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/routes/web.php b/routes/web.php
index 444d9485b..7d56e5f04 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -119,9 +119,9 @@
     Route::get('ticket', [TicketsController::class, 'index'])->name('ticket.index');
     Route::get('ticket/datatable', [TicketsController::class, 'datatable'])->name('ticket.datatable');
     Route::get('ticket/new', [TicketsController::class, 'create'])->name('ticket.new');
-    Route::post('ticket/new', [TicketsController::class, 'store'])->middleware(['throttle:ticket-new'])->name('ticket.new.store');
+    Route::post('ticket/new', [TicketsController::class, 'store'])->middleware(['throttle:1,1'])->name('ticket.new.store');
     Route::get('ticket/show/{ticket_id}', [TicketsController::class, 'show'])->name('ticket.show');
-    Route::post('ticket/reply', [TicketsController::class, 'reply'])->middleware(['throttle:ticket-reply'])->name('ticket.reply');
+    Route::post('ticket/reply', [TicketsController::class, 'reply'])->middleware(['throttle:10,1'])->name('ticket.reply');
     Route::post('ticket/status/{ticket_id}', [TicketsController::class, 'changeStatus'])->name('ticket.changeStatus');
 
 

From fca27fdf17b476c7721b38f91e62e83e78dd8be2 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Mon, 29 Jul 2024 11:11:28 -0600
Subject: [PATCH 457/514] feat: Update composer.lock

---
 composer.lock | 4267 +++++++++++++++++++++++++++----------------------
 1 file changed, 2318 insertions(+), 1949 deletions(-)

diff --git a/composer.lock b/composer.lock
index 3f224c0c4..20e494507 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "8a9b4a3cda2a919fa33f41527b679dce",
+    "content-hash": "6284e796f9bb6fd440148a123c7a77e3",
     "packages": [
         {
             "name": "aws/aws-crt-php",
-            "version": "v1.2.1",
+            "version": "v1.2.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/awslabs/aws-crt-php.git",
-                "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5"
+                "reference": "a63485b65b6b3367039306496d49737cf1995408"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5",
-                "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5",
+                "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/a63485b65b6b3367039306496d49737cf1995408",
+                "reference": "a63485b65b6b3367039306496d49737cf1995408",
                 "shasum": ""
             },
             "require": {
@@ -56,34 +56,35 @@
             ],
             "support": {
                 "issues": "https://github.com/awslabs/aws-crt-php/issues",
-                "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1"
+                "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.6"
             },
-            "time": "2023-03-24T20:22:19+00:00"
+            "time": "2024-06-13T17:21:28+00:00"
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.269.0",
+            "version": "3.316.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "6d759ef9f24f0c7f271baf8014f41fc0cfdfbf78"
+                "reference": "e832e594b3c213760e067e15ef2739f77505e832"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6d759ef9f24f0c7f271baf8014f41fc0cfdfbf78",
-                "reference": "6d759ef9f24f0c7f271baf8014f41fc0cfdfbf78",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e832e594b3c213760e067e15ef2739f77505e832",
+                "reference": "e832e594b3c213760e067e15ef2739f77505e832",
                 "shasum": ""
             },
             "require": {
-                "aws/aws-crt-php": "^1.0.4",
+                "aws/aws-crt-php": "^1.2.3",
                 "ext-json": "*",
                 "ext-pcre": "*",
                 "ext-simplexml": "*",
                 "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5",
-                "guzzlehttp/promises": "^1.4.0",
+                "guzzlehttp/promises": "^1.4.0 || ^2.0",
                 "guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
                 "mtdowling/jmespath.php": "^2.6",
-                "php": ">=5.5"
+                "php": ">=7.2.5",
+                "psr/http-message": "^1.0 || ^2.0"
             },
             "require-dev": {
                 "andrewsville/php-token-reflection": "^1.4",
@@ -98,9 +99,8 @@
                 "ext-sockets": "*",
                 "nette/neon": "^2.3",
                 "paragonie/random_compat": ">= 2",
-                "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5",
+                "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5",
                 "psr/cache": "^1.0",
-                "psr/http-message": "^1.0",
                 "psr/simple-cache": "^1.0",
                 "sebastian/comparator": "^1.2.3 || ^4.0",
                 "yoast/phpunit-polyfills": "^1.0"
@@ -151,33 +151,33 @@
             "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.269.0"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.316.3"
             },
-            "time": "2023-04-26T18:21:04+00:00"
+            "time": "2024-07-12T18:07:23+00:00"
         },
         {
             "name": "barryvdh/laravel-dompdf",
-            "version": "v2.0.1",
+            "version": "v2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-dompdf.git",
-                "reference": "9843d2be423670fb434f4c978b3c0f4dd92c87a6"
+                "reference": "c96f90c97666cebec154ca1ffb67afed372114d8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/9843d2be423670fb434f4c978b3c0f4dd92c87a6",
-                "reference": "9843d2be423670fb434f4c978b3c0f4dd92c87a6",
+                "url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/c96f90c97666cebec154ca1ffb67afed372114d8",
+                "reference": "c96f90c97666cebec154ca1ffb67afed372114d8",
                 "shasum": ""
             },
             "require": {
-                "dompdf/dompdf": "^2.0.1",
-                "illuminate/support": "^6|^7|^8|^9|^10",
+                "dompdf/dompdf": "^2.0.7",
+                "illuminate/support": "^6|^7|^8|^9|^10|^11",
                 "php": "^7.2 || ^8.0"
             },
             "require-dev": {
-                "nunomaduro/larastan": "^1|^2",
-                "orchestra/testbench": "^4|^5|^6|^7|^8",
-                "phpro/grumphp": "^1",
+                "larastan/larastan": "^1.0|^2.7.0",
+                "orchestra/testbench": "^4|^5|^6|^7|^8|^9",
+                "phpro/grumphp": "^1 || ^2.5",
                 "squizlabs/php_codesniffer": "^3.5"
             },
             "type": "library",
@@ -218,7 +218,7 @@
             ],
             "support": {
                 "issues": "https://github.com/barryvdh/laravel-dompdf/issues",
-                "source": "https://github.com/barryvdh/laravel-dompdf/tree/v2.0.1"
+                "source": "https://github.com/barryvdh/laravel-dompdf/tree/v2.2.0"
             },
             "funding": [
                 {
@@ -230,30 +230,30 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-12T15:12:49+00:00"
+            "time": "2024-04-25T13:16:04+00:00"
         },
         {
             "name": "biscolab/laravel-recaptcha",
-            "version": "v5.4.0",
+            "version": "v6.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/biscolab/laravel-recaptcha.git",
-                "reference": "1bab726402d5376553a439b88a0faa07e84488fd"
+                "reference": "440fc617cba9f39aab7fda5d7697b76a55286e31"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/biscolab/laravel-recaptcha/zipball/1bab726402d5376553a439b88a0faa07e84488fd",
-                "reference": "1bab726402d5376553a439b88a0faa07e84488fd",
+                "url": "https://api.github.com/repos/biscolab/laravel-recaptcha/zipball/440fc617cba9f39aab7fda5d7697b76a55286e31",
+                "reference": "440fc617cba9f39aab7fda5d7697b76a55286e31",
                 "shasum": ""
             },
             "require": {
-                "illuminate/routing": "^7.0|^8.0|^9.0",
-                "illuminate/support": "^7.0|^8.0|^9.0",
+                "illuminate/routing": "^7.0|^8.0|^9.0|^10.0|^11.0",
+                "illuminate/support": "^7.0|^8.0|^9.0|^10.0|^11.0",
                 "php": "^7.3|^8.0"
             },
             "require-dev": {
-                "orchestra/testbench": "5.*|6.*|^7.0",
-                "phpunit/phpunit": "^9.1"
+                "orchestra/testbench": "5.*|6.*|^7.0|^8.0|^9.0",
+                "phpunit/phpunit": "^9.1|^10.5"
             },
             "suggest": {
                 "biscolab/laravel-authlog": "It allows to handle logged-in users and force log-out if needed"
@@ -299,31 +299,32 @@
             ],
             "support": {
                 "issues": "https://github.com/biscolab/laravel-recaptcha/issues",
-                "source": "https://github.com/biscolab/laravel-recaptcha/tree/v5.4.0"
+                "source": "https://github.com/biscolab/laravel-recaptcha/tree/v6.1.0"
             },
-            "time": "2022-05-07T12:52:46+00:00"
+            "abandoned": true,
+            "time": "2024-03-27T11:06:21+00:00"
         },
         {
             "name": "brick/math",
-            "version": "0.11.0",
+            "version": "0.12.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/brick/math.git",
-                "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478"
+                "reference": "f510c0a40911935b77b86859eb5223d58d660df1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478",
-                "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478",
+                "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1",
+                "reference": "f510c0a40911935b77b86859eb5223d58d660df1",
                 "shasum": ""
             },
             "require": {
-                "php": "^8.0"
+                "php": "^8.1"
             },
             "require-dev": {
                 "php-coveralls/php-coveralls": "^2.2",
-                "phpunit/phpunit": "^9.0",
-                "vimeo/psalm": "5.0.0"
+                "phpunit/phpunit": "^10.1",
+                "vimeo/psalm": "5.16.0"
             },
             "type": "library",
             "autoload": {
@@ -343,12 +344,17 @@
                 "arithmetic",
                 "bigdecimal",
                 "bignum",
+                "bignumber",
                 "brick",
-                "math"
+                "decimal",
+                "integer",
+                "math",
+                "mathematics",
+                "rational"
             ],
             "support": {
                 "issues": "https://github.com/brick/math/issues",
-                "source": "https://github.com/brick/math/tree/0.11.0"
+                "source": "https://github.com/brick/math/tree/0.12.1"
             },
             "funding": [
                 {
@@ -356,20 +362,89 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-15T23:15:59+00:00"
+            "time": "2023-11-29T23:19:16+00:00"
+        },
+        {
+            "name": "carbonphp/carbon-doctrine-types",
+            "version": "3.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
+                "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
+                "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.1"
+            },
+            "conflict": {
+                "doctrine/dbal": "<4.0.0 || >=5.0.0"
+            },
+            "require-dev": {
+                "doctrine/dbal": "^4.0.0",
+                "nesbot/carbon": "^2.71.0 || ^3.0.0",
+                "phpunit/phpunit": "^10.3"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "KyleKatarn",
+                    "email": "kylekatarnls@gmail.com"
+                }
+            ],
+            "description": "Types to use Carbon in Doctrine",
+            "keywords": [
+                "carbon",
+                "date",
+                "datetime",
+                "doctrine",
+                "time"
+            ],
+            "support": {
+                "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
+                "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/kylekatarnls",
+                    "type": "github"
+                },
+                {
+                    "url": "https://opencollective.com/Carbon",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-02-09T16:56:22+00:00"
         },
         {
             "name": "dflydev/dot-access-data",
-            "version": "v3.0.2",
+            "version": "v3.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dflydev/dflydev-dot-access-data.git",
-                "reference": "f41715465d65213d644d3141a6a93081be5d3549"
+                "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549",
-                "reference": "f41715465d65213d644d3141a6a93081be5d3549",
+                "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f",
+                "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f",
                 "shasum": ""
             },
             "require": {
@@ -429,145 +504,48 @@
             ],
             "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/cache",
-            "version": "2.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/doctrine/cache.git",
-                "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
-                "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
-                "shasum": ""
-            },
-            "require": {
-                "php": "~7.1 || ^8.0"
-            },
-            "conflict": {
-                "doctrine/common": ">2.2,<2.4"
-            },
-            "require-dev": {
-                "cache/integration-tests": "dev-master",
-                "doctrine/coding-standard": "^9",
-                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
-                "psr/cache": "^1.0 || ^2.0 || ^3.0",
-                "symfony/cache": "^4.4 || ^5.4 || ^6",
-                "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-4": {
-                    "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
-                }
-            },
-            "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 Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
-            "homepage": "https://www.doctrine-project.org/projects/cache.html",
-            "keywords": [
-                "abstraction",
-                "apcu",
-                "cache",
-                "caching",
-                "couchdb",
-                "memcached",
-                "php",
-                "redis",
-                "xcache"
-            ],
-            "support": {
-                "issues": "https://github.com/doctrine/cache/issues",
-                "source": "https://github.com/doctrine/cache/tree/2.2.0"
+                "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3"
             },
-            "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%2Fcache",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2022-05-20T20:07:39+00:00"
+            "time": "2024-07-08T12:26:09+00:00"
         },
         {
             "name": "doctrine/dbal",
-            "version": "3.6.2",
+            "version": "4.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c"
+                "reference": "50fda19f80724b55ff770bb4ff352407008e63c5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/b4bd1cfbd2b916951696d82e57d054394d84864c",
-                "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/50fda19f80724b55ff770bb4ff352407008e63c5",
+                "reference": "50fda19f80724b55ff770bb4ff352407008e63c5",
                 "shasum": ""
             },
             "require": {
-                "composer-runtime-api": "^2",
-                "doctrine/cache": "^1.11|^2.0",
                 "doctrine/deprecations": "^0.5.3|^1",
-                "doctrine/event-manager": "^1|^2",
-                "php": "^7.4 || ^8.0",
+                "php": "^8.1",
                 "psr/cache": "^1|^2|^3",
                 "psr/log": "^1|^2|^3"
             },
             "require-dev": {
-                "doctrine/coding-standard": "11.1.0",
+                "doctrine/coding-standard": "12.0.0",
                 "fig/log-test": "^1",
-                "jetbrains/phpstorm-stubs": "2022.3",
-                "phpstan/phpstan": "1.10.9",
-                "phpstan/phpstan-strict-rules": "^1.5",
-                "phpunit/phpunit": "9.6.6",
-                "psalm/plugin-phpunit": "0.18.4",
-                "squizlabs/php_codesniffer": "3.7.2",
-                "symfony/cache": "^5.4|^6.0",
-                "symfony/console": "^4.4|^5.4|^6.0",
-                "vimeo/psalm": "4.30.0"
+                "jetbrains/phpstorm-stubs": "2023.2",
+                "phpstan/phpstan": "1.11.5",
+                "phpstan/phpstan-phpunit": "1.4.0",
+                "phpstan/phpstan-strict-rules": "^1.6",
+                "phpunit/phpunit": "10.5.22",
+                "psalm/plugin-phpunit": "0.19.0",
+                "slevomat/coding-standard": "8.13.1",
+                "squizlabs/php_codesniffer": "3.10.1",
+                "symfony/cache": "^6.3.8|^7.0",
+                "symfony/console": "^5.4|^6.3|^7.0",
+                "vimeo/psalm": "5.24.0"
             },
             "suggest": {
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
             },
-            "bin": [
-                "bin/doctrine-dbal"
-            ],
             "type": "library",
             "autoload": {
                 "psr-4": {
@@ -620,7 +598,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/3.6.2"
+                "source": "https://github.com/doctrine/dbal/tree/4.0.4"
             },
             "funding": [
                 {
@@ -636,29 +614,33 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-14T07:25:38+00:00"
+            "time": "2024-06-19T11:57:23+00:00"
         },
         {
             "name": "doctrine/deprecations",
-            "version": "v1.0.0",
+            "version": "1.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/deprecations.git",
-                "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
+                "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
-                "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+                "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+                "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.1|^8.0"
+                "php": "^7.1 || ^8.0"
             },
             "require-dev": {
                 "doctrine/coding-standard": "^9",
-                "phpunit/phpunit": "^7.5|^8.5|^9.5",
-                "psr/log": "^1|^2|^3"
+                "phpstan/phpstan": "1.4.10 || 1.10.15",
+                "phpstan/phpstan-phpunit": "^1.0",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "psalm/plugin-phpunit": "0.18.4",
+                "psr/log": "^1 || ^2 || ^3",
+                "vimeo/psalm": "4.30.0 || 5.12.0"
             },
             "suggest": {
                 "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
@@ -677,125 +659,34 @@
             "homepage": "https://www.doctrine-project.org/",
             "support": {
                 "issues": "https://github.com/doctrine/deprecations/issues",
-                "source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
-            },
-            "time": "2022-05-02T15:47:09+00:00"
-        },
-        {
-            "name": "doctrine/event-manager",
-            "version": "2.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/doctrine/event-manager.git",
-                "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32",
-                "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^8.1"
-            },
-            "conflict": {
-                "doctrine/common": "<2.9"
-            },
-            "require-dev": {
-                "doctrine/coding-standard": "^10",
-                "phpstan/phpstan": "^1.8.8",
-                "phpunit/phpunit": "^9.5",
-                "vimeo/psalm": "^4.28"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-4": {
-                    "Doctrine\\Common\\": "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": "Benjamin Eberlei",
-                    "email": "kontakt@beberlei.de"
-                },
-                {
-                    "name": "Jonathan Wage",
-                    "email": "jonwage@gmail.com"
-                },
-                {
-                    "name": "Johannes Schmitt",
-                    "email": "schmittjoh@gmail.com"
-                },
-                {
-                    "name": "Marco Pivetta",
-                    "email": "ocramius@gmail.com"
-                }
-            ],
-            "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
-            "homepage": "https://www.doctrine-project.org/projects/event-manager.html",
-            "keywords": [
-                "event",
-                "event dispatcher",
-                "event manager",
-                "event system",
-                "events"
-            ],
-            "support": {
-                "issues": "https://github.com/doctrine/event-manager/issues",
-                "source": "https://github.com/doctrine/event-manager/tree/2.0.0"
+                "source": "https://github.com/doctrine/deprecations/tree/1.1.3"
             },
-            "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%2Fevent-manager",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2022-10-12T20:59:15+00:00"
+            "time": "2024-01-30T19:34:25+00:00"
         },
         {
             "name": "doctrine/inflector",
-            "version": "2.0.6",
+            "version": "2.0.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/inflector.git",
-                "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024"
+                "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
-                "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
+                "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc",
+                "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.2 || ^8.0"
             },
             "require-dev": {
-                "doctrine/coding-standard": "^10",
+                "doctrine/coding-standard": "^11.0",
                 "phpstan/phpstan": "^1.8",
                 "phpstan/phpstan-phpunit": "^1.1",
                 "phpstan/phpstan-strict-rules": "^1.3",
                 "phpunit/phpunit": "^8.5 || ^9.5",
-                "vimeo/psalm": "^4.25"
+                "vimeo/psalm": "^4.25 || ^5.4"
             },
             "type": "library",
             "autoload": {
@@ -845,7 +736,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/inflector/issues",
-                "source": "https://github.com/doctrine/inflector/tree/2.0.6"
+                "source": "https://github.com/doctrine/inflector/tree/2.0.10"
             },
             "funding": [
                 {
@@ -861,31 +752,31 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-10-20T09:10:12+00:00"
+            "time": "2024-02-18T20:23:39+00:00"
         },
         {
             "name": "doctrine/lexer",
-            "version": "3.0.0",
+            "version": "3.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/lexer.git",
-                "reference": "84a527db05647743d50373e0ec53a152f2cde568"
+                "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568",
-                "reference": "84a527db05647743d50373e0ec53a152f2cde568",
+                "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+                "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
                 "shasum": ""
             },
             "require": {
                 "php": "^8.1"
             },
             "require-dev": {
-                "doctrine/coding-standard": "^10",
-                "phpstan/phpstan": "^1.9",
-                "phpunit/phpunit": "^9.5",
+                "doctrine/coding-standard": "^12",
+                "phpstan/phpstan": "^1.10",
+                "phpunit/phpunit": "^10.5",
                 "psalm/plugin-phpunit": "^0.18.3",
-                "vimeo/psalm": "^5.0"
+                "vimeo/psalm": "^5.21"
             },
             "type": "library",
             "autoload": {
@@ -922,7 +813,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/lexer/issues",
-                "source": "https://github.com/doctrine/lexer/tree/3.0.0"
+                "source": "https://github.com/doctrine/lexer/tree/3.0.1"
             },
             "funding": [
                 {
@@ -938,20 +829,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-12-15T16:57:16+00:00"
+            "time": "2024-02-05T11:56:58+00:00"
         },
         {
             "name": "dompdf/dompdf",
-            "version": "v2.0.3",
+            "version": "v2.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dompdf/dompdf.git",
-                "reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85"
+                "reference": "c20247574601700e1f7c8dab39310fca1964dc52"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dompdf/dompdf/zipball/e8d2d5e37e8b0b30f0732a011295ab80680d7e85",
-                "reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85",
+                "url": "https://api.github.com/repos/dompdf/dompdf/zipball/c20247574601700e1f7c8dab39310fca1964dc52",
+                "reference": "c20247574601700e1f7c8dab39310fca1964dc52",
                 "shasum": ""
             },
             "require": {
@@ -959,7 +850,7 @@
                 "ext-mbstring": "*",
                 "masterminds/html5": "^2.0",
                 "phenx/php-font-lib": ">=0.5.4 <1.0.0",
-                "phenx/php-svg-lib": ">=0.3.3 <1.0.0",
+                "phenx/php-svg-lib": ">=0.5.2 <1.0.0",
                 "php": "^7.1 || ^8.0"
             },
             "require-dev": {
@@ -998,22 +889,22 @@
             "homepage": "https://github.com/dompdf/dompdf",
             "support": {
                 "issues": "https://github.com/dompdf/dompdf/issues",
-                "source": "https://github.com/dompdf/dompdf/tree/v2.0.3"
+                "source": "https://github.com/dompdf/dompdf/tree/v2.0.8"
             },
-            "time": "2023-02-07T12:51:48+00:00"
+            "time": "2024-04-29T13:06:17+00:00"
         },
         {
             "name": "dragonmantank/cron-expression",
-            "version": "v3.3.2",
+            "version": "v3.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dragonmantank/cron-expression.git",
-                "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8"
+                "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8",
-                "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8",
+                "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
+                "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
                 "shasum": ""
             },
             "require": {
@@ -1053,7 +944,7 @@
             ],
             "support": {
                 "issues": "https://github.com/dragonmantank/cron-expression/issues",
-                "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2"
+                "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3"
             },
             "funding": [
                 {
@@ -1061,20 +952,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-09-10T18:51:20+00:00"
+            "time": "2023-08-10T19:36:49+00:00"
         },
         {
             "name": "egulias/email-validator",
-            "version": "4.0.1",
+            "version": "4.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/egulias/EmailValidator.git",
-                "reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff"
+                "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/3a85486b709bc384dae8eb78fb2eec649bdb64ff",
-                "reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff",
+                "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e",
+                "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e",
                 "shasum": ""
             },
             "require": {
@@ -1083,8 +974,8 @@
                 "symfony/polyfill-intl-idn": "^1.26"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.5.27",
-                "vimeo/psalm": "^4.30"
+                "phpunit/phpunit": "^10.2",
+                "vimeo/psalm": "^5.12"
             },
             "suggest": {
                 "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
@@ -1120,7 +1011,7 @@
             ],
             "support": {
                 "issues": "https://github.com/egulias/EmailValidator/issues",
-                "source": "https://github.com/egulias/EmailValidator/tree/4.0.1"
+                "source": "https://github.com/egulias/EmailValidator/tree/4.0.2"
             },
             "funding": [
                 {
@@ -1128,7 +1019,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-14T14:17:03+00:00"
+            "time": "2023-10-06T06:47:41+00:00"
         },
         {
             "name": "facade/ignition-contracts",
@@ -1183,23 +1074,86 @@
             },
             "time": "2020-10-16T08:27:54+00:00"
         },
+        {
+            "name": "firebase/php-jwt",
+            "version": "v6.10.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/firebase/php-jwt.git",
+                "reference": "500501c2ce893c824c801da135d02661199f60c5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5",
+                "reference": "500501c2ce893c824c801da135d02661199f60c5",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "guzzlehttp/guzzle": "^7.4",
+                "phpspec/prophecy-phpunit": "^2.0",
+                "phpunit/phpunit": "^9.5",
+                "psr/cache": "^2.0||^3.0",
+                "psr/http-client": "^1.0",
+                "psr/http-factory": "^1.0"
+            },
+            "suggest": {
+                "ext-sodium": "Support EdDSA (Ed25519) signatures",
+                "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Firebase\\JWT\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Neuman Vong",
+                    "email": "neuman+pear@twilio.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Anant Narayanan",
+                    "email": "anant@php.net",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
+            "homepage": "https://github.com/firebase/php-jwt",
+            "keywords": [
+                "jwt",
+                "php"
+            ],
+            "support": {
+                "issues": "https://github.com/firebase/php-jwt/issues",
+                "source": "https://github.com/firebase/php-jwt/tree/v6.10.1"
+            },
+            "time": "2024-05-18T18:05:11+00:00"
+        },
         {
             "name": "fruitcake/php-cors",
-            "version": "v1.2.0",
+            "version": "v1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/fruitcake/php-cors.git",
-                "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e"
+                "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e",
-                "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e",
+                "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b",
+                "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.4|^8.0",
-                "symfony/http-foundation": "^4.4|^5.4|^6"
+                "symfony/http-foundation": "^4.4|^5.4|^6|^7"
             },
             "require-dev": {
                 "phpstan/phpstan": "^1.4",
@@ -1209,7 +1163,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.1-dev"
+                    "dev-master": "1.2-dev"
                 }
             },
             "autoload": {
@@ -1240,7 +1194,7 @@
             ],
             "support": {
                 "issues": "https://github.com/fruitcake/php-cors/issues",
-                "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0"
+                "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0"
             },
             "funding": [
                 {
@@ -1252,28 +1206,28 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-02-20T15:07:15+00:00"
+            "time": "2023-10-12T05:21:21+00:00"
         },
         {
             "name": "graham-campbell/result-type",
-            "version": "v1.1.1",
+            "version": "v1.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/GrahamCampbell/Result-Type.git",
-                "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831"
+                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
-                "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
+                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
+                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.2.5 || ^8.0",
-                "phpoption/phpoption": "^1.9.1"
+                "phpoption/phpoption": "^1.9.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
             },
             "type": "library",
             "autoload": {
@@ -1302,7 +1256,7 @@
             ],
             "support": {
                 "issues": "https://github.com/GrahamCampbell/Result-Type/issues",
-                "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1"
+                "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
             },
             "funding": [
                 {
@@ -1314,26 +1268,26 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-25T20:23:15+00:00"
+            "time": "2024-07-20T21:45:45+00:00"
         },
         {
             "name": "guzzlehttp/guzzle",
-            "version": "7.5.1",
+            "version": "7.9.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/guzzle.git",
-                "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9"
+                "reference": "d281ed313b989f213357e3be1a179f02196ac99b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9",
-                "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b",
+                "reference": "d281ed313b989f213357e3be1a179f02196ac99b",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
-                "guzzlehttp/promises": "^1.5",
-                "guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
+                "guzzlehttp/promises": "^1.5.3 || ^2.0.3",
+                "guzzlehttp/psr7": "^2.7.0",
                 "php": "^7.2.5 || ^8.0",
                 "psr/http-client": "^1.0",
                 "symfony/deprecation-contracts": "^2.2 || ^3.0"
@@ -1342,10 +1296,11 @@
                 "psr/http-client-implementation": "1.0"
             },
             "require-dev": {
-                "bamarni/composer-bin-plugin": "^1.8.1",
+                "bamarni/composer-bin-plugin": "^1.8.2",
                 "ext-curl": "*",
-                "php-http/client-integration-tests": "^3.0",
-                "phpunit/phpunit": "^8.5.29 || ^9.5.23",
+                "guzzle/client-integration-tests": "3.0.2",
+                "php-http/message-factory": "^1.1",
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20",
                 "psr/log": "^1.1 || ^2.0 || ^3.0"
             },
             "suggest": {
@@ -1358,9 +1313,6 @@
                 "bamarni-bin": {
                     "bin-links": true,
                     "forward-command": false
-                },
-                "branch-alias": {
-                    "dev-master": "7.5-dev"
                 }
             },
             "autoload": {
@@ -1426,7 +1378,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/guzzle/issues",
-                "source": "https://github.com/guzzle/guzzle/tree/7.5.1"
+                "source": "https://github.com/guzzle/guzzle/tree/7.9.2"
             },
             "funding": [
                 {
@@ -1442,38 +1394,37 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-17T16:30:08+00:00"
+            "time": "2024-07-24T11:22:20+00:00"
         },
         {
             "name": "guzzlehttp/promises",
-            "version": "1.5.2",
+            "version": "2.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/promises.git",
-                "reference": "b94b2807d85443f9719887892882d0329d1e2598"
+                "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
-                "reference": "b94b2807d85443f9719887892882d0329d1e2598",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8",
+                "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.5"
+                "php": "^7.2.5 || ^8.0"
             },
             "require-dev": {
-                "symfony/phpunit-bridge": "^4.4 || ^5.1"
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20"
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-master": "1.5-dev"
+                "bamarni-bin": {
+                    "bin-links": true,
+                    "forward-command": false
                 }
             },
             "autoload": {
-                "files": [
-                    "src/functions_include.php"
-                ],
                 "psr-4": {
                     "GuzzleHttp\\Promise\\": "src/"
                 }
@@ -1510,7 +1461,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/promises/issues",
-                "source": "https://github.com/guzzle/promises/tree/1.5.2"
+                "source": "https://github.com/guzzle/promises/tree/2.0.3"
             },
             "funding": [
                 {
@@ -1526,20 +1477,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-08-28T14:55:35+00:00"
+            "time": "2024-07-18T10:29:17+00:00"
         },
         {
             "name": "guzzlehttp/psr7",
-            "version": "2.5.0",
+            "version": "2.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "b635f279edd83fc275f822a1188157ffea568ff6"
+                "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6",
-                "reference": "b635f279edd83fc275f822a1188157ffea568ff6",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
+                "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
                 "shasum": ""
             },
             "require": {
@@ -1553,9 +1504,9 @@
                 "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"
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "http-interop/http-factory-tests": "0.9.0",
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20"
             },
             "suggest": {
                 "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
@@ -1626,7 +1577,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.5.0"
+                "source": "https://github.com/guzzle/psr7/tree/2.7.0"
             },
             "funding": [
                 {
@@ -1642,34 +1593,36 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-17T16:11:26+00:00"
+            "time": "2024-07-18T11:15:46+00:00"
         },
         {
             "name": "guzzlehttp/uri-template",
-            "version": "v1.0.1",
+            "version": "v1.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/uri-template.git",
-                "reference": "b945d74a55a25a949158444f09ec0d3c120d69e2"
+                "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/uri-template/zipball/b945d74a55a25a949158444f09ec0d3c120d69e2",
-                "reference": "b945d74a55a25a949158444f09ec0d3c120d69e2",
+                "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c",
+                "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.2.5 || ^8.0",
-                "symfony/polyfill-php80": "^1.17"
+                "symfony/polyfill-php80": "^1.24"
             },
             "require-dev": {
-                "phpunit/phpunit": "^8.5.19 || ^9.5.8",
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "phpunit/phpunit": "^8.5.36 || ^9.6.15",
                 "uri-template/tests": "1.0.0"
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0-dev"
+                "bamarni-bin": {
+                    "bin-links": true,
+                    "forward-command": false
                 }
             },
             "autoload": {
@@ -1710,7 +1663,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/uri-template/issues",
-                "source": "https://github.com/guzzle/uri-template/tree/v1.0.1"
+                "source": "https://github.com/guzzle/uri-template/tree/v1.0.3"
             },
             "funding": [
                 {
@@ -1726,7 +1679,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-10-07T12:57:01+00:00"
+            "time": "2023-12-03T19:50:20+00:00"
         },
         {
             "name": "hidehalo/nanoid-php",
@@ -1787,29 +1740,29 @@
         },
         {
             "name": "kkomelin/laravel-translatable-string-exporter",
-            "version": "1.21.0",
+            "version": "1.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/kkomelin/laravel-translatable-string-exporter.git",
-                "reference": "51e6575223c345be359f5387ecaaf6bb7fc1de3d"
+                "reference": "0c6dbec4694a7e702830ecfc005d131cd5ffe402"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/kkomelin/laravel-translatable-string-exporter/zipball/51e6575223c345be359f5387ecaaf6bb7fc1de3d",
-                "reference": "51e6575223c345be359f5387ecaaf6bb7fc1de3d",
+                "url": "https://api.github.com/repos/kkomelin/laravel-translatable-string-exporter/zipball/0c6dbec4694a7e702830ecfc005d131cd5ffe402",
+                "reference": "0c6dbec4694a7e702830ecfc005d131cd5ffe402",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
-                "illuminate/support": "^8|^9|^10.0",
-                "illuminate/translation": "^8|^9|^10.0",
+                "illuminate/support": "^8|^9|^10.0|^11.0",
+                "illuminate/translation": "^8|^9|^10.0|^11.0",
                 "php": "^8.0",
-                "symfony/finder": "^5|^6"
+                "symfony/finder": "^5|^6|^7.0"
             },
             "require-dev": {
                 "nunomaduro/larastan": "^1.0|^2.0",
-                "orchestra/testbench": "^6.0|^7.0|^8.0",
-                "phpunit/phpunit": "^9.0"
+                "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0",
+                "phpunit/phpunit": "^9.0|^10.5"
             },
             "type": "library",
             "extra": {
@@ -1846,26 +1799,27 @@
             ],
             "support": {
                 "issues": "https://github.com/kkomelin/laravel-translatable-string-exporter/issues",
-                "source": "https://github.com/kkomelin/laravel-translatable-string-exporter/tree/1.21.0"
+                "source": "https://github.com/kkomelin/laravel-translatable-string-exporter/tree/1.22.0"
             },
-            "time": "2023-03-14T04:18:49+00:00"
+            "time": "2024-03-13T13:44:41+00:00"
         },
         {
             "name": "laravel/framework",
-            "version": "v9.52.7",
+            "version": "v11.18.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "675ea868fe36b18c8303e954aac540e6b1caa677"
+                "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/675ea868fe36b18c8303e954aac540e6b1caa677",
-                "reference": "675ea868fe36b18c8303e954aac540e6b1caa677",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/b19ba518c56852567e99fbae9321bc436c2cc5a8",
+                "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8",
                 "shasum": ""
             },
             "require": {
-                "brick/math": "^0.9.3|^0.10.2|^0.11",
+                "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12",
+                "composer-runtime-api": "^2.2",
                 "doctrine/inflector": "^2.0.5",
                 "dragonmantank/cron-expression": "^3.3.2",
                 "egulias/email-validator": "^3.2.1|^4.0",
@@ -1876,39 +1830,44 @@
                 "ext-openssl": "*",
                 "ext-session": "*",
                 "ext-tokenizer": "*",
-                "fruitcake/php-cors": "^1.2",
+                "fruitcake/php-cors": "^1.3",
+                "guzzlehttp/guzzle": "^7.8",
                 "guzzlehttp/uri-template": "^1.0",
-                "laravel/serializable-closure": "^1.2.2",
+                "laravel/prompts": "^0.1.18",
+                "laravel/serializable-closure": "^1.3",
                 "league/commonmark": "^2.2.1",
                 "league/flysystem": "^3.8.0",
-                "monolog/monolog": "^2.0",
-                "nesbot/carbon": "^2.62.1",
-                "nunomaduro/termwind": "^1.13",
-                "php": "^8.0.2",
+                "monolog/monolog": "^3.0",
+                "nesbot/carbon": "^2.72.2|^3.0",
+                "nunomaduro/termwind": "^2.0",
+                "php": "^8.2",
                 "psr/container": "^1.1.1|^2.0.1",
                 "psr/log": "^1.0|^2.0|^3.0",
                 "psr/simple-cache": "^1.0|^2.0|^3.0",
                 "ramsey/uuid": "^4.7",
-                "symfony/console": "^6.0.9",
-                "symfony/error-handler": "^6.0",
-                "symfony/finder": "^6.0",
-                "symfony/http-foundation": "^6.0",
-                "symfony/http-kernel": "^6.0",
-                "symfony/mailer": "^6.0",
-                "symfony/mime": "^6.0",
-                "symfony/process": "^6.0",
-                "symfony/routing": "^6.0",
-                "symfony/uid": "^6.0",
-                "symfony/var-dumper": "^6.0",
+                "symfony/console": "^7.0",
+                "symfony/error-handler": "^7.0",
+                "symfony/finder": "^7.0",
+                "symfony/http-foundation": "^7.0",
+                "symfony/http-kernel": "^7.0",
+                "symfony/mailer": "^7.0",
+                "symfony/mime": "^7.0",
+                "symfony/polyfill-php83": "^1.28",
+                "symfony/process": "^7.0",
+                "symfony/routing": "^7.0",
+                "symfony/uid": "^7.0",
+                "symfony/var-dumper": "^7.0",
                 "tijsverkoyen/css-to-inline-styles": "^2.2.5",
                 "vlucas/phpdotenv": "^5.4.1",
                 "voku/portable-ascii": "^2.0"
             },
             "conflict": {
+                "mockery/mockery": "1.6.8",
                 "tightenco/collect": "<5.5.33"
             },
             "provide": {
                 "psr/container-implementation": "1.1|2.0",
+                "psr/log-implementation": "1.0|2.0|3.0",
                 "psr/simple-cache-implementation": "1.0|2.0|3.0"
             },
             "replace": {
@@ -1935,6 +1894,7 @@
                 "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",
@@ -1943,35 +1903,35 @@
                 "illuminate/testing": "self.version",
                 "illuminate/translation": "self.version",
                 "illuminate/validation": "self.version",
-                "illuminate/view": "self.version"
+                "illuminate/view": "self.version",
+                "spatie/once": "*"
             },
             "require-dev": {
                 "ably/ably-php": "^1.0",
                 "aws/aws-sdk-php": "^3.235.5",
-                "doctrine/dbal": "^2.13.3|^3.1.4",
                 "ext-gmp": "*",
-                "fakerphp/faker": "^1.21",
-                "guzzlehttp/guzzle": "^7.5",
+                "fakerphp/faker": "^1.23",
                 "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": "^7.24",
-                "pda/pheanstalk": "^4.0",
-                "phpstan/phpdoc-parser": "^1.15",
-                "phpstan/phpstan": "^1.4.7",
-                "phpunit/phpunit": "^9.5.8",
-                "predis/predis": "^1.1.9|^2.0.2",
-                "symfony/cache": "^6.0",
-                "symfony/http-client": "^6.0"
+                "mockery/mockery": "^1.6",
+                "nyholm/psr7": "^1.2",
+                "orchestra/testbench-core": "^9.1.5",
+                "pda/pheanstalk": "^5.0",
+                "phpstan/phpstan": "^1.11.5",
+                "phpunit/phpunit": "^10.5|^11.0",
+                "predis/predis": "^2.0.2",
+                "resend/resend-php": "^0.10.0",
+                "symfony/cache": "^7.0",
+                "symfony/http-client": "^7.0",
+                "symfony/psr-http-message-bridge": "^7.0"
             },
             "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 (^2.13.3|^3.1.4).",
+                "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).",
                 "ext-apcu": "Required to use the APC cache driver.",
                 "ext-fileinfo": "Required to use the Filesystem class.",
                 "ext-ftp": "Required to use the Flysystem FTP driver.",
@@ -1980,40 +1940,41 @@
                 "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).",
+                "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).",
                 "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).",
                 "filp/whoops": "Required for friendly error pages in development (^2.14.3).",
-                "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).",
+                "mockery/mockery": "Required to use mocking (^1.6).",
                 "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).",
-                "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).",
-                "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8).",
-                "predis/predis": "Required to use the predis connector (^1.1.9|^2.0.2).",
+                "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).",
+                "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).",
+                "predis/predis": "Required to use the predis connector (^2.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.0).",
-                "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).",
-                "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.0).",
-                "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).",
-                "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).",
-                "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)."
+                "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).",
+                "symfony/cache": "Required to PSR-6 cache bridge (^7.0).",
+                "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).",
+                "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).",
+                "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).",
+                "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).",
+                "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)."
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "9.x-dev"
+                    "dev-master": "11.x-dev"
                 }
             },
             "autoload": {
                 "files": [
                     "src/Illuminate/Collections/helpers.php",
                     "src/Illuminate/Events/functions.php",
+                    "src/Illuminate/Filesystem/functions.php",
                     "src/Illuminate/Foundation/helpers.php",
                     "src/Illuminate/Support/helpers.php"
                 ],
@@ -2046,20 +2007,78 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-04-25T13:44:05+00:00"
+            "time": "2024-07-26T10:39:29+00:00"
+        },
+        {
+            "name": "laravel/prompts",
+            "version": "v0.1.24",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/prompts.git",
+                "reference": "409b0b4305273472f3754826e68f4edbd0150149"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/prompts/zipball/409b0b4305273472f3754826e68f4edbd0150149",
+                "reference": "409b0b4305273472f3754826e68f4edbd0150149",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "illuminate/collections": "^10.0|^11.0",
+                "php": "^8.1",
+                "symfony/console": "^6.2|^7.0"
+            },
+            "conflict": {
+                "illuminate/console": ">=10.17.0 <10.25.0",
+                "laravel/framework": ">=10.17.0 <10.25.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.5",
+                "pestphp/pest": "^2.3",
+                "phpstan/phpstan": "^1.11",
+                "phpstan/phpstan-mockery": "^1.1"
+            },
+            "suggest": {
+                "ext-pcntl": "Required for the spinner to be animated."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "0.1.x-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/helpers.php"
+                ],
+                "psr-4": {
+                    "Laravel\\Prompts\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Add beautiful and user-friendly forms to your command-line applications.",
+            "support": {
+                "issues": "https://github.com/laravel/prompts/issues",
+                "source": "https://github.com/laravel/prompts/tree/v0.1.24"
+            },
+            "time": "2024-06-17T13:58:22+00:00"
         },
         {
             "name": "laravel/serializable-closure",
-            "version": "v1.3.0",
+            "version": "v1.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/serializable-closure.git",
-                "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37"
+                "reference": "3dbf8a8e914634c48d389c1234552666b3d43754"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f23fe9d4e95255dacee1bf3525e0810d1a1b0f37",
-                "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37",
+                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754",
+                "reference": "3dbf8a8e914634c48d389c1234552666b3d43754",
                 "shasum": ""
             },
             "require": {
@@ -2106,35 +2125,38 @@
                 "issues": "https://github.com/laravel/serializable-closure/issues",
                 "source": "https://github.com/laravel/serializable-closure"
             },
-            "time": "2023-01-30T18:31:20+00:00"
+            "time": "2023-11-08T14:08:06+00:00"
         },
         {
             "name": "laravel/socialite",
-            "version": "v5.6.1",
+            "version": "v5.15.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/socialite.git",
-                "reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09"
+                "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/socialite/zipball/a14a177f2cc71d8add71e2b19e00800e83bdda09",
-                "reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09",
+                "url": "https://api.github.com/repos/laravel/socialite/zipball/cc02625f0bd1f95dc3688eb041cce0f1e709d029",
+                "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
+                "firebase/php-jwt": "^6.4",
                 "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",
+                "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
+                "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
+                "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
                 "league/oauth1-client": "^1.10.1",
-                "php": "^7.2|^8.0"
+                "php": "^7.2|^8.0",
+                "phpseclib/phpseclib": "^3.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"
+                "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0|^9.0",
+                "phpstan/phpstan": "^1.10",
+                "phpunit/phpunit": "^8.0|^9.3|^10.4"
             },
             "type": "library",
             "extra": {
@@ -2175,42 +2197,40 @@
                 "issues": "https://github.com/laravel/socialite/issues",
                 "source": "https://github.com/laravel/socialite"
             },
-            "time": "2023-01-20T15:42:35+00:00"
+            "time": "2024-06-28T20:09:34+00:00"
         },
         {
             "name": "laravel/tinker",
-            "version": "v2.8.1",
+            "version": "v2.9.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/tinker.git",
-                "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10"
+                "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/tinker/zipball/04a2d3bd0d650c0764f70bf49d1ee39393e4eb10",
-                "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10",
+                "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe",
+                "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe",
                 "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",
+                "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
+                "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
+                "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
                 "php": "^7.2.5|^8.0",
-                "psy/psysh": "^0.10.4|^0.11.1",
-                "symfony/var-dumper": "^4.3.4|^5.0|^6.0"
+                "psy/psysh": "^0.11.1|^0.12.0",
+                "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0"
             },
             "require-dev": {
                 "mockery/mockery": "~1.3.3|^1.4.2",
+                "phpstan/phpstan": "^1.10",
                 "phpunit/phpunit": "^8.5.8|^9.3.3"
             },
             "suggest": {
-                "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0)."
+                "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)."
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-master": "2.x-dev"
-                },
                 "laravel": {
                     "providers": [
                         "Laravel\\Tinker\\TinkerServiceProvider"
@@ -2241,38 +2261,40 @@
             ],
             "support": {
                 "issues": "https://github.com/laravel/tinker/issues",
-                "source": "https://github.com/laravel/tinker/tree/v2.8.1"
+                "source": "https://github.com/laravel/tinker/tree/v2.9.0"
             },
-            "time": "2023-02-15T16:40:09+00:00"
+            "time": "2024-01-04T16:10:04+00:00"
         },
         {
             "name": "laravel/ui",
-            "version": "v3.4.6",
+            "version": "v4.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/ui.git",
-                "reference": "65ec5c03f7fee2c8ecae785795b829a15be48c2c"
+                "reference": "c75396f63268c95b053c8e4814eb70e0875e9628"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/ui/zipball/65ec5c03f7fee2c8ecae785795b829a15be48c2c",
-                "reference": "65ec5c03f7fee2c8ecae785795b829a15be48c2c",
+                "url": "https://api.github.com/repos/laravel/ui/zipball/c75396f63268c95b053c8e4814eb70e0875e9628",
+                "reference": "c75396f63268c95b053c8e4814eb70e0875e9628",
                 "shasum": ""
             },
             "require": {
-                "illuminate/console": "^8.42|^9.0",
-                "illuminate/filesystem": "^8.42|^9.0",
-                "illuminate/support": "^8.82|^9.0",
-                "illuminate/validation": "^8.42|^9.0",
-                "php": "^7.3|^8.0"
+                "illuminate/console": "^9.21|^10.0|^11.0",
+                "illuminate/filesystem": "^9.21|^10.0|^11.0",
+                "illuminate/support": "^9.21|^10.0|^11.0",
+                "illuminate/validation": "^9.21|^10.0|^11.0",
+                "php": "^8.0",
+                "symfony/console": "^6.0|^7.0"
             },
             "require-dev": {
-                "orchestra/testbench": "^6.23|^7.0"
+                "orchestra/testbench": "^7.35|^8.15|^9.0",
+                "phpunit/phpunit": "^9.3|^10.4|^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.x-dev"
+                    "dev-master": "4.x-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -2302,34 +2324,33 @@
                 "ui"
             ],
             "support": {
-                "source": "https://github.com/laravel/ui/tree/v3.4.6"
+                "source": "https://github.com/laravel/ui/tree/v4.5.2"
             },
-            "time": "2022-05-20T13:38:08+00:00"
+            "time": "2024-05-08T18:07:10+00:00"
         },
         {
             "name": "laraveldaily/laravel-invoices",
-            "version": "3.1.0",
+            "version": "4.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/LaravelDaily/laravel-invoices.git",
-                "reference": "7f3f2fd2042ad7ca228b506059a1e8535de46e05"
+                "reference": "d9fa7eca22a7836fb9b09ee7fc2a97b4dfd7b228"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/LaravelDaily/laravel-invoices/zipball/7f3f2fd2042ad7ca228b506059a1e8535de46e05",
-                "reference": "7f3f2fd2042ad7ca228b506059a1e8535de46e05",
+                "url": "https://api.github.com/repos/LaravelDaily/laravel-invoices/zipball/d9fa7eca22a7836fb9b09ee7fc2a97b4dfd7b228",
+                "reference": "d9fa7eca22a7836fb9b09ee7fc2a97b4dfd7b228",
                 "shasum": ""
             },
             "require": {
                 "barryvdh/laravel-dompdf": "^v2.0",
-                "illuminate/http": "^5.5|^6|^7|^8|^9|^10",
-                "illuminate/support": "^5.5|^6|^7|^8|^9|^10",
-                "php": "^7.3|^8.0",
-                "symfony/http-foundation": "^4.0|^5.0|^6.0"
+                "illuminate/http": "^10|^11",
+                "illuminate/support": "^10|^11",
+                "php": ">=8.2",
+                "symfony/http-foundation": "^6|^7"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3",
-                "symfony/var-dumper": "^5.0"
+                "phpunit/phpunit": "^10.1"
             },
             "type": "library",
             "extra": {
@@ -2369,22 +2390,22 @@
             ],
             "support": {
                 "issues": "https://github.com/LaravelDaily/laravel-invoices/issues",
-                "source": "https://github.com/LaravelDaily/laravel-invoices/tree/3.1.0"
+                "source": "https://github.com/LaravelDaily/laravel-invoices/tree/4.0.0"
             },
-            "time": "2023-02-15T12:35:38+00:00"
+            "time": "2024-03-14T08:31:01+00:00"
         },
         {
             "name": "league/commonmark",
-            "version": "2.4.0",
+            "version": "2.5.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/commonmark.git",
-                "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048"
+                "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
-                "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c",
+                "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c",
                 "shasum": ""
             },
             "require": {
@@ -2397,8 +2418,8 @@
             },
             "require-dev": {
                 "cebe/markdown": "^1.0",
-                "commonmark/cmark": "0.30.0",
-                "commonmark/commonmark.js": "0.30.0",
+                "commonmark/cmark": "0.31.0",
+                "commonmark/commonmark.js": "0.31.0",
                 "composer/package-versions-deprecated": "^1.8",
                 "embed/embed": "^4.4",
                 "erusev/parsedown": "^1.0",
@@ -2407,10 +2428,10 @@
                 "michelf/php-markdown": "^1.4 || ^2.0",
                 "nyholm/psr7": "^1.5",
                 "phpstan/phpstan": "^1.8.2",
-                "phpunit/phpunit": "^9.5.21",
+                "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
                 "scrutinizer/ocular": "^1.8.1",
-                "symfony/finder": "^5.3 | ^6.0",
-                "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
+                "symfony/finder": "^5.3 | ^6.0 || ^7.0",
+                "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0",
                 "unleashedtech/php-coding-standard": "^3.1.1",
                 "vimeo/psalm": "^4.24.0 || ^5.0.0"
             },
@@ -2420,7 +2441,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "2.5-dev"
+                    "dev-main": "2.6-dev"
                 }
             },
             "autoload": {
@@ -2477,7 +2498,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-24T15:16:10+00:00"
+            "time": "2024-07-24T12:52:09+00:00"
         },
         {
             "name": "league/config",
@@ -2563,23 +2584,26 @@
         },
         {
             "name": "league/flysystem",
-            "version": "3.14.0",
+            "version": "3.28.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem.git",
-                "reference": "e2a279d7f47d9098e479e8b21f7fb8b8de230158"
+                "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e2a279d7f47d9098e479e8b21f7fb8b8de230158",
-                "reference": "e2a279d7f47d9098e479e8b21f7fb8b8de230158",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c",
+                "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c",
                 "shasum": ""
             },
             "require": {
+                "league/flysystem-local": "^3.0.0",
                 "league/mime-type-detection": "^1.0.0",
                 "php": "^8.0.2"
             },
             "conflict": {
+                "async-aws/core": "<1.19.0",
+                "async-aws/s3": "<1.14.0",
                 "aws/aws-sdk-php": "3.209.31 || 3.210.0",
                 "guzzlehttp/guzzle": "<7.0",
                 "guzzlehttp/ringphp": "<1.1.1",
@@ -2587,20 +2611,23 @@
                 "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",
+                "async-aws/s3": "^1.5 || ^2.0",
+                "async-aws/simple-s3": "^1.1 || ^2.0",
+                "aws/aws-sdk-php": "^3.295.10",
                 "composer/semver": "^3.0",
                 "ext-fileinfo": "*",
                 "ext-ftp": "*",
+                "ext-mongodb": "^1.3",
                 "ext-zip": "*",
                 "friendsofphp/php-cs-fixer": "^3.5",
                 "google/cloud-storage": "^1.23",
+                "guzzlehttp/psr7": "^2.6",
                 "microsoft/azure-storage-blob": "^1.1",
-                "phpseclib/phpseclib": "^3.0.14",
-                "phpstan/phpstan": "^0.12.26",
-                "phpunit/phpunit": "^9.5.11",
-                "sabre/dav": "^4.3.1"
+                "mongodb/mongodb": "^1.2",
+                "phpseclib/phpseclib": "^3.0.36",
+                "phpstan/phpstan": "^1.10",
+                "phpunit/phpunit": "^9.5.11|^10.0",
+                "sabre/dav": "^4.6.0"
             },
             "type": "library",
             "autoload": {
@@ -2634,48 +2661,89 @@
             ],
             "support": {
                 "issues": "https://github.com/thephpleague/flysystem/issues",
-                "source": "https://github.com/thephpleague/flysystem/tree/3.14.0"
+                "source": "https://github.com/thephpleague/flysystem/tree/3.28.0"
             },
-            "funding": [
-                {
-                    "url": "https://ecologi.com/frankdejonge",
-                    "type": "custom"
-                },
+            "time": "2024-05-22T10:09:12+00:00"
+        },
+        {
+            "name": "league/flysystem-aws-s3-v3",
+            "version": "3.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
+                "reference": "22071ef1604bc776f5ff2468ac27a752514665c8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/22071ef1604bc776f5ff2468ac27a752514665c8",
+                "reference": "22071ef1604bc776f5ff2468ac27a752514665c8",
+                "shasum": ""
+            },
+            "require": {
+                "aws/aws-sdk-php": "^3.295.10",
+                "league/flysystem": "^3.10.0",
+                "league/mime-type-detection": "^1.0.0",
+                "php": "^8.0.2"
+            },
+            "conflict": {
+                "guzzlehttp/guzzle": "<7.0",
+                "guzzlehttp/ringphp": "<1.1.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "League\\Flysystem\\AwsS3V3\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://github.com/frankdejonge",
-                    "type": "github"
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
                 }
             ],
-            "time": "2023-04-11T18:11:47+00:00"
+            "description": "AWS S3 filesystem adapter for Flysystem.",
+            "keywords": [
+                "Flysystem",
+                "aws",
+                "file",
+                "files",
+                "filesystem",
+                "s3",
+                "storage"
+            ],
+            "support": {
+                "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.28.0"
+            },
+            "time": "2024-05-06T20:05:52+00:00"
         },
         {
-            "name": "league/flysystem-aws-s3-v3",
-            "version": "3.13.0",
+            "name": "league/flysystem-local",
+            "version": "3.28.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
-                "reference": "8e04cbb403d4dfd5b73a2f8685f1df395bd177eb"
+                "url": "https://github.com/thephpleague/flysystem-local.git",
+                "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/8e04cbb403d4dfd5b73a2f8685f1df395bd177eb",
-                "reference": "8e04cbb403d4dfd5b73a2f8685f1df395bd177eb",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/13f22ea8be526ea58c2ddff9e158ef7c296e4f40",
+                "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40",
                 "shasum": ""
             },
             "require": {
-                "aws/aws-sdk-php": "^3.220.0",
-                "league/flysystem": "^3.10.0",
+                "ext-fileinfo": "*",
+                "league/flysystem": "^3.0.0",
                 "league/mime-type-detection": "^1.0.0",
                 "php": "^8.0.2"
             },
-            "conflict": {
-                "guzzlehttp/guzzle": "<7.0",
-                "guzzlehttp/ringphp": "<1.1.1"
-            },
             "type": "library",
             "autoload": {
                 "psr-4": {
-                    "League\\Flysystem\\AwsS3V3\\": ""
+                    "League\\Flysystem\\Local\\": ""
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2688,54 +2756,41 @@
                     "email": "info@frankdejonge.nl"
                 }
             ],
-            "description": "AWS S3 filesystem adapter for Flysystem.",
+            "description": "Local filesystem adapter for Flysystem.",
             "keywords": [
                 "Flysystem",
-                "aws",
                 "file",
                 "files",
                 "filesystem",
-                "s3",
-                "storage"
+                "local"
             ],
             "support": {
-                "issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues",
-                "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.13.0"
+                "source": "https://github.com/thephpleague/flysystem-local/tree/3.28.0"
             },
-            "funding": [
-                {
-                    "url": "https://ecologi.com/frankdejonge",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/frankdejonge",
-                    "type": "github"
-                }
-            ],
-            "time": "2023-03-16T14:29:01+00:00"
+            "time": "2024-05-06T20:05:52+00:00"
         },
         {
             "name": "league/mime-type-detection",
-            "version": "1.11.0",
+            "version": "1.15.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/mime-type-detection.git",
-                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
+                "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
-                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
+                "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
                 "shasum": ""
             },
             "require": {
                 "ext-fileinfo": "*",
-                "php": "^7.2 || ^8.0"
+                "php": "^7.4 || ^8.0"
             },
             "require-dev": {
                 "friendsofphp/php-cs-fixer": "^3.2",
                 "phpstan/phpstan": "^0.12.68",
-                "phpunit/phpunit": "^8.5.8 || ^9.3"
+                "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0"
             },
             "type": "library",
             "autoload": {
@@ -2756,7 +2811,7 @@
             "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"
+                "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0"
             },
             "funding": [
                 {
@@ -2768,7 +2823,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-04-17T13:12:02+00:00"
+            "time": "2024-01-28T23:22:08+00:00"
         },
         {
             "name": "league/oauth1-client",
@@ -2848,16 +2903,16 @@
         },
         {
             "name": "masterminds/html5",
-            "version": "2.8.0",
+            "version": "2.9.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Masterminds/html5-php.git",
-                "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3"
+                "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3",
-                "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3",
+                "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
+                "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
                 "shasum": ""
             },
             "require": {
@@ -2865,7 +2920,7 @@
                 "php": ">=5.3.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8"
+                "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
             },
             "type": "library",
             "extra": {
@@ -2909,48 +2964,47 @@
             ],
             "support": {
                 "issues": "https://github.com/Masterminds/html5-php/issues",
-                "source": "https://github.com/Masterminds/html5-php/tree/2.8.0"
+                "source": "https://github.com/Masterminds/html5-php/tree/2.9.0"
             },
-            "time": "2023-04-26T07:27:39+00:00"
+            "time": "2024-03-31T07:05:07+00:00"
         },
         {
             "name": "monolog/monolog",
-            "version": "2.9.1",
+            "version": "3.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/monolog.git",
-                "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1"
+                "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1",
-                "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8",
+                "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.2",
-                "psr/log": "^1.0.1 || ^2.0 || ^3.0"
+                "php": ">=8.1",
+                "psr/log": "^2.0 || ^3.0"
             },
             "provide": {
-                "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
+                "psr/log-implementation": "3.0.0"
             },
             "require-dev": {
-                "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+                "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",
+                "graylog2/gelf-php": "^1.4.2 || ^2.0",
+                "guzzlehttp/guzzle": "^7.4.5",
                 "guzzlehttp/psr7": "^2.2",
                 "mongodb/mongodb": "^1.8",
                 "php-amqplib/php-amqplib": "~2.4 || ^3",
-                "phpspec/prophecy": "^1.15",
-                "phpstan/phpstan": "^0.12.91",
-                "phpunit/phpunit": "^8.5.14",
-                "predis/predis": "^1.1 || ^2.0",
-                "rollbar/rollbar": "^1.3 || ^2 || ^3",
+                "phpstan/phpstan": "^1.9",
+                "phpstan/phpstan-deprecation-rules": "^1.0",
+                "phpstan/phpstan-strict-rules": "^1.4",
+                "phpunit/phpunit": "^10.5.17",
+                "predis/predis": "^1.1 || ^2",
                 "ruflin/elastica": "^7",
-                "swiftmailer/swiftmailer": "^5.3|^6.0",
                 "symfony/mailer": "^5.4 || ^6",
                 "symfony/mime": "^5.4 || ^6"
             },
@@ -2973,7 +3027,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "2.x-dev"
+                    "dev-main": "3.x-dev"
                 }
             },
             "autoload": {
@@ -3001,7 +3055,7 @@
             ],
             "support": {
                 "issues": "https://github.com/Seldaek/monolog/issues",
-                "source": "https://github.com/Seldaek/monolog/tree/2.9.1"
+                "source": "https://github.com/Seldaek/monolog/tree/3.7.0"
             },
             "funding": [
                 {
@@ -3013,29 +3067,29 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-06T13:44:46+00:00"
+            "time": "2024-06-28T09:40:51+00:00"
         },
         {
             "name": "mtdowling/jmespath.php",
-            "version": "2.6.1",
+            "version": "2.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/jmespath/jmespath.php.git",
-                "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb"
+                "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb",
-                "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb",
+                "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/bbb69a935c2cbb0c03d7f481a238027430f6440b",
+                "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.4 || ^7.0 || ^8.0",
+                "php": "^7.2.5 || ^8.0",
                 "symfony/polyfill-mbstring": "^1.17"
             },
             "require-dev": {
-                "composer/xdebug-handler": "^1.4 || ^2.0",
-                "phpunit/phpunit": "^4.8.36 || ^7.5.15"
+                "composer/xdebug-handler": "^3.0.3",
+                "phpunit/phpunit": "^8.5.33"
             },
             "bin": [
                 "bin/jp.php"
@@ -3043,7 +3097,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "2.7-dev"
                 }
             },
             "autoload": {
@@ -3059,6 +3113,11 @@
                 "MIT"
             ],
             "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
                 {
                     "name": "Michael Dowling",
                     "email": "mtdowling@gmail.com",
@@ -3072,43 +3131,47 @@
             ],
             "support": {
                 "issues": "https://github.com/jmespath/jmespath.php/issues",
-                "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1"
+                "source": "https://github.com/jmespath/jmespath.php/tree/2.7.0"
             },
-            "time": "2021-06-14T00:11:39+00:00"
+            "time": "2023-08-25T10:54:48+00:00"
         },
         {
             "name": "nesbot/carbon",
-            "version": "2.66.0",
+            "version": "3.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "496712849902241f04902033b0441b269effe001"
+                "reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/496712849902241f04902033b0441b269effe001",
-                "reference": "496712849902241f04902033b0441b269effe001",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cb4374784c87d0a0294e8513a52eb63c0aff3139",
+                "reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139",
                 "shasum": ""
             },
             "require": {
+                "carbonphp/carbon-doctrine-types": "*",
                 "ext-json": "*",
-                "php": "^7.1.8 || ^8.0",
+                "php": "^8.1",
+                "psr/clock": "^1.0",
+                "symfony/clock": "^6.3 || ^7.0",
                 "symfony/polyfill-mbstring": "^1.0",
-                "symfony/polyfill-php80": "^1.16",
-                "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0"
+                "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0"
+            },
+            "provide": {
+                "psr/clock-implementation": "1.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"
+                "doctrine/dbal": "^3.6.3 || ^4.0",
+                "doctrine/orm": "^2.15.2 || ^3.0",
+                "friendsofphp/php-cs-fixer": "^3.57.2",
+                "kylekatarnls/multi-tester": "^2.5.3",
+                "ondrejmirtes/better-reflection": "^6.25.0.4",
+                "phpmd/phpmd": "^2.15.0",
+                "phpstan/extension-installer": "^1.3.1",
+                "phpstan/phpstan": "^1.11.2",
+                "phpunit/phpunit": "^10.5.20",
+                "squizlabs/php_codesniffer": "^3.9.0"
             },
             "bin": [
                 "bin/carbon"
@@ -3116,8 +3179,8 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-3.x": "3.x-dev",
-                    "dev-master": "2.x-dev"
+                    "dev-master": "3.x-dev",
+                    "dev-2.x": "2.x-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -3176,35 +3239,35 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-29T18:53:47+00:00"
+            "time": "2024-07-16T22:29:20+00:00"
         },
         {
             "name": "nette/schema",
-            "version": "v1.2.3",
+            "version": "v1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nette/schema.git",
-                "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f"
+                "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
-                "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
+                "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
+                "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
                 "shasum": ""
             },
             "require": {
-                "nette/utils": "^2.5.7 || ^3.1.5 ||  ^4.0",
-                "php": ">=7.1 <8.3"
+                "nette/utils": "^4.0",
+                "php": "8.1 - 8.3"
             },
             "require-dev": {
-                "nette/tester": "^2.3 || ^2.4",
+                "nette/tester": "^2.4",
                 "phpstan/phpstan-nette": "^1.0",
-                "tracy/tracy": "^2.7"
+                "tracy/tracy": "^2.8"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.3-dev"
                 }
             },
             "autoload": {
@@ -3236,26 +3299,26 @@
             ],
             "support": {
                 "issues": "https://github.com/nette/schema/issues",
-                "source": "https://github.com/nette/schema/tree/v1.2.3"
+                "source": "https://github.com/nette/schema/tree/v1.3.0"
             },
-            "time": "2022-10-13T01:24:26+00:00"
+            "time": "2023-12-11T11:54:22+00:00"
         },
         {
             "name": "nette/utils",
-            "version": "v4.0.0",
+            "version": "v4.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nette/utils.git",
-                "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e"
+                "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e",
-                "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e",
+                "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
+                "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.0 <8.3"
+                "php": ">=8.0 <8.4"
             },
             "conflict": {
                 "nette/finder": "<3",
@@ -3263,7 +3326,7 @@
             },
             "require-dev": {
                 "jetbrains/phpstorm-attributes": "dev-master",
-                "nette/tester": "^2.4",
+                "nette/tester": "^2.5",
                 "phpstan/phpstan": "^1.0",
                 "tracy/tracy": "^2.9"
             },
@@ -3273,8 +3336,7 @@
                 "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"
+                "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()"
             },
             "type": "library",
             "extra": {
@@ -3323,31 +3385,33 @@
             ],
             "support": {
                 "issues": "https://github.com/nette/utils/issues",
-                "source": "https://github.com/nette/utils/tree/v4.0.0"
+                "source": "https://github.com/nette/utils/tree/v4.0.4"
             },
-            "time": "2023-02-02T10:41:53+00:00"
+            "time": "2024-01-17T16:50:36+00:00"
         },
         {
             "name": "nikic/php-parser",
-            "version": "v4.15.4",
+            "version": "v5.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290"
+                "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
-                "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1",
+                "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1",
                 "shasum": ""
             },
             "require": {
+                "ext-ctype": "*",
+                "ext-json": "*",
                 "ext-tokenizer": "*",
-                "php": ">=7.0"
+                "php": ">=7.4"
             },
             "require-dev": {
                 "ircmaxell/php-yacc": "^0.0.7",
-                "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+                "phpunit/phpunit": "^9.0"
             },
             "bin": [
                 "bin/php-parse"
@@ -3355,7 +3419,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.9-dev"
+                    "dev-master": "5.0-dev"
                 }
             },
             "autoload": {
@@ -3379,39 +3443,38 @@
             ],
             "support": {
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
-                "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4"
+                "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0"
             },
-            "time": "2023-03-05T19:49:14+00:00"
+            "time": "2024-07-01T20:03:41+00:00"
         },
         {
             "name": "nunomaduro/termwind",
-            "version": "v1.15.1",
+            "version": "v2.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nunomaduro/termwind.git",
-                "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc"
+                "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/8ab0b32c8caa4a2e09700ea32925441385e4a5dc",
-                "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc",
+                "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/58c4c58cf23df7f498daeb97092e34f5259feb6a",
+                "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a",
                 "shasum": ""
             },
             "require": {
                 "ext-mbstring": "*",
-                "php": "^8.0",
-                "symfony/console": "^5.3.0|^6.0.0"
+                "php": "^8.2",
+                "symfony/console": "^7.0.4"
             },
             "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",
+                "ergebnis/phpstan-rules": "^2.2.0",
+                "illuminate/console": "^11.0.0",
+                "laravel/pint": "^1.14.0",
+                "mockery/mockery": "^1.6.7",
+                "pestphp/pest": "^2.34.1",
+                "phpstan/phpstan": "^1.10.59",
+                "phpstan/phpstan-strict-rules": "^1.5.2",
+                "symfony/var-dumper": "^7.0.4",
                 "thecodingmachine/phpstan-strict-rules": "^1.0.0"
             },
             "type": "library",
@@ -3420,6 +3483,9 @@
                     "providers": [
                         "Termwind\\Laravel\\TermwindServiceProvider"
                     ]
+                },
+                "branch-alias": {
+                    "dev-2.x": "2.x-dev"
                 }
             },
             "autoload": {
@@ -3451,7 +3517,7 @@
             ],
             "support": {
                 "issues": "https://github.com/nunomaduro/termwind/issues",
-                "source": "https://github.com/nunomaduro/termwind/tree/v1.15.1"
+                "source": "https://github.com/nunomaduro/termwind/tree/v2.0.1"
             },
             "funding": [
                 {
@@ -3467,7 +3533,74 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-08T01:06:31+00:00"
+            "time": "2024-03-06T16:17:14+00:00"
+        },
+        {
+            "name": "paragonie/constant_time_encoding",
+            "version": "v3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/paragonie/constant_time_encoding.git",
+                "reference": "df1e7fde177501eee2037dd159cf04f5f301a512"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512",
+                "reference": "df1e7fde177501eee2037dd159cf04f5f301a512",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9",
+                "vimeo/psalm": "^4|^5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "ParagonIE\\ConstantTime\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Paragon Initiative Enterprises",
+                    "email": "security@paragonie.com",
+                    "homepage": "https://paragonie.com",
+                    "role": "Maintainer"
+                },
+                {
+                    "name": "Steve 'Sc00bz' Thomas",
+                    "email": "steve@tobtu.com",
+                    "homepage": "https://www.tobtu.com",
+                    "role": "Original Developer"
+                }
+            ],
+            "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+            "keywords": [
+                "base16",
+                "base32",
+                "base32_decode",
+                "base32_encode",
+                "base64",
+                "base64_decode",
+                "base64_encode",
+                "bin2hex",
+                "encoding",
+                "hex",
+                "hex2bin",
+                "rfc4648"
+            ],
+            "support": {
+                "email": "info@paragonie.com",
+                "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+                "source": "https://github.com/paragonie/constant_time_encoding"
+            },
+            "time": "2024-05-08T12:36:18+00:00"
         },
         {
             "name": "paragonie/random_compat",
@@ -3615,79 +3748,25 @@
             },
             "time": "2021-09-14T21:35:26+00:00"
         },
-        {
-            "name": "paypal/rest-api-sdk-php",
-            "version": "1.14.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/paypal/PayPal-PHP-SDK.git",
-                "reference": "72e2f2466975bf128a31e02b15110180f059fc04"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/paypal/PayPal-PHP-SDK/zipball/72e2f2466975bf128a31e02b15110180f059fc04",
-                "reference": "72e2f2466975bf128a31e02b15110180f059fc04",
-                "shasum": ""
-            },
-            "require": {
-                "ext-curl": "*",
-                "ext-json": "*",
-                "php": ">=5.3.0",
-                "psr/log": "^1.0.0"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.8.35"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "PayPal": "lib/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "Apache-2.0"
-            ],
-            "authors": [
-                {
-                    "name": "PayPal",
-                    "homepage": "https://github.com/paypal/rest-api-sdk-php/contributors"
-                }
-            ],
-            "description": "PayPal's PHP SDK for REST APIs",
-            "homepage": "http://paypal.github.io/PayPal-PHP-SDK/",
-            "keywords": [
-                "payments",
-                "paypal",
-                "rest",
-                "sdk"
-            ],
-            "support": {
-                "issues": "https://github.com/paypal/PayPal-PHP-SDK/issues",
-                "source": "https://github.com/paypal/PayPal-PHP-SDK/tree/master"
-            },
-            "abandoned": true,
-            "time": "2019-01-04T20:04:25+00:00"
-        },
         {
             "name": "phenx/php-font-lib",
-            "version": "0.5.4",
+            "version": "0.5.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dompdf/php-font-lib.git",
-                "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4"
+                "reference": "a1681e9793040740a405ac5b189275059e2a9863"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/dd448ad1ce34c63d09baccd05415e361300c35b4",
-                "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4",
+                "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a1681e9793040740a405ac5b189275059e2a9863",
+                "reference": "a1681e9793040740a405ac5b189275059e2a9863",
                 "shasum": ""
             },
             "require": {
                 "ext-mbstring": "*"
             },
             "require-dev": {
-                "symfony/phpunit-bridge": "^3 || ^4 || ^5"
+                "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
             },
             "type": "library",
             "autoload": {
@@ -3697,7 +3776,7 @@
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "LGPL-3.0"
+                "LGPL-2.1-or-later"
             ],
             "authors": [
                 {
@@ -3709,22 +3788,22 @@
             "homepage": "https://github.com/PhenX/php-font-lib",
             "support": {
                 "issues": "https://github.com/dompdf/php-font-lib/issues",
-                "source": "https://github.com/dompdf/php-font-lib/tree/0.5.4"
+                "source": "https://github.com/dompdf/php-font-lib/tree/0.5.6"
             },
-            "time": "2021-12-17T19:44:54+00:00"
+            "time": "2024-01-29T14:45:26+00:00"
         },
         {
             "name": "phenx/php-svg-lib",
-            "version": "0.5.0",
+            "version": "0.5.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dompdf/php-svg-lib.git",
-                "reference": "76876c6cf3080bcb6f249d7d59705108166a6685"
+                "reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/76876c6cf3080bcb6f249d7d59705108166a6685",
-                "reference": "76876c6cf3080bcb6f249d7d59705108166a6685",
+                "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/46b25da81613a9cf43c83b2a8c2c1bdab27df691",
+                "reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691",
                 "shasum": ""
             },
             "require": {
@@ -3743,7 +3822,7 @@
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "LGPL-3.0"
+                "LGPL-3.0-or-later"
             ],
             "authors": [
                 {
@@ -3755,9 +3834,9 @@
             "homepage": "https://github.com/PhenX/php-svg-lib",
             "support": {
                 "issues": "https://github.com/dompdf/php-svg-lib/issues",
-                "source": "https://github.com/dompdf/php-svg-lib/tree/0.5.0"
+                "source": "https://github.com/dompdf/php-svg-lib/tree/0.5.4"
             },
-            "time": "2022-09-06T12:16:56+00:00"
+            "time": "2024-04-08T12:52:34+00:00"
         },
         {
             "name": "phpdocumentor/reflection-common",
@@ -3814,21 +3893,21 @@
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "1.7.1",
+            "version": "1.8.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "dfc078e8af9c99210337325ff5aa152872c98714"
+                "reference": "153ae662783729388a584b4361f2545e4d841e3c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714",
-                "reference": "dfc078e8af9c99210337325ff5aa152872c98714",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
+                "reference": "153ae662783729388a584b4361f2545e4d841e3c",
                 "shasum": ""
             },
             "require": {
                 "doctrine/deprecations": "^1.0",
-                "php": "^7.4 || ^8.0",
+                "php": "^7.3 || ^8.0",
                 "phpdocumentor/reflection-common": "^2.0",
                 "phpstan/phpdoc-parser": "^1.13"
             },
@@ -3866,22 +3945,22 @@
             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
             "support": {
                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.1"
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
             },
-            "time": "2023-03-27T19:02:04+00:00"
+            "time": "2024-02-23T11:10:43+00:00"
         },
         {
             "name": "phpoption/phpoption",
-            "version": "1.9.1",
+            "version": "1.9.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/schmittjoh/php-option.git",
-                "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e"
+                "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e",
-                "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e",
+                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54",
+                "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54",
                 "shasum": ""
             },
             "require": {
@@ -3889,13 +3968,13 @@
             },
             "require-dev": {
                 "bamarni/composer-bin-plugin": "^1.8.2",
-                "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
             },
             "type": "library",
             "extra": {
                 "bamarni-bin": {
                     "bin-links": true,
-                    "forward-command": true
+                    "forward-command": false
                 },
                 "branch-alias": {
                     "dev-master": "1.9-dev"
@@ -3931,7 +4010,7 @@
             ],
             "support": {
                 "issues": "https://github.com/schmittjoh/php-option/issues",
-                "source": "https://github.com/schmittjoh/php-option/tree/1.9.1"
+                "source": "https://github.com/schmittjoh/php-option/tree/1.9.3"
             },
             "funding": [
                 {
@@ -3943,26 +4022,138 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-25T19:38:58+00:00"
+            "time": "2024-07-20T21:41:07+00:00"
+        },
+        {
+            "name": "phpseclib/phpseclib",
+            "version": "3.0.39",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpseclib/phpseclib.git",
+                "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/211ebc399c6e73c225a018435fe5ae209d1d1485",
+                "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485",
+                "shasum": ""
+            },
+            "require": {
+                "paragonie/constant_time_encoding": "^1|^2|^3",
+                "paragonie/random_compat": "^1.4|^2.0|^9.99.99",
+                "php": ">=5.6.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "*"
+            },
+            "suggest": {
+                "ext-dom": "Install the DOM extension to load XML formatted public keys.",
+                "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+                "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+                "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+                "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "phpseclib/bootstrap.php"
+                ],
+                "psr-4": {
+                    "phpseclib3\\": "phpseclib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jim Wigginton",
+                    "email": "terrafrost@php.net",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Patrick Monnerat",
+                    "email": "pm@datasphere.ch",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Andreas Fischer",
+                    "email": "bantu@phpbb.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Hans-Jürgen Petrich",
+                    "email": "petrich@tronic-media.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+            "homepage": "http://phpseclib.sourceforge.net",
+            "keywords": [
+                "BigInteger",
+                "aes",
+                "asn.1",
+                "asn1",
+                "blowfish",
+                "crypto",
+                "cryptography",
+                "encryption",
+                "rsa",
+                "security",
+                "sftp",
+                "signature",
+                "signing",
+                "ssh",
+                "twofish",
+                "x.509",
+                "x509"
+            ],
+            "support": {
+                "issues": "https://github.com/phpseclib/phpseclib/issues",
+                "source": "https://github.com/phpseclib/phpseclib/tree/3.0.39"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/terrafrost",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/phpseclib",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-06-24T06:27:33+00:00"
         },
         {
             "name": "phpstan/phpdoc-parser",
-            "version": "1.20.3",
+            "version": "1.29.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpdoc-parser.git",
-                "reference": "6c04009f6cae6eda2f040745b6b846080ef069c2"
+                "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6c04009f6cae6eda2f040745b6b846080ef069c2",
-                "reference": "6c04009f6cae6eda2f040745b6b846080ef069c2",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4",
+                "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.2 || ^8.0"
             },
             "require-dev": {
+                "doctrine/annotations": "^2.0",
+                "nikic/php-parser": "^4.15",
                 "php-parallel-lint/php-parallel-lint": "^1.2",
                 "phpstan/extension-installer": "^1.0",
                 "phpstan/phpstan": "^1.5",
@@ -3986,22 +4177,22 @@
             "description": "PHPDoc parser with support for nullable, intersection and generic types",
             "support": {
                 "issues": "https://github.com/phpstan/phpdoc-parser/issues",
-                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.3"
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1"
             },
-            "time": "2023-04-25T09:01:03+00:00"
+            "time": "2024-05-31T08:52:43+00:00"
         },
         {
             "name": "predis/predis",
-            "version": "v2.1.2",
+            "version": "v2.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/predis/predis.git",
-                "reference": "a77a43913a74f9331f637bb12867eb8e274814e5"
+                "reference": "b1d3255ed9ad4d7254f9f9bba386c99f4bb983d1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/predis/predis/zipball/a77a43913a74f9331f637bb12867eb8e274814e5",
-                "reference": "a77a43913a74f9331f637bb12867eb8e274814e5",
+                "url": "https://api.github.com/repos/predis/predis/zipball/b1d3255ed9ad4d7254f9f9bba386c99f4bb983d1",
+                "reference": "b1d3255ed9ad4d7254f9f9bba386c99f4bb983d1",
                 "shasum": ""
             },
             "require": {
@@ -4012,6 +4203,9 @@
                 "phpstan/phpstan": "^1.9",
                 "phpunit/phpunit": "^8.0 || ~9.4.4"
             },
+            "suggest": {
+                "ext-relay": "Faster connection with in-memory caching (>=0.6.2)"
+            },
             "type": "library",
             "autoload": {
                 "psr-4": {
@@ -4037,43 +4231,87 @@
                 "redis"
             ],
             "support": {
-                "issues": "https://github.com/predis/predis/issues",
-                "source": "https://github.com/predis/predis/tree/v2.1.2"
+                "issues": "https://github.com/predis/predis/issues",
+                "source": "https://github.com/predis/predis/tree/v2.2.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/tillkruss",
+                    "type": "github"
+                }
+            ],
+            "time": "2023-09-13T16:42:03+00:00"
+        },
+        {
+            "name": "psr/cache",
+            "version": "3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/cache.git",
+                "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+                "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.0.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Cache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for caching libraries",
+            "keywords": [
+                "cache",
+                "psr",
+                "psr-6"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/cache/tree/3.0.0"
             },
-            "funding": [
-                {
-                    "url": "https://github.com/sponsors/tillkruss",
-                    "type": "github"
-                }
-            ],
-            "time": "2023-03-02T18:32:04+00:00"
+            "time": "2021-02-03T23:26:27+00:00"
         },
         {
-            "name": "psr/cache",
-            "version": "3.0.0",
+            "name": "psr/clock",
+            "version": "1.0.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/php-fig/cache.git",
-                "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
+                "url": "https://github.com/php-fig/clock.git",
+                "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
-                "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+                "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
+                "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.0.0"
+                "php": "^7.0 || ^8.0"
             },
             "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0.x-dev"
-                }
-            },
             "autoload": {
                 "psr-4": {
-                    "Psr\\Cache\\": "src/"
+                    "Psr\\Clock\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -4086,16 +4324,20 @@
                     "homepage": "https://www.php-fig.org/"
                 }
             ],
-            "description": "Common interface for caching libraries",
+            "description": "Common interface for reading the clock.",
+            "homepage": "https://github.com/php-fig/clock",
             "keywords": [
-                "cache",
+                "clock",
+                "now",
                 "psr",
-                "psr-6"
+                "psr-20",
+                "time"
             ],
             "support": {
-                "source": "https://github.com/php-fig/cache/tree/3.0.0"
+                "issues": "https://github.com/php-fig/clock/issues",
+                "source": "https://github.com/php-fig/clock/tree/1.0.0"
             },
-            "time": "2021-02-03T23:26:27+00:00"
+            "time": "2022-11-25T14:36:26+00:00"
         },
         {
             "name": "psr/container",
@@ -4202,16 +4444,16 @@
         },
         {
             "name": "psr/http-client",
-            "version": "1.0.2",
+            "version": "1.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/http-client.git",
-                "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31"
+                "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31",
-                "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31",
+                "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
+                "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
                 "shasum": ""
             },
             "require": {
@@ -4248,26 +4490,26 @@
                 "psr-18"
             ],
             "support": {
-                "source": "https://github.com/php-fig/http-client/tree/1.0.2"
+                "source": "https://github.com/php-fig/http-client"
             },
-            "time": "2023-04-10T20:12:12+00:00"
+            "time": "2023-09-23T14:17:50+00:00"
         },
         {
             "name": "psr/http-factory",
-            "version": "1.0.2",
+            "version": "1.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/http-factory.git",
-                "reference": "e616d01114759c4c489f93b099585439f795fe35"
+                "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
-                "reference": "e616d01114759c4c489f93b099585439f795fe35",
+                "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
+                "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.0.0",
+                "php": ">=7.1",
                 "psr/http-message": "^1.0 || ^2.0"
             },
             "type": "library",
@@ -4291,7 +4533,7 @@
                     "homepage": "https://www.php-fig.org/"
                 }
             ],
-            "description": "Common interfaces for PSR-7 HTTP message factories",
+            "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
             "keywords": [
                 "factory",
                 "http",
@@ -4303,9 +4545,9 @@
                 "response"
             ],
             "support": {
-                "source": "https://github.com/php-fig/http-factory/tree/1.0.2"
+                "source": "https://github.com/php-fig/http-factory"
             },
-            "time": "2023-04-10T20:10:41+00:00"
+            "time": "2024-04-15T12:06:14+00:00"
         },
         {
             "name": "psr/http-message",
@@ -4362,30 +4604,30 @@
         },
         {
             "name": "psr/log",
-            "version": "1.1.4",
+            "version": "3.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/log.git",
-                "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
-                "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
+                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.0"
+                "php": ">=8.0.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.1.x-dev"
+                    "dev-master": "3.x-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Psr\\Log\\": "Psr/Log/"
+                    "Psr\\Log\\": "src"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -4406,9 +4648,9 @@
                 "psr-3"
             ],
             "support": {
-                "source": "https://github.com/php-fig/log/tree/1.1.4"
+                "source": "https://github.com/php-fig/log/tree/3.0.0"
             },
-            "time": "2021-05-03T11:20:27+00:00"
+            "time": "2021-07-14T16:46:02+00:00"
         },
         {
             "name": "psr/simple-cache",
@@ -4463,25 +4705,25 @@
         },
         {
             "name": "psy/psysh",
-            "version": "v0.11.16",
+            "version": "v0.12.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/bobthecow/psysh.git",
-                "reference": "151b145906804eea8e5d71fea23bfb470c904bfb"
+                "reference": "2fd717afa05341b4f8152547f142cd2f130f6818"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/151b145906804eea8e5d71fea23bfb470c904bfb",
-                "reference": "151b145906804eea8e5d71fea23bfb470c904bfb",
+                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/2fd717afa05341b4f8152547f142cd2f130f6818",
+                "reference": "2fd717afa05341b4f8152547f142cd2f130f6818",
                 "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"
+                "nikic/php-parser": "^5.0 || ^4.0",
+                "php": "^8.0 || ^7.4",
+                "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4",
+                "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4"
             },
             "conflict": {
                 "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4"
@@ -4492,8 +4734,7 @@
             "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."
+                "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well."
             },
             "bin": [
                 "bin/psysh"
@@ -4501,7 +4742,11 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "0.11.x-dev"
+                    "dev-main": "0.12.x-dev"
+                },
+                "bamarni-bin": {
+                    "bin-links": false,
+                    "forward-command": false
                 }
             },
             "autoload": {
@@ -4533,33 +4778,33 @@
             ],
             "support": {
                 "issues": "https://github.com/bobthecow/psysh/issues",
-                "source": "https://github.com/bobthecow/psysh/tree/v0.11.16"
+                "source": "https://github.com/bobthecow/psysh/tree/v0.12.4"
             },
-            "time": "2023-04-26T12:53:57+00:00"
+            "time": "2024-06-10T01:18:23+00:00"
         },
         {
             "name": "qirolab/laravel-themer",
-            "version": "2.1.0",
+            "version": "2.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/qirolab/laravel-themer.git",
-                "reference": "f643b371411e063fb0d42bffb1586df6ec70972b"
+                "reference": "d1ad2eae0068c026fcb5ebfe5391c280f5ace361"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/qirolab/laravel-themer/zipball/f643b371411e063fb0d42bffb1586df6ec70972b",
-                "reference": "f643b371411e063fb0d42bffb1586df6ec70972b",
+                "url": "https://api.github.com/repos/qirolab/laravel-themer/zipball/d1ad2eae0068c026fcb5ebfe5391c280f5ace361",
+                "reference": "d1ad2eae0068c026fcb5ebfe5391c280f5ace361",
                 "shasum": ""
             },
             "require": {
                 "facade/ignition-contracts": "^1.0",
-                "illuminate/support": "^9.19|^10.0",
+                "illuminate/support": "^9.19|^10.0|^11.0",
                 "php": ">=7.1.0"
             },
             "require-dev": {
-                "orchestra/testbench": "^7.0|^8.0",
-                "phpunit/phpunit": "^8.3|^9.0",
-                "vimeo/psalm": "^4.0"
+                "orchestra/testbench": "^7.0|^8.0|^9.0",
+                "phpunit/phpunit": "^8.3|^9.0|^10.5",
+                "vimeo/psalm": "^4.0|^5.22"
             },
             "type": "library",
             "extra": {
@@ -4597,7 +4842,7 @@
             ],
             "support": {
                 "issues": "https://github.com/qirolab/laravel-themer/issues",
-                "source": "https://github.com/qirolab/laravel-themer/tree/2.1.0"
+                "source": "https://github.com/qirolab/laravel-themer/tree/2.3.3"
             },
             "funding": [
                 {
@@ -4605,7 +4850,7 @@
                     "type": "other"
                 }
             ],
-            "time": "2023-02-14T12:31:27+00:00"
+            "time": "2024-05-15T15:29:58+00:00"
         },
         {
             "name": "ralouphie/getallheaders",
@@ -4742,20 +4987,20 @@
         },
         {
             "name": "ramsey/uuid",
-            "version": "4.7.4",
+            "version": "4.7.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ramsey/uuid.git",
-                "reference": "60a4c63ab724854332900504274f6150ff26d286"
+                "reference": "91039bc1faa45ba123c4328958e620d382ec7088"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286",
-                "reference": "60a4c63ab724854332900504274f6150ff26d286",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088",
+                "reference": "91039bc1faa45ba123c4328958e620d382ec7088",
                 "shasum": ""
             },
             "require": {
-                "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11",
+                "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12",
                 "ext-json": "*",
                 "php": "^8.0",
                 "ramsey/collection": "^1.2 || ^2.0"
@@ -4818,7 +5063,7 @@
             ],
             "support": {
                 "issues": "https://github.com/ramsey/uuid/issues",
-                "source": "https://github.com/ramsey/uuid/tree/4.7.4"
+                "source": "https://github.com/ramsey/uuid/tree/4.7.6"
             },
             "funding": [
                 {
@@ -4830,20 +5075,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-15T23:01:58+00:00"
+            "time": "2024-04-27T21:32:50+00:00"
         },
         {
             "name": "sabberworm/php-css-parser",
-            "version": "8.4.0",
+            "version": "v8.6.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/sabberworm/PHP-CSS-Parser.git",
-                "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30"
+                "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
+                "reference": "d2fb94a9641be84d79c7548c6d39bbebba6e9a70"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/e41d2140031d533348b2192a83f02d8dd8a71d30",
-                "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30",
+                "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d2fb94a9641be84d79c7548c6d39bbebba6e9a70",
+                "reference": "d2fb94a9641be84d79c7548c6d39bbebba6e9a70",
                 "shasum": ""
             },
             "require": {
@@ -4851,13 +5096,17 @@
                 "php": ">=5.6.20"
             },
             "require-dev": {
-                "codacy/coverage": "^1.4",
-                "phpunit/phpunit": "^4.8.36"
+                "phpunit/phpunit": "^5.7.27"
             },
             "suggest": {
                 "ext-mbstring": "for parsing UTF-8 CSS"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "9.0.x-dev"
+                }
+            },
             "autoload": {
                 "psr-4": {
                     "Sabberworm\\CSS\\": "src/"
@@ -4870,6 +5119,14 @@
             "authors": [
                 {
                     "name": "Raphael Schweikert"
+                },
+                {
+                    "name": "Oliver Klee",
+                    "email": "github@oliverklee.de"
+                },
+                {
+                    "name": "Jake Hotson",
+                    "email": "jake.github@qzdesign.co.uk"
                 }
             ],
             "description": "Parser for CSS Files written in PHP",
@@ -4880,23 +5137,23 @@
                 "stylesheet"
             ],
             "support": {
-                "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues",
-                "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0"
+                "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
+                "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.6.0"
             },
-            "time": "2021-12-11T13:40:54+00:00"
+            "time": "2024-07-01T07:33:21+00:00"
         },
         {
             "name": "socialiteproviders/discord",
-            "version": "4.1.2",
+            "version": "4.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/SocialiteProviders/Discord.git",
-                "reference": "11f6a8ded5b1948723886f2e5413b91139fcce6b"
+                "reference": "c71c379acfdca5ba4aa65a3db5ae5222852a919c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/SocialiteProviders/Discord/zipball/11f6a8ded5b1948723886f2e5413b91139fcce6b",
-                "reference": "11f6a8ded5b1948723886f2e5413b91139fcce6b",
+                "url": "https://api.github.com/repos/SocialiteProviders/Discord/zipball/c71c379acfdca5ba4aa65a3db5ae5222852a919c",
+                "reference": "c71c379acfdca5ba4aa65a3db5ae5222852a919c",
                 "shasum": ""
             },
             "require": {
@@ -4933,30 +5190,30 @@
                 "issues": "https://github.com/socialiteproviders/providers/issues",
                 "source": "https://github.com/socialiteproviders/providers"
             },
-            "time": "2023-02-01T08:54:49+00:00"
+            "time": "2023-07-24T23:28:47+00:00"
         },
         {
             "name": "socialiteproviders/manager",
-            "version": "v4.3.0",
+            "version": "v4.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/SocialiteProviders/Manager.git",
-                "reference": "47402cbc5b7ef445317e799bf12fd5a12062206c"
+                "reference": "dea5190981c31b89e52259da9ab1ca4e2b258b21"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/47402cbc5b7ef445317e799bf12fd5a12062206c",
-                "reference": "47402cbc5b7ef445317e799bf12fd5a12062206c",
+                "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/dea5190981c31b89e52259da9ab1ca4e2b258b21",
+                "reference": "dea5190981c31b89e52259da9ab1ca4e2b258b21",
                 "shasum": ""
             },
             "require": {
-                "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0",
-                "laravel/socialite": "~5.0",
-                "php": "^7.4 || ^8.0"
+                "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0",
+                "laravel/socialite": "^5.5",
+                "php": "^8.0"
             },
             "require-dev": {
                 "mockery/mockery": "^1.2",
-                "phpunit/phpunit": "^6.0 || ^9.0"
+                "phpunit/phpunit": "^9.0"
             },
             "type": "library",
             "extra": {
@@ -5007,33 +5264,33 @@
                 "issues": "https://github.com/socialiteproviders/manager/issues",
                 "source": "https://github.com/socialiteproviders/manager"
             },
-            "time": "2023-01-26T23:11:27+00:00"
+            "time": "2024-05-04T07:57:39+00:00"
         },
         {
             "name": "spatie/laravel-activitylog",
-            "version": "4.7.3",
+            "version": "4.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-activitylog.git",
-                "reference": "ec65a478a909b8df1b4f0c3c45de2592ca7639e5"
+                "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/ec65a478a909b8df1b4f0c3c45de2592ca7639e5",
-                "reference": "ec65a478a909b8df1b4f0c3c45de2592ca7639e5",
+                "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/eb6f37dd40af950ce10cf5280f0acfa3e08c3bff",
+                "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff",
                 "shasum": ""
             },
             "require": {
-                "illuminate/config": "^8.0 || ^9.0 || ^10.0",
-                "illuminate/database": "^8.69 || ^9.27 || ^10.0",
-                "illuminate/support": "^8.0 || ^9.0 || ^10.0",
-                "php": "^8.0",
+                "illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0",
+                "illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0",
+                "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0",
+                "php": "^8.1",
                 "spatie/laravel-package-tools": "^1.6.3"
             },
             "require-dev": {
                 "ext-json": "*",
-                "orchestra/testbench": "^6.23 || ^7.0 || ^8.0",
-                "pestphp/pest": "^1.20"
+                "orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0",
+                "pestphp/pest": "^1.20 || ^2.0"
             },
             "type": "library",
             "extra": {
@@ -5086,7 +5343,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-activitylog/issues",
-                "source": "https://github.com/spatie/laravel-activitylog/tree/4.7.3"
+                "source": "https://github.com/spatie/laravel-activitylog/tree/4.8.0"
             },
             "funding": [
                 {
@@ -5098,24 +5355,24 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-25T17:04:51+00:00"
+            "time": "2024-03-08T22:28:17+00:00"
         },
         {
             "name": "spatie/laravel-package-tools",
-            "version": "1.15.0",
+            "version": "1.16.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-package-tools.git",
-                "reference": "efab1844b8826443135201c4443690f032c3d533"
+                "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/efab1844b8826443135201c4443690f032c3d533",
-                "reference": "efab1844b8826443135201c4443690f032c3d533",
+                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
+                "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
                 "shasum": ""
             },
             "require": {
-                "illuminate/contracts": "^9.28|^10.0",
+                "illuminate/contracts": "^9.28|^10.0|^11.0",
                 "php": "^8.0"
             },
             "require-dev": {
@@ -5150,7 +5407,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-package-tools/issues",
-                "source": "https://github.com/spatie/laravel-package-tools/tree/1.15.0"
+                "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4"
             },
             "funding": [
                 {
@@ -5158,39 +5415,39 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-04-27T08:09:01+00:00"
+            "time": "2024-03-20T07:29:11+00:00"
         },
         {
             "name": "spatie/laravel-permission",
-            "version": "5.10.1",
+            "version": "6.9.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-permission.git",
-                "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae"
+                "reference": "fe973a58b44380d0e8620107259b7bda22f70408"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/d08b3ffc5870cce4a47a39f22174947b33c191ae",
-                "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae",
+                "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/fe973a58b44380d0e8620107259b7bda22f70408",
+                "reference": "fe973a58b44380d0e8620107259b7bda22f70408",
                 "shasum": ""
             },
             "require": {
-                "illuminate/auth": "^7.0|^8.0|^9.0|^10.0",
-                "illuminate/container": "^7.0|^8.0|^9.0|^10.0",
-                "illuminate/contracts": "^7.0|^8.0|^9.0|^10.0",
-                "illuminate/database": "^7.0|^8.0|^9.0|^10.0",
-                "php": "^7.3|^8.0"
+                "illuminate/auth": "^8.12|^9.0|^10.0|^11.0",
+                "illuminate/container": "^8.12|^9.0|^10.0|^11.0",
+                "illuminate/contracts": "^8.12|^9.0|^10.0|^11.0",
+                "illuminate/database": "^8.12|^9.0|^10.0|^11.0",
+                "php": "^8.0"
             },
             "require-dev": {
-                "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0",
-                "phpunit/phpunit": "^9.4",
-                "predis/predis": "^1.1"
+                "laravel/passport": "^11.0|^12.0",
+                "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
+                "phpunit/phpunit": "^9.4|^10.1"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "5.x-dev",
-                    "dev-master": "5.x-dev"
+                    "dev-main": "6.x-dev",
+                    "dev-master": "6.x-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -5218,7 +5475,7 @@
                     "role": "Developer"
                 }
             ],
-            "description": "Permission handling for Laravel 6.0 and up",
+            "description": "Permission handling for Laravel 8.0 and up",
             "homepage": "https://github.com/spatie/laravel-permission",
             "keywords": [
                 "acl",
@@ -5232,7 +5489,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-permission/issues",
-                "source": "https://github.com/spatie/laravel-permission/tree/5.10.1"
+                "source": "https://github.com/spatie/laravel-permission/tree/6.9.0"
             },
             "funding": [
                 {
@@ -5240,35 +5497,37 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-04-12T17:08:32+00:00"
+            "time": "2024-06-22T23:04:52+00:00"
         },
         {
             "name": "spatie/laravel-query-builder",
-            "version": "5.2.0",
+            "version": "6.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-query-builder.git",
-                "reference": "7b3911f61dcaa27804b80f30b73a468a9539e850"
+                "reference": "69a6fd38c1515e42aec0df10d8adb8465f2f1f79"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/7b3911f61dcaa27804b80f30b73a468a9539e850",
-                "reference": "7b3911f61dcaa27804b80f30b73a468a9539e850",
+                "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/69a6fd38c1515e42aec0df10d8adb8465f2f1f79",
+                "reference": "69a6fd38c1515e42aec0df10d8adb8465f2f1f79",
                 "shasum": ""
             },
             "require": {
-                "illuminate/database": "^9.0|^10.0",
-                "illuminate/http": "^9.0|^10.0",
-                "illuminate/support": "^9.0|^10.0",
-                "php": "^8.0",
+                "illuminate/database": "^10.0|^11.0",
+                "illuminate/http": "^10.0|^11.0",
+                "illuminate/support": "^10.0|^11.0",
+                "php": "^8.2",
                 "spatie/laravel-package-tools": "^1.11"
             },
             "require-dev": {
                 "ext-json": "*",
                 "mockery/mockery": "^1.4",
+                "nunomaduro/larastan": "^2.0",
                 "orchestra/testbench": "^7.0|^8.0",
-                "pestphp/pest": "^1.20",
-                "spatie/laravel-ray": "^1.28"
+                "pestphp/pest": "^2.0",
+                "phpunit/phpunit": "^10.0",
+                "spatie/invade": "^2.0"
             },
             "type": "library",
             "extra": {
@@ -5312,43 +5571,43 @@
                     "type": "custom"
                 }
             ],
-            "time": "2023-02-24T15:48:30+00:00"
+            "time": "2024-05-21T12:12:10+00:00"
         },
         {
             "name": "spatie/laravel-settings",
-            "version": "2.8.3",
+            "version": "3.3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-settings.git",
-                "reference": "9193603a3e02d19af9f2fd0d309ac2469b25d680"
+                "reference": "395066797823856638a0a2feb243b396a94e22e5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/9193603a3e02d19af9f2fd0d309ac2469b25d680",
-                "reference": "9193603a3e02d19af9f2fd0d309ac2469b25d680",
+                "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/395066797823856638a0a2feb243b396a94e22e5",
+                "reference": "395066797823856638a0a2feb243b396a94e22e5",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
-                "illuminate/database": "^8.73|^9.0|^10.0",
+                "illuminate/database": "^8.73|^9.0|^10.0|^11.0",
                 "php": "^7.4|^8.0",
                 "phpdocumentor/type-resolver": "^1.5",
                 "spatie/temporary-directory": "^1.3|^2.0"
             },
             "require-dev": {
                 "ext-redis": "*",
+                "larastan/larastan": "^2.0",
                 "mockery/mockery": "^1.4",
-                "nunomaduro/larastan": "^2.0",
-                "orchestra/testbench": "^6.23|^7.0|^8.0",
-                "pestphp/pest": "^1.21",
-                "pestphp/pest-plugin-laravel": "^1.2",
+                "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
+                "pestphp/pest": "^1.21|^2.0",
+                "pestphp/pest-plugin-laravel": "^1.2|^2.0",
                 "phpstan/extension-installer": "^1.1",
                 "phpstan/phpstan-deprecation-rules": "^1.0",
                 "phpstan/phpstan-phpunit": "^1.0",
-                "phpunit/phpunit": "^9.5",
-                "spatie/laravel-data": "^1.0.0|^2.0.0",
-                "spatie/pest-plugin-snapshots": "^1.1",
-                "spatie/phpunit-snapshot-assertions": "^4.2",
+                "phpunit/phpunit": "^9.5|^10.0",
+                "spatie/laravel-data": "^1.0.0|^2.0.0|^4.0.0",
+                "spatie/pest-plugin-snapshots": "^1.1|^2.0",
+                "spatie/phpunit-snapshot-assertions": "^4.2|^5.0",
                 "spatie/ray": "^1.36"
             },
             "suggest": {
@@ -5387,7 +5646,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-settings/issues",
-                "source": "https://github.com/spatie/laravel-settings/tree/2.8.3"
+                "source": "https://github.com/spatie/laravel-settings/tree/3.3.2"
             },
             "funding": [
                 {
@@ -5399,32 +5658,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-03-30T12:47:39+00:00"
+            "time": "2024-03-22T07:50:04+00:00"
         },
         {
             "name": "spatie/laravel-validation-rules",
-            "version": "3.2.2",
+            "version": "3.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-validation-rules.git",
-                "reference": "3cbef3441cb274cd3c12409586f18c3a44d46d0a"
+                "reference": "b629b0a1049ddfe18e5534717b1627bacfaef208"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-validation-rules/zipball/3cbef3441cb274cd3c12409586f18c3a44d46d0a",
-                "reference": "3cbef3441cb274cd3c12409586f18c3a44d46d0a",
+                "url": "https://api.github.com/repos/spatie/laravel-validation-rules/zipball/b629b0a1049ddfe18e5534717b1627bacfaef208",
+                "reference": "b629b0a1049ddfe18e5534717b1627bacfaef208",
                 "shasum": ""
             },
             "require": {
-                "illuminate/support": "^8.0|^9.0|^10.0",
+                "illuminate/support": "^8.0|^9.0|^10.0|^11.0",
                 "php": "^8.0"
             },
             "require-dev": {
                 "laravel/pint": "^1.3",
-                "league/iso3166": "^3.0",
+                "league/iso3166": "^3.0|^4.3",
                 "myclabs/php-enum": "^1.6",
-                "orchestra/testbench": "^6.23|^7.0|^8.0",
-                "phpunit/phpunit": "^9.4",
+                "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
+                "pestphp/pest": "^1.23|^2.6",
                 "spatie/enum": "^2.2|^3.0"
             },
             "suggest": {
@@ -5464,7 +5723,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-validation-rules/issues",
-                "source": "https://github.com/spatie/laravel-validation-rules/tree/3.2.2"
+                "source": "https://github.com/spatie/laravel-validation-rules/tree/3.4.0"
             },
             "funding": [
                 {
@@ -5472,20 +5731,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-25T16:22:06+00:00"
+            "time": "2024-03-02T05:57:47+00:00"
         },
         {
             "name": "spatie/temporary-directory",
-            "version": "2.1.2",
+            "version": "2.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/temporary-directory.git",
-                "reference": "0c804873f6b4042aa8836839dca683c7d0f71831"
+                "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/0c804873f6b4042aa8836839dca683c7d0f71831",
-                "reference": "0c804873f6b4042aa8836839dca683c7d0f71831",
+                "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a",
+                "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a",
                 "shasum": ""
             },
             "require": {
@@ -5521,7 +5780,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/temporary-directory/issues",
-                "source": "https://github.com/spatie/temporary-directory/tree/2.1.2"
+                "source": "https://github.com/spatie/temporary-directory/tree/2.2.1"
             },
             "funding": [
                 {
@@ -5533,7 +5792,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-04-28T07:47:42+00:00"
+            "time": "2023-12-25T11:46:58+00:00"
         },
         {
             "name": "stripe/stripe-php",
@@ -5595,51 +5854,122 @@
             },
             "time": "2022-05-05T17:18:02+00:00"
         },
+        {
+            "name": "symfony/clock",
+            "version": "v7.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/clock.git",
+                "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/clock/zipball/3dfc8b084853586de51dd1441c6242c76a28cbe7",
+                "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "psr/clock": "^1.0",
+                "symfony/polyfill-php83": "^1.28"
+            },
+            "provide": {
+                "psr/clock-implementation": "1.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "Resources/now.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Component\\Clock\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Decouples applications from the system clock",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "clock",
+                "psr20",
+                "time"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/clock/tree/v7.1.1"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-05-31T14:57:53+00:00"
+        },
         {
             "name": "symfony/console",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "12288d9f4500f84a4d02254d4aa968b15488476f"
+                "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/12288d9f4500f84a4d02254d4aa968b15488476f",
-                "reference": "12288d9f4500f84a4d02254d4aa968b15488476f",
+                "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
+                "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
-                "symfony/deprecation-contracts": "^2.1|^3",
+                "php": ">=8.2",
                 "symfony/polyfill-mbstring": "~1.0",
-                "symfony/service-contracts": "^1.1|^2|^3",
-                "symfony/string": "^5.4|^6.0"
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/string": "^6.4|^7.0"
             },
             "conflict": {
-                "symfony/dependency-injection": "<5.4",
-                "symfony/dotenv": "<5.4",
-                "symfony/event-dispatcher": "<5.4",
-                "symfony/lock": "<5.4",
-                "symfony/process": "<5.4"
+                "symfony/dependency-injection": "<6.4",
+                "symfony/dotenv": "<6.4",
+                "symfony/event-dispatcher": "<6.4",
+                "symfony/lock": "<6.4",
+                "symfony/process": "<6.4"
             },
             "provide": {
                 "psr/log-implementation": "1.0|2.0|3.0"
             },
             "require-dev": {
                 "psr/log": "^1|^2|^3",
-                "symfony/config": "^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": ""
+                "symfony/config": "^6.4|^7.0",
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/event-dispatcher": "^6.4|^7.0",
+                "symfony/http-foundation": "^6.4|^7.0",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/lock": "^6.4|^7.0",
+                "symfony/messenger": "^6.4|^7.0",
+                "symfony/process": "^6.4|^7.0",
+                "symfony/stopwatch": "^6.4|^7.0",
+                "symfony/var-dumper": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -5673,7 +6003,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v6.2.10"
+                "source": "https://github.com/symfony/console/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -5689,24 +6019,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-28T13:37:43+00:00"
+            "time": "2024-07-26T12:41:01+00:00"
         },
         {
             "name": "symfony/css-selector",
-            "version": "v6.2.7",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0"
+                "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/aedf3cb0f5b929ec255d96bbb4909e9932c769e0",
-                "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
+                "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1"
+                "php": ">=8.2"
             },
             "type": "library",
             "autoload": {
@@ -5738,7 +6068,7 @@
             "description": "Converts CSS selectors to XPath expressions",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/css-selector/tree/v6.2.7"
+                "source": "https://github.com/symfony/css-selector/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -5754,20 +6084,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-14T08:44:56+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
-            "version": "v3.2.1",
+            "version": "v3.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/deprecation-contracts.git",
-                "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
+                "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
-                "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
+                "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
                 "shasum": ""
             },
             "require": {
@@ -5776,7 +6106,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "3.3-dev"
+                    "dev-main": "3.5-dev"
                 },
                 "thanks": {
                     "name": "symfony/contracts",
@@ -5805,7 +6135,7 @@
             "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"
+                "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
             },
             "funding": [
                 {
@@ -5821,31 +6151,35 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-01T10:25:55+00:00"
+            "time": "2024-04-18T09:32:20+00:00"
         },
         {
             "name": "symfony/error-handler",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "8b7e9f124640cb0611624a9383176c3e5f7d8cfb"
+                "reference": "432bb369952795c61ca1def65e078c4a80dad13c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/8b7e9f124640cb0611624a9383176c3e5f7d8cfb",
-                "reference": "8b7e9f124640cb0611624a9383176c3e5f7d8cfb",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c",
+                "reference": "432bb369952795c61ca1def65e078c4a80dad13c",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "psr/log": "^1|^2|^3",
-                "symfony/var-dumper": "^5.4|^6.0"
+                "symfony/var-dumper": "^6.4|^7.0"
+            },
+            "conflict": {
+                "symfony/deprecation-contracts": "<2.5",
+                "symfony/http-kernel": "<6.4"
             },
             "require-dev": {
-                "symfony/deprecation-contracts": "^2.1|^3",
-                "symfony/http-kernel": "^5.4|^6.0",
-                "symfony/serializer": "^5.4|^6.0"
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/serializer": "^6.4|^7.0"
             },
             "bin": [
                 "Resources/bin/patch-type-declarations"
@@ -5876,7 +6210,7 @@
             "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.10"
+                "source": "https://github.com/symfony/error-handler/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -5892,28 +6226,29 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-18T13:46:08+00:00"
+            "time": "2024-07-26T13:02:51+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v6.2.8",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339"
+                "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
-                "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
+                "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
-                "symfony/event-dispatcher-contracts": "^2|^3"
+                "php": ">=8.2",
+                "symfony/event-dispatcher-contracts": "^2.5|^3"
             },
             "conflict": {
-                "symfony/dependency-injection": "<5.4"
+                "symfony/dependency-injection": "<6.4",
+                "symfony/service-contracts": "<2.5"
             },
             "provide": {
                 "psr/event-dispatcher-implementation": "1.0",
@@ -5921,17 +6256,13 @@
             },
             "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": ""
+                "symfony/config": "^6.4|^7.0",
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/error-handler": "^6.4|^7.0",
+                "symfony/expression-language": "^6.4|^7.0",
+                "symfony/http-foundation": "^6.4|^7.0",
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/stopwatch": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -5959,7 +6290,7 @@
             "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"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -5975,33 +6306,30 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-20T16:06:02+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
-            "version": "v3.2.1",
+            "version": "v3.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher-contracts.git",
-                "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd"
+                "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
-                "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50",
+                "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.1",
                 "psr/event-dispatcher": "^1"
             },
-            "suggest": {
-                "symfony/event-dispatcher-implementation": ""
-            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "3.3-dev"
+                    "dev-main": "3.5-dev"
                 },
                 "thanks": {
                     "name": "symfony/contracts",
@@ -6038,7 +6366,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.1"
+                "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0"
             },
             "funding": [
                 {
@@ -6054,27 +6382,27 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-01T10:32:47+00:00"
+            "time": "2024-04-18T09:32:20+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v6.2.7",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb"
+                "reference": "717c6329886f32dc65e27461f80f2a465412fdca"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb",
-                "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca",
+                "reference": "717c6329886f32dc65e27461f80f2a465412fdca",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "symfony/filesystem": "^6.0"
+                "symfony/filesystem": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -6102,7 +6430,7 @@
             "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"
+                "source": "https://github.com/symfony/finder/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -6118,28 +6446,32 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-16T09:57:23+00:00"
+            "time": "2024-07-24T07:08:44+00:00"
         },
         {
             "name": "symfony/http-client",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "3f5545a91c8e79dedd1a06c4b04e1682c80c42f9"
+                "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/3f5545a91c8e79dedd1a06c4b04e1682c80c42f9",
-                "reference": "3f5545a91c8e79dedd1a06c4b04e1682c80c42f9",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/b79858aa7a051ea791b0d50269a234a0b50cb231",
+                "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "psr/log": "^1|^2|^3",
-                "symfony/deprecation-contracts": "^2.1|^3",
-                "symfony/http-client-contracts": "^3",
-                "symfony/service-contracts": "^1.0|^2|^3"
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/http-client-contracts": "^3.4.1",
+                "symfony/service-contracts": "^2.5|^3"
+            },
+            "conflict": {
+                "php-http/discovery": "<1.15",
+                "symfony/http-foundation": "<6.4"
             },
             "provide": {
                 "php-http/async-client-implementation": "*",
@@ -6152,14 +6484,16 @@
                 "amphp/http-client": "^4.2.1",
                 "amphp/http-tunnel": "^1.0",
                 "amphp/socket": "^1.1",
-                "guzzlehttp/promises": "^1.4",
+                "guzzlehttp/promises": "^1.4|^2.0",
                 "nyholm/psr7": "^1.0",
                 "php-http/httplug": "^1.0|^2.0",
                 "psr/http-client": "^1.0",
-                "symfony/dependency-injection": "^5.4|^6.0",
-                "symfony/http-kernel": "^5.4|^6.0",
-                "symfony/process": "^5.4|^6.0",
-                "symfony/stopwatch": "^5.4|^6.0"
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/messenger": "^6.4|^7.0",
+                "symfony/process": "^6.4|^7.0",
+                "symfony/rate-limiter": "^6.4|^7.0",
+                "symfony/stopwatch": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -6190,7 +6524,7 @@
                 "http"
             ],
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v6.2.10"
+                "source": "https://github.com/symfony/http-client/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -6206,32 +6540,29 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-20T13:12:48+00:00"
+            "time": "2024-07-17T06:10:24+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
-            "version": "v3.2.1",
+            "version": "v3.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client-contracts.git",
-                "reference": "df2ecd6cb70e73c1080e6478aea85f5f4da2c48b"
+                "reference": "20414d96f391677bf80078aa55baece78b82647d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/df2ecd6cb70e73c1080e6478aea85f5f4da2c48b",
-                "reference": "df2ecd6cb70e73c1080e6478aea85f5f4da2c48b",
+                "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d",
+                "reference": "20414d96f391677bf80078aa55baece78b82647d",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.1"
             },
-            "suggest": {
-                "symfony/http-client-implementation": ""
-            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "3.3-dev"
+                    "dev-main": "3.5-dev"
                 },
                 "thanks": {
                     "name": "symfony/contracts",
@@ -6271,7 +6602,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/http-client-contracts/tree/v3.2.1"
+                "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0"
             },
             "funding": [
                 {
@@ -6287,41 +6618,40 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-01T10:32:47+00:00"
+            "time": "2024-04-18T09:32:20+00:00"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "49adbb92bcb4e3c2943719d2756271e8b9602acc"
+                "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/49adbb92bcb4e3c2943719d2756271e8b9602acc",
-                "reference": "49adbb92bcb4e3c2943719d2756271e8b9602acc",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
+                "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
-                "symfony/deprecation-contracts": "^2.1|^3",
-                "symfony/polyfill-mbstring": "~1.1"
+                "php": ">=8.2",
+                "symfony/polyfill-mbstring": "~1.1",
+                "symfony/polyfill-php83": "^1.27"
             },
             "conflict": {
-                "symfony/cache": "<6.2"
+                "doctrine/dbal": "<3.6",
+                "symfony/cache": "<6.4"
             },
             "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"
+                "doctrine/dbal": "^3.6|^4",
+                "predis/predis": "^1.1|^2.0",
+                "symfony/cache": "^6.4|^7.0",
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/expression-language": "^6.4|^7.0",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/mime": "^6.4|^7.0",
+                "symfony/rate-limiter": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -6349,7 +6679,7 @@
             "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.10"
+                "source": "https://github.com/symfony/http-foundation/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -6365,74 +6695,77 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-18T13:46:08+00:00"
+            "time": "2024-07-26T12:41:01+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "81064a65a5496f17d2b6984f6519406f98864215"
+                "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/81064a65a5496f17d2b6984f6519406f98864215",
-                "reference": "81064a65a5496f17d2b6984f6519406f98864215",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186",
+                "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "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/deprecation-contracts": "^2.5|^3",
+                "symfony/error-handler": "^6.4|^7.0",
+                "symfony/event-dispatcher": "^6.4|^7.0",
+                "symfony/http-foundation": "^6.4|^7.0",
                 "symfony/polyfill-ctype": "^1.8"
             },
             "conflict": {
-                "symfony/browser-kit": "<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"
+                "symfony/browser-kit": "<6.4",
+                "symfony/cache": "<6.4",
+                "symfony/config": "<6.4",
+                "symfony/console": "<6.4",
+                "symfony/dependency-injection": "<6.4",
+                "symfony/doctrine-bridge": "<6.4",
+                "symfony/form": "<6.4",
+                "symfony/http-client": "<6.4",
+                "symfony/http-client-contracts": "<2.5",
+                "symfony/mailer": "<6.4",
+                "symfony/messenger": "<6.4",
+                "symfony/translation": "<6.4",
+                "symfony/translation-contracts": "<2.5",
+                "symfony/twig-bridge": "<6.4",
+                "symfony/validator": "<6.4",
+                "symfony/var-dumper": "<6.4",
+                "twig/twig": "<3.0.4"
             },
             "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": ""
+                "symfony/browser-kit": "^6.4|^7.0",
+                "symfony/clock": "^6.4|^7.0",
+                "symfony/config": "^6.4|^7.0",
+                "symfony/console": "^6.4|^7.0",
+                "symfony/css-selector": "^6.4|^7.0",
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/dom-crawler": "^6.4|^7.0",
+                "symfony/expression-language": "^6.4|^7.0",
+                "symfony/finder": "^6.4|^7.0",
+                "symfony/http-client-contracts": "^2.5|^3",
+                "symfony/process": "^6.4|^7.0",
+                "symfony/property-access": "^7.1",
+                "symfony/routing": "^6.4|^7.0",
+                "symfony/serializer": "^7.1",
+                "symfony/stopwatch": "^6.4|^7.0",
+                "symfony/translation": "^6.4|^7.0",
+                "symfony/translation-contracts": "^2.5|^3",
+                "symfony/uid": "^6.4|^7.0",
+                "symfony/validator": "^6.4|^7.0",
+                "symfony/var-dumper": "^6.4|^7.0",
+                "symfony/var-exporter": "^6.4|^7.0",
+                "twig/twig": "^3.0.4"
             },
             "type": "library",
             "autoload": {
@@ -6460,7 +6793,7 @@
             "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.10"
+                "source": "https://github.com/symfony/http-kernel/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -6476,28 +6809,32 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-28T13:50:28+00:00"
+            "time": "2024-07-26T14:58:15+00:00"
         },
         {
             "name": "symfony/intl",
-            "version": "v6.2.10",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/intl.git",
-                "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d"
+                "reference": "66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/intl/zipball/860c99e53149d22df1900d3aefdaeb17adb7669d",
-                "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d",
+                "url": "https://api.github.com/repos/symfony/intl/zipball/66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c",
+                "reference": "66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1"
+                "php": ">=8.2",
+                "symfony/deprecation-contracts": "^2.5|^3"
+            },
+            "conflict": {
+                "symfony/string": "<7.1"
             },
             "require-dev": {
-                "symfony/filesystem": "^5.4|^6.0",
-                "symfony/finder": "^5.4|^6.0"
+                "symfony/filesystem": "^6.4|^7.0",
+                "symfony/var-exporter": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -6505,7 +6842,8 @@
                     "Symfony\\Component\\Intl\\": ""
                 },
                 "exclude-from-classmap": [
-                    "/Tests/"
+                    "/Tests/",
+                    "/Resources/data/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -6541,7 +6879,7 @@
                 "localization"
             ],
             "support": {
-                "source": "https://github.com/symfony/intl/tree/v6.2.10"
+                "source": "https://github.com/symfony/intl/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -6557,42 +6895,43 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-14T16:23:31+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/mailer",
-            "version": "v6.2.8",
+            "version": "v7.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mailer.git",
-                "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17"
+                "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mailer/zipball/bfcfa015c67e19c6fdb7ca6fe70700af1e740a17",
-                "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17",
+                "url": "https://api.github.com/repos/symfony/mailer/zipball/8fcff0af9043c8f8a8e229437cea363e282f9aee",
+                "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee",
                 "shasum": ""
             },
             "require": {
                 "egulias/email-validator": "^2.1.10|^3|^4",
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "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"
+                "symfony/event-dispatcher": "^6.4|^7.0",
+                "symfony/mime": "^6.4|^7.0",
+                "symfony/service-contracts": "^2.5|^3"
             },
             "conflict": {
-                "symfony/http-kernel": "<5.4",
-                "symfony/messenger": "<6.2",
-                "symfony/mime": "<6.2",
-                "symfony/twig-bridge": "<6.2.1"
+                "symfony/http-client-contracts": "<2.5",
+                "symfony/http-kernel": "<6.4",
+                "symfony/messenger": "<6.4",
+                "symfony/mime": "<6.4",
+                "symfony/twig-bridge": "<6.4"
             },
             "require-dev": {
-                "symfony/console": "^5.4|^6.0",
-                "symfony/http-client": "^5.4|^6.0",
-                "symfony/messenger": "^6.2",
-                "symfony/twig-bridge": "^6.2"
+                "symfony/console": "^6.4|^7.0",
+                "symfony/http-client": "^6.4|^7.0",
+                "symfony/messenger": "^6.4|^7.0",
+                "symfony/twig-bridge": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -6620,7 +6959,7 @@
             "description": "Helps sending emails",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/mailer/tree/v6.2.8"
+                "source": "https://github.com/symfony/mailer/tree/v7.1.2"
             },
             "funding": [
                 {
@@ -6636,28 +6975,32 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-14T15:00:05+00:00"
+            "time": "2024-06-28T08:00:31+00:00"
         },
         {
             "name": "symfony/mailgun-mailer",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mailgun-mailer.git",
-                "reference": "2c9d47b11cc154d2db3f571030cd965d128de1a8"
+                "reference": "dac02fe68e9306849703025511c56f10701696a8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/2c9d47b11cc154d2db3f571030cd965d128de1a8",
-                "reference": "2c9d47b11cc154d2db3f571030cd965d128de1a8",
+                "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8",
+                "reference": "dac02fe68e9306849703025511c56f10701696a8",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
-                "symfony/mailer": "^5.4.21|^6.2.7"
+                "php": ">=8.2",
+                "symfony/mailer": "^6.4|^7.0"
+            },
+            "conflict": {
+                "symfony/http-foundation": "<6.4"
             },
             "require-dev": {
-                "symfony/http-client": "^5.4|^6.0"
+                "symfony/http-client": "^6.4|^7.0",
+                "symfony/webhook": "^6.4|^7.0"
             },
             "type": "symfony-mailer-bridge",
             "autoload": {
@@ -6685,7 +7028,7 @@
             "description": "Symfony Mailgun Mailer Bridge",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/mailgun-mailer/tree/v6.2.10"
+                "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -6701,24 +7044,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-14T16:23:31+00:00"
+            "time": "2024-07-04T11:20:59+00:00"
         },
         {
             "name": "symfony/mime",
-            "version": "v6.2.10",
+            "version": "v7.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mime.git",
-                "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723"
+                "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mime/zipball/b6c137fc53a9f7c4c951cd3f362b3734c7a97723",
-                "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723",
+                "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
+                "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "symfony/polyfill-intl-idn": "^1.10",
                 "symfony/polyfill-mbstring": "^1.0"
             },
@@ -6726,17 +7069,18 @@
                 "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"
+                "symfony/mailer": "<6.4",
+                "symfony/serializer": "<6.4.3|>7.0,<7.0.3"
             },
             "require-dev": {
                 "egulias/email-validator": "^2.1.10|^3.1|^4",
                 "league/html-to-markdown": "^5.0",
                 "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
-                "symfony/dependency-injection": "^5.4|^6.0",
-                "symfony/property-access": "^5.4|^6.0",
-                "symfony/property-info": "^5.4|^6.0",
-                "symfony/serializer": "^6.2"
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/process": "^6.4|^7.0",
+                "symfony/property-access": "^6.4|^7.0",
+                "symfony/property-info": "^6.4|^7.0",
+                "symfony/serializer": "^6.4.3|^7.0.3"
             },
             "type": "library",
             "autoload": {
@@ -6768,7 +7112,7 @@
                 "mime-type"
             ],
             "support": {
-                "source": "https://github.com/symfony/mime/tree/v6.2.10"
+                "source": "https://github.com/symfony/mime/tree/v7.1.2"
             },
             "funding": [
                 {
@@ -6784,20 +7128,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-19T09:54:16+00:00"
+            "time": "2024-06-28T10:03:55+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
+                "reference": "0424dff1c58f028c451efff2045f5d92410bd540"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
-                "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
+                "reference": "0424dff1c58f028c451efff2045f5d92410bd540",
                 "shasum": ""
             },
             "require": {
@@ -6811,9 +7155,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -6850,7 +7191,7 @@
                 "portable"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -6866,20 +7207,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-05-31T15:07:36+00:00"
         },
         {
             "name": "symfony/polyfill-intl-grapheme",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
-                "reference": "511a08c03c1960e08a883f4cffcacd219b758354"
+                "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
-                "reference": "511a08c03c1960e08a883f4cffcacd219b758354",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a",
+                "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a",
                 "shasum": ""
             },
             "require": {
@@ -6890,9 +7231,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -6931,7 +7269,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -6947,20 +7285,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-05-31T15:07:36+00:00"
         },
         {
             "name": "symfony/polyfill-intl-idn",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-idn.git",
-                "reference": "639084e360537a19f9ee352433b84ce831f3d2da"
+                "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da",
-                "reference": "639084e360537a19f9ee352433b84ce831f3d2da",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
+                "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
                 "shasum": ""
             },
             "require": {
@@ -6973,9 +7311,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -7018,7 +7353,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -7034,20 +7369,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-05-31T15:07:36+00:00"
         },
         {
             "name": "symfony/polyfill-intl-normalizer",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
-                "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
+                "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
-                "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
+                "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
                 "shasum": ""
             },
             "require": {
@@ -7058,9 +7393,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -7102,7 +7434,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -7118,20 +7450,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-05-31T15:07:36+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
+                "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
-                "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+                "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
                 "shasum": ""
             },
             "require": {
@@ -7145,9 +7477,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -7185,7 +7514,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -7201,20 +7530,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-06-19T12:30:46+00:00"
         },
         {
             "name": "symfony/polyfill-php72",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php72.git",
-                "reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
+                "reference": "10112722600777e02d2745716b70c5db4ca70442"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
-                "reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442",
+                "reference": "10112722600777e02d2745716b70c5db4ca70442",
                 "shasum": ""
             },
             "require": {
@@ -7222,9 +7551,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -7261,7 +7587,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-php72/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -7277,20 +7603,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-06-19T12:30:46+00:00"
         },
         {
             "name": "symfony/polyfill-php80",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php80.git",
-                "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
+                "reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
-                "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
+                "reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
                 "shasum": ""
             },
             "require": {
@@ -7298,9 +7624,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -7344,7 +7667,83 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-05-31T15:07:36+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php83",
+            "version": "v1.30.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php83.git",
+                "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
+                "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php83\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -7360,20 +7759,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-06-19T12:35:24+00:00"
         },
         {
             "name": "symfony/polyfill-uuid",
-            "version": "v1.27.0",
+            "version": "v1.30.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-uuid.git",
-                "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166"
+                "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/f3cf1a645c2734236ed1e2e671e273eeb3586166",
-                "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166",
+                "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2ba1f33797470debcda07fe9dce20a0003df18e9",
+                "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9",
                 "shasum": ""
             },
             "require": {
@@ -7387,9 +7786,6 @@
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-main": "1.27-dev"
-                },
                 "thanks": {
                     "name": "symfony/polyfill",
                     "url": "https://github.com/symfony/polyfill"
@@ -7426,7 +7822,7 @@
                 "uuid"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-uuid/tree/v1.27.0"
+                "source": "https://github.com/symfony/polyfill-uuid/tree/v1.30.0"
             },
             "funding": [
                 {
@@ -7442,24 +7838,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-03T14:55:06+00:00"
+            "time": "2024-05-31T15:07:36+00:00"
         },
         {
             "name": "symfony/process",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e"
+                "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
-                "reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
+                "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca",
+                "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1"
+                "php": ">=8.2"
             },
             "type": "library",
             "autoload": {
@@ -7487,7 +7883,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v6.2.10"
+                "source": "https://github.com/symfony/process/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -7503,45 +7899,38 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-18T13:56:57+00:00"
+            "time": "2024-07-26T12:44:47+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v6.2.8",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "69062e2823f03b82265d73a966999660f0e1e404"
+                "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/69062e2823f03b82265d73a966999660f0e1e404",
-                "reference": "69062e2823f03b82265d73a966999660f0e1e404",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
+                "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1"
+                "php": ">=8.2",
+                "symfony/deprecation-contracts": "^2.5|^3"
             },
             "conflict": {
-                "doctrine/annotations": "<1.12",
-                "symfony/config": "<6.2",
-                "symfony/dependency-injection": "<5.4",
-                "symfony/yaml": "<5.4"
+                "symfony/config": "<6.4",
+                "symfony/dependency-injection": "<6.4",
+                "symfony/yaml": "<6.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"
+                "symfony/config": "^6.4|^7.0",
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/expression-language": "^6.4|^7.0",
+                "symfony/http-foundation": "^6.4|^7.0",
+                "symfony/yaml": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -7575,7 +7964,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v6.2.8"
+                "source": "https://github.com/symfony/routing/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -7591,36 +7980,34 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-14T15:00:05+00:00"
+            "time": "2024-07-17T06:10:24+00:00"
         },
         {
             "name": "symfony/service-contracts",
-            "version": "v3.2.1",
+            "version": "v3.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/service-contracts.git",
-                "reference": "a8c9cedf55f314f3a186041d19537303766df09a"
+                "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a",
-                "reference": "a8c9cedf55f314f3a186041d19537303766df09a",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f",
+                "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.1",
-                "psr/container": "^2.0"
+                "psr/container": "^1.1|^2.0",
+                "symfony/deprecation-contracts": "^2.5|^3"
             },
             "conflict": {
                 "ext-psr": "<1.1|>=2"
             },
-            "suggest": {
-                "symfony/service-implementation": ""
-            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "3.3-dev"
+                    "dev-main": "3.5-dev"
                 },
                 "thanks": {
                     "name": "symfony/contracts",
@@ -7660,7 +8047,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/service-contracts/tree/v3.2.1"
+                "source": "https://github.com/symfony/service-contracts/tree/v3.5.0"
             },
             "funding": [
                 {
@@ -7676,38 +8063,39 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-01T10:32:47+00:00"
+            "time": "2024-04-18T09:32:20+00:00"
         },
         {
             "name": "symfony/string",
-            "version": "v6.2.8",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
+                "reference": "ea272a882be7f20cad58d5d78c215001617b7f07"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
-                "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
+                "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07",
+                "reference": "ea272a882be7f20cad58d5d78c215001617b7f07",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "symfony/polyfill-ctype": "~1.8",
                 "symfony/polyfill-intl-grapheme": "~1.0",
                 "symfony/polyfill-intl-normalizer": "~1.0",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "conflict": {
-                "symfony/translation-contracts": "<2.0"
+                "symfony/translation-contracts": "<2.5"
             },
             "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"
+                "symfony/emoji": "^7.1",
+                "symfony/error-handler": "^6.4|^7.0",
+                "symfony/http-client": "^6.4|^7.0",
+                "symfony/intl": "^6.4|^7.0",
+                "symfony/translation-contracts": "^2.5|^3.0",
+                "symfony/var-exporter": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -7746,7 +8134,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v6.2.8"
+                "source": "https://github.com/symfony/string/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -7762,58 +8150,54 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-20T16:06:02+00:00"
+            "time": "2024-07-22T10:25:37+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v6.2.8",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5"
+                "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/817535dbb1721df8b3a8f2489dc7e50bcd6209b5",
-                "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1",
+                "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "symfony/polyfill-mbstring": "~1.0",
-                "symfony/translation-contracts": "^2.3|^3.0"
+                "symfony/translation-contracts": "^2.5|^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"
+                "symfony/config": "<6.4",
+                "symfony/console": "<6.4",
+                "symfony/dependency-injection": "<6.4",
+                "symfony/http-client-contracts": "<2.5",
+                "symfony/http-kernel": "<6.4",
+                "symfony/service-contracts": "<2.5",
+                "symfony/twig-bundle": "<6.4",
+                "symfony/yaml": "<6.4"
             },
             "provide": {
                 "symfony/translation-implementation": "2.3|3.0"
             },
             "require-dev": {
-                "nikic/php-parser": "^4.13",
+                "nikic/php-parser": "^4.18|^5.0",
                 "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/config": "^6.4|^7.0",
+                "symfony/console": "^6.4|^7.0",
+                "symfony/dependency-injection": "^6.4|^7.0",
+                "symfony/finder": "^6.4|^7.0",
+                "symfony/http-client-contracts": "^2.5|^3.0",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/intl": "^6.4|^7.0",
                 "symfony/polyfill-intl-icu": "^1.21",
-                "symfony/routing": "^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": ""
+                "symfony/routing": "^6.4|^7.0",
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/yaml": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -7844,7 +8228,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v6.2.8"
+                "source": "https://github.com/symfony/translation/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -7860,32 +8244,29 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-31T09:14:44+00:00"
+            "time": "2024-07-26T12:41:01+00:00"
         },
         {
             "name": "symfony/translation-contracts",
-            "version": "v3.2.1",
+            "version": "v3.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation-contracts.git",
-                "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8"
+                "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dfec258b9dd17a6b24420d464c43bffe347441c8",
-                "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8",
+                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a",
+                "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.1"
             },
-            "suggest": {
-                "symfony/translation-implementation": ""
-            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "3.3-dev"
+                    "dev-main": "3.5-dev"
                 },
                 "thanks": {
                     "name": "symfony/contracts",
@@ -7925,7 +8306,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/translation-contracts/tree/v3.2.1"
+                "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0"
             },
             "funding": [
                 {
@@ -7941,28 +8322,28 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-01T10:32:47+00:00"
+            "time": "2024-04-18T09:32:20+00:00"
         },
         {
             "name": "symfony/uid",
-            "version": "v6.2.7",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/uid.git",
-                "reference": "d30c72a63897cfa043e1de4d4dd2ffa9ecefcdc0"
+                "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/uid/zipball/d30c72a63897cfa043e1de4d4dd2ffa9ecefcdc0",
-                "reference": "d30c72a63897cfa043e1de4d4dd2ffa9ecefcdc0",
+                "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277",
+                "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "symfony/polyfill-uuid": "^1.15"
             },
             "require-dev": {
-                "symfony/console": "^5.4|^6.0"
+                "symfony/console": "^6.4|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -7999,7 +8380,7 @@
                 "uuid"
             ],
             "support": {
-                "source": "https://github.com/symfony/uid/tree/v6.2.7"
+                "source": "https://github.com/symfony/uid/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -8015,41 +8396,36 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-14T08:44:56+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v6.2.10",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "41a750a23412ca76fdbbf5096943b4134272c1ab"
+                "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41a750a23412ca76fdbbf5096943b4134272c1ab",
-                "reference": "41a750a23412ca76fdbbf5096943b4134272c1ab",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f",
+                "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "conflict": {
-                "phpunit/phpunit": "<5.4.3",
-                "symfony/console": "<5.4"
+                "symfony/console": "<6.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"
+                "symfony/console": "^6.4|^7.0",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/process": "^6.4|^7.0",
+                "symfony/uid": "^6.4|^7.0",
+                "twig/twig": "^3.0.4"
             },
             "bin": [
                 "Resources/bin/var-dump-server"
@@ -8087,7 +8463,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v6.2.10"
+                "source": "https://github.com/symfony/var-dumper/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -8103,27 +8479,27 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-18T13:46:08+00:00"
+            "time": "2024-07-26T12:41:01+00:00"
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
-            "version": "2.2.6",
+            "version": "v2.2.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
-                "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c"
+                "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c",
-                "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c",
+                "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb",
+                "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-libxml": "*",
                 "php": "^5.5 || ^7.0 || ^8.0",
-                "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
+                "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
             },
             "require-dev": {
                 "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
@@ -8154,37 +8530,37 @@
             "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
             "support": {
                 "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
-                "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6"
+                "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7"
             },
-            "time": "2023-01-03T09:29:04+00:00"
+            "time": "2023-12-08T13:03:43+00:00"
         },
         {
             "name": "vlucas/phpdotenv",
-            "version": "v5.5.0",
+            "version": "v5.6.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/vlucas/phpdotenv.git",
-                "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7"
+                "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
-                "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
+                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2",
+                "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2",
                 "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"
+                "graham-campbell/result-type": "^1.1.3",
+                "php": "^7.2.5 || ^8.0",
+                "phpoption/phpoption": "^1.9.3",
+                "symfony/polyfill-ctype": "^1.24",
+                "symfony/polyfill-mbstring": "^1.24",
+                "symfony/polyfill-php80": "^1.24"
             },
             "require-dev": {
-                "bamarni/composer-bin-plugin": "^1.4.1",
+                "bamarni/composer-bin-plugin": "^1.8.2",
                 "ext-filter": "*",
-                "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25"
+                "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
             },
             "suggest": {
                 "ext-filter": "Required to use the boolean validator."
@@ -8193,10 +8569,10 @@
             "extra": {
                 "bamarni-bin": {
                     "bin-links": true,
-                    "forward-command": true
+                    "forward-command": false
                 },
                 "branch-alias": {
-                    "dev-master": "5.5-dev"
+                    "dev-master": "5.6-dev"
                 }
             },
             "autoload": {
@@ -8228,7 +8604,7 @@
             ],
             "support": {
                 "issues": "https://github.com/vlucas/phpdotenv/issues",
-                "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0"
+                "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1"
             },
             "funding": [
                 {
@@ -8240,7 +8616,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-10-16T01:01:54+00:00"
+            "time": "2024-07-20T21:52:34+00:00"
         },
         {
             "name": "voku/portable-ascii",
@@ -8376,39 +8752,46 @@
         },
         {
             "name": "yajra/laravel-datatables-oracle",
-            "version": "v9.21.2",
+            "version": "v11.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/yajra/laravel-datatables.git",
-                "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a"
+                "reference": "78ecbc43025a24b92c307664c0cf395fea56c215"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/a7fd01f06282923e9c63fa27fe6b391e21dc321a",
-                "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a",
+                "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/78ecbc43025a24b92c307664c0cf395fea56c215",
+                "reference": "78ecbc43025a24b92c307664c0cf395fea56c215",
                 "shasum": ""
             },
             "require": {
-                "illuminate/database": "5.8.*|^6|^7|^8|^9",
-                "illuminate/filesystem": "5.8.*|^6|^7|^8|^9",
-                "illuminate/http": "5.8.*|^6|^7|^8|^9",
-                "illuminate/support": "5.8.*|^6|^7|^8|^9",
-                "illuminate/view": "5.8.*|^6|^7|^8|^9",
-                "php": "^7.1.3|^8"
+                "illuminate/database": "^11",
+                "illuminate/filesystem": "^11",
+                "illuminate/http": "^11",
+                "illuminate/support": "^11",
+                "illuminate/view": "^11",
+                "php": "^8.2"
             },
             "require-dev": {
-                "orchestra/testbench": "^3.8|^4.0|^5.0|^6.0|^7.0"
+                "algolia/algoliasearch-client-php": "^3.4.1",
+                "larastan/larastan": "^2.9.1",
+                "laravel/pint": "^1.14",
+                "laravel/scout": "^10.8.3",
+                "meilisearch/meilisearch-php": "^1.6.1",
+                "orchestra/testbench": "^9",
+                "rector/rector": "^1.0"
             },
             "suggest": {
                 "yajra/laravel-datatables-buttons": "Plugin for server-side exporting of dataTables.",
                 "yajra/laravel-datatables-editor": "Plugin to use DataTables Editor (requires a license).",
+                "yajra/laravel-datatables-export": "Plugin for server-side exporting using livewire and queue worker.",
                 "yajra/laravel-datatables-fractal": "Plugin for server-side response using Fractal.",
                 "yajra/laravel-datatables-html": "Plugin for server-side HTML builder of dataTables."
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "9.0-dev"
+                    "dev-master": "11.x-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -8437,62 +8820,59 @@
                     "email": "aqangeles@gmail.com"
                 }
             ],
-            "description": "jQuery DataTables API for Laravel 5|6|7|8|9",
+            "description": "jQuery DataTables API for Laravel",
             "keywords": [
                 "datatables",
                 "jquery",
-                "laravel"
+                "laravel",
+                "yajra"
             ],
             "support": {
                 "issues": "https://github.com/yajra/laravel-datatables/issues",
-                "source": "https://github.com/yajra/laravel-datatables/tree/v9.21.2"
+                "source": "https://github.com/yajra/laravel-datatables/tree/v11.1.3"
             },
             "funding": [
                 {
-                    "url": "https://www.paypal.me/yajra",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://www.patreon.com/yajra",
-                    "type": "patreon"
+                    "url": "https://github.com/sponsors/yajra",
+                    "type": "github"
                 }
             ],
-            "time": "2022-07-12T04:48:03+00:00"
+            "time": "2024-07-15T04:47:52+00:00"
         }
     ],
     "packages-dev": [
         {
             "name": "barryvdh/laravel-debugbar",
-            "version": "v3.8.1",
+            "version": "v3.13.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-debugbar.git",
-                "reference": "aff3235fecb4104203b1e62c32239c56530eee32"
+                "reference": "92d86be45ee54edff735e46856f64f14b6a8bb07"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/aff3235fecb4104203b1e62c32239c56530eee32",
-                "reference": "aff3235fecb4104203b1e62c32239c56530eee32",
+                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/92d86be45ee54edff735e46856f64f14b6a8bb07",
+                "reference": "92d86be45ee54edff735e46856f64f14b6a8bb07",
                 "shasum": ""
             },
             "require": {
-                "illuminate/routing": "^9|^10",
-                "illuminate/session": "^9|^10",
-                "illuminate/support": "^9|^10",
-                "maximebf/debugbar": "^1.18.2",
+                "illuminate/routing": "^9|^10|^11",
+                "illuminate/session": "^9|^10|^11",
+                "illuminate/support": "^9|^10|^11",
+                "maximebf/debugbar": "~1.22.0",
                 "php": "^8.0",
-                "symfony/finder": "^6"
+                "symfony/finder": "^6|^7"
             },
             "require-dev": {
                 "mockery/mockery": "^1.3.3",
-                "orchestra/testbench-dusk": "^5|^6|^7|^8",
-                "phpunit/phpunit": "^8.5.30|^9.0",
+                "orchestra/testbench-dusk": "^5|^6|^7|^8|^9",
+                "phpunit/phpunit": "^9.6|^10.5",
                 "squizlabs/php_codesniffer": "^3.5"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.8-dev"
+                    "dev-master": "3.13-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -8531,7 +8911,7 @@
             ],
             "support": {
                 "issues": "https://github.com/barryvdh/laravel-debugbar/issues",
-                "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.8.1"
+                "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.13.5"
             },
             "funding": [
                 {
@@ -8543,90 +8923,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-21T14:21:02+00:00"
-        },
-        {
-            "name": "doctrine/instantiator",
-            "version": "2.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/doctrine/instantiator.git",
-                "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
-                "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^8.1"
-            },
-            "require-dev": {
-                "doctrine/coding-standard": "^11",
-                "ext-pdo": "*",
-                "ext-phar": "*",
-                "phpbench/phpbench": "^1.2",
-                "phpstan/phpstan": "^1.9.4",
-                "phpstan/phpstan-phpunit": "^1.3",
-                "phpunit/phpunit": "^9.5.27",
-                "vimeo/psalm": "^5.4"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-4": {
-                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Marco Pivetta",
-                    "email": "ocramius@gmail.com",
-                    "homepage": "https://ocramius.github.io/"
-                }
-            ],
-            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
-            "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
-            "keywords": [
-                "constructor",
-                "instantiate"
-            ],
-            "support": {
-                "issues": "https://github.com/doctrine/instantiator/issues",
-                "source": "https://github.com/doctrine/instantiator/tree/2.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%2Finstantiator",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2022-12-30T00:23:10+00:00"
+            "time": "2024-04-12T11:20:37+00:00"
         },
         {
             "name": "fakerphp/faker",
-            "version": "v1.21.0",
+            "version": "v1.23.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FakerPHP/Faker.git",
-                "reference": "92efad6a967f0b79c499705c69b662f738cc9e4d"
+                "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/92efad6a967f0b79c499705c69b662f738cc9e4d",
-                "reference": "92efad6a967f0b79c499705c69b662f738cc9e4d",
+                "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b",
+                "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b",
                 "shasum": ""
             },
             "require": {
@@ -8652,11 +8962,6 @@
                 "ext-mbstring": "Required for multibyte Unicode string functionality."
             },
             "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-main": "v1.21-dev"
-                }
-            },
             "autoload": {
                 "psr-4": {
                     "Faker\\": "src/Faker/"
@@ -8679,22 +8984,22 @@
             ],
             "support": {
                 "issues": "https://github.com/FakerPHP/Faker/issues",
-                "source": "https://github.com/FakerPHP/Faker/tree/v1.21.0"
+                "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1"
             },
-            "time": "2022-12-13T13:54:32+00:00"
+            "time": "2024-01-02T13:46:09+00:00"
         },
         {
             "name": "filp/whoops",
-            "version": "2.15.2",
+            "version": "2.15.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filp/whoops.git",
-                "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73"
+                "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filp/whoops/zipball/aac9304c5ed61bf7b1b7a6064bf9806ab842ce73",
-                "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73",
+                "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
+                "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
                 "shasum": ""
             },
             "require": {
@@ -8744,7 +9049,7 @@
             ],
             "support": {
                 "issues": "https://github.com/filp/whoops/issues",
-                "source": "https://github.com/filp/whoops/tree/2.15.2"
+                "source": "https://github.com/filp/whoops/tree/2.15.4"
             },
             "funding": [
                 {
@@ -8752,7 +9057,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-04-12T12:00:00+00:00"
+            "time": "2023-11-03T12:00:00+00:00"
         },
         {
             "name": "hamcrest/hamcrest-php",
@@ -8807,27 +9112,28 @@
         },
         {
             "name": "laravel/sail",
-            "version": "v1.21.5",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/sail.git",
-                "reference": "27af207bb1c53faddcba34c7528b3e969f6a646d"
+                "reference": "48d89608a3bb5be763c9bb87121d31e7da27c1cb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/sail/zipball/27af207bb1c53faddcba34c7528b3e969f6a646d",
-                "reference": "27af207bb1c53faddcba34c7528b3e969f6a646d",
+                "url": "https://api.github.com/repos/laravel/sail/zipball/48d89608a3bb5be763c9bb87121d31e7da27c1cb",
+                "reference": "48d89608a3bb5be763c9bb87121d31e7da27c1cb",
                 "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"
+                "illuminate/console": "^9.52.16|^10.0|^11.0",
+                "illuminate/contracts": "^9.52.16|^10.0|^11.0",
+                "illuminate/support": "^9.52.16|^10.0|^11.0",
+                "php": "^8.0",
+                "symfony/console": "^6.0|^7.0",
+                "symfony/yaml": "^6.0|^7.0"
             },
             "require-dev": {
-                "orchestra/testbench": "^6.0|^7.0|^8.0",
+                "orchestra/testbench": "^7.0|^8.0|^9.0",
                 "phpstan/phpstan": "^1.10"
             },
             "bin": [
@@ -8835,9 +9141,6 @@
             ],
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-master": "1.x-dev"
-                },
                 "laravel": {
                     "providers": [
                         "Laravel\\Sail\\SailServiceProvider"
@@ -8868,29 +9171,31 @@
                 "issues": "https://github.com/laravel/sail/issues",
                 "source": "https://github.com/laravel/sail"
             },
-            "time": "2023-04-24T13:29:38+00:00"
+            "time": "2024-07-22T14:36:50+00:00"
         },
         {
             "name": "maximebf/debugbar",
-            "version": "v1.18.2",
+            "version": "v1.22.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/maximebf/php-debugbar.git",
-                "reference": "17dcf3f6ed112bb85a37cf13538fd8de49f5c274"
+                "reference": "7aa9a27a0b1158ed5ad4e7175e8d3aee9a818b96"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/17dcf3f6ed112bb85a37cf13538fd8de49f5c274",
-                "reference": "17dcf3f6ed112bb85a37cf13538fd8de49f5c274",
+                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/7aa9a27a0b1158ed5ad4e7175e8d3aee9a818b96",
+                "reference": "7aa9a27a0b1158ed5ad4e7175e8d3aee9a818b96",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.1|^8",
+                "php": "^7.2|^8",
                 "psr/log": "^1|^2|^3",
-                "symfony/var-dumper": "^4|^5|^6"
+                "symfony/var-dumper": "^4|^5|^6|^7"
             },
             "require-dev": {
-                "phpunit/phpunit": ">=7.5.20 <10.0",
+                "dbrekelmans/bdi": "^1",
+                "phpunit/phpunit": "^8|^9",
+                "symfony/panther": "^1|^2.1",
                 "twig/twig": "^1.38|^2.7|^3.0"
             },
             "suggest": {
@@ -8901,7 +9206,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.18-dev"
+                    "dev-master": "1.22-dev"
                 }
             },
             "autoload": {
@@ -8932,44 +9237,44 @@
             ],
             "support": {
                 "issues": "https://github.com/maximebf/php-debugbar/issues",
-                "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.2"
+                "source": "https://github.com/maximebf/php-debugbar/tree/v1.22.3"
             },
-            "time": "2023-02-04T15:27:00+00:00"
+            "time": "2024-04-03T19:39:26+00:00"
         },
         {
             "name": "mockery/mockery",
-            "version": "1.5.1",
+            "version": "1.6.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mockery/mockery.git",
-                "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e"
+                "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mockery/mockery/zipball/e92dcc83d5a51851baf5f5591d32cb2b16e3684e",
-                "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e",
+                "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699",
+                "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699",
                 "shasum": ""
             },
             "require": {
                 "hamcrest/hamcrest-php": "^2.0.1",
                 "lib-pcre": ">=7.0",
-                "php": "^7.3 || ^8.0"
+                "php": ">=7.3"
             },
             "conflict": {
                 "phpunit/phpunit": "<8.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^8.5 || ^9.3"
+                "phpunit/phpunit": "^8.5 || ^9.6.17",
+                "symplify/easy-coding-standard": "^12.1.14"
             },
             "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.4.x-dev"
-                }
-            },
             "autoload": {
-                "psr-0": {
-                    "Mockery": "library/"
+                "files": [
+                    "library/helpers.php",
+                    "library/Mockery.php"
+                ],
+                "psr-4": {
+                    "Mockery\\": "library/Mockery"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -8980,12 +9285,20 @@
                 {
                     "name": "Pádraic Brady",
                     "email": "padraic.brady@gmail.com",
-                    "homepage": "http://blog.astrumfutura.com"
+                    "homepage": "https://github.com/padraic",
+                    "role": "Author"
                 },
                 {
                     "name": "Dave Marshall",
                     "email": "dave.marshall@atstsolutions.co.uk",
-                    "homepage": "http://davedevelopment.co.uk"
+                    "homepage": "https://davedevelopment.co.uk",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Nathanael Esayeas",
+                    "email": "nathanael.esayeas@protonmail.com",
+                    "homepage": "https://github.com/ghostwriter",
+                    "role": "Lead Developer"
                 }
             ],
             "description": "Mockery is a simple yet flexible PHP mock object framework",
@@ -9003,23 +9316,26 @@
                 "testing"
             ],
             "support": {
+                "docs": "https://docs.mockery.io/",
                 "issues": "https://github.com/mockery/mockery/issues",
-                "source": "https://github.com/mockery/mockery/tree/1.5.1"
+                "rss": "https://github.com/mockery/mockery/releases.atom",
+                "security": "https://github.com/mockery/mockery/security/advisories",
+                "source": "https://github.com/mockery/mockery"
             },
-            "time": "2022-09-07T15:32:08+00:00"
+            "time": "2024-05-16T03:13:13+00:00"
         },
         {
             "name": "myclabs/deep-copy",
-            "version": "1.11.1",
+            "version": "1.12.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/myclabs/DeepCopy.git",
-                "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+                "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
-                "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
+                "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
                 "shasum": ""
             },
             "require": {
@@ -9027,11 +9343,12 @@
             },
             "conflict": {
                 "doctrine/collections": "<1.6.8",
-                "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+                "doctrine/common": "<2.13.3 || >=3 <3.2.2"
             },
             "require-dev": {
                 "doctrine/collections": "^1.6.8",
                 "doctrine/common": "^2.13.3 || ^3.2.2",
+                "phpspec/prophecy": "^1.10",
                 "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
             },
             "type": "library",
@@ -9057,7 +9374,7 @@
             ],
             "support": {
                 "issues": "https://github.com/myclabs/DeepCopy/issues",
-                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0"
             },
             "funding": [
                 {
@@ -9065,49 +9382,58 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-03-08T13:26:56+00:00"
+            "time": "2024-06-12T14:39:25+00:00"
         },
         {
             "name": "nunomaduro/collision",
-            "version": "v6.4.0",
+            "version": "v8.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nunomaduro/collision.git",
-                "reference": "f05978827b9343cba381ca05b8c7deee346b6015"
+                "reference": "b49f5b2891ce52726adfd162841c69d4e4c84229"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f05978827b9343cba381ca05b8c7deee346b6015",
-                "reference": "f05978827b9343cba381ca05b8c7deee346b6015",
+                "url": "https://api.github.com/repos/nunomaduro/collision/zipball/b49f5b2891ce52726adfd162841c69d4e4c84229",
+                "reference": "b49f5b2891ce52726adfd162841c69d4e4c84229",
                 "shasum": ""
             },
             "require": {
-                "filp/whoops": "^2.14.5",
-                "php": "^8.0.0",
-                "symfony/console": "^6.0.2"
+                "filp/whoops": "^2.15.4",
+                "nunomaduro/termwind": "^2.0.1",
+                "php": "^8.2.0",
+                "symfony/console": "^7.1.2"
+            },
+            "conflict": {
+                "laravel/framework": "<11.0.0 || >=12.0.0",
+                "phpunit/phpunit": "<10.5.1 || >=12.0.0"
             },
             "require-dev": {
-                "brianium/paratest": "^6.4.1",
-                "laravel/framework": "^9.26.1",
-                "laravel/pint": "^1.1.1",
-                "nunomaduro/larastan": "^1.0.3",
-                "nunomaduro/mock-final-classes": "^1.1.0",
-                "orchestra/testbench": "^7.7",
-                "phpunit/phpunit": "^9.5.23",
-                "spatie/ignition": "^1.4.1"
+                "larastan/larastan": "^2.9.8",
+                "laravel/framework": "^11.16.0",
+                "laravel/pint": "^1.16.2",
+                "laravel/sail": "^1.30.2",
+                "laravel/sanctum": "^4.0.2",
+                "laravel/tinker": "^2.9.0",
+                "orchestra/testbench-core": "^9.2.1",
+                "pestphp/pest": "^2.34.9 || ^3.0.0",
+                "sebastian/environment": "^6.1.0 || ^7.0.0"
             },
             "type": "library",
             "extra": {
-                "branch-alias": {
-                    "dev-develop": "6.x-dev"
-                },
                 "laravel": {
                     "providers": [
                         "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider"
                     ]
+                },
+                "branch-alias": {
+                    "dev-8.x": "8.x-dev"
                 }
             },
             "autoload": {
+                "files": [
+                    "./src/Adapters/Phpunit/Autoload.php"
+                ],
                 "psr-4": {
                     "NunoMaduro\\Collision\\": "src/"
                 }
@@ -9153,24 +9479,25 @@
                     "type": "patreon"
                 }
             ],
-            "time": "2023-01-03T12:54:54+00:00"
+            "time": "2024-07-16T22:41:01+00:00"
         },
         {
             "name": "phar-io/manifest",
-            "version": "2.0.3",
+            "version": "2.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phar-io/manifest.git",
-                "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+                "reference": "54750ef60c58e43759730615a392c31c80e23176"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
-                "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+                "reference": "54750ef60c58e43759730615a392c31c80e23176",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
+                "ext-libxml": "*",
                 "ext-phar": "*",
                 "ext-xmlwriter": "*",
                 "phar-io/version": "^3.0.1",
@@ -9211,9 +9538,15 @@
             "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"
+                "source": "https://github.com/phar-io/manifest/tree/2.0.4"
             },
-            "time": "2021-07-20T11:28:43+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/theseer",
+                    "type": "github"
+                }
+            ],
+            "time": "2024-03-03T12:33:53+00:00"
         },
         {
             "name": "phar-io/version",
@@ -9268,35 +9601,35 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "9.2.26",
+            "version": "11.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1"
+                "reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
-                "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/19b6365ab8b59a64438c0c3f4241feeb480c9861",
+                "reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-libxml": "*",
                 "ext-xmlwriter": "*",
-                "nikic/php-parser": "^4.15",
-                "php": ">=7.3",
-                "phpunit/php-file-iterator": "^3.0.3",
-                "phpunit/php-text-template": "^2.0.2",
-                "sebastian/code-unit-reverse-lookup": "^2.0.2",
-                "sebastian/complexity": "^2.0",
-                "sebastian/environment": "^5.1.2",
-                "sebastian/lines-of-code": "^1.0.3",
-                "sebastian/version": "^3.0.1",
+                "nikic/php-parser": "^5.0",
+                "php": ">=8.2",
+                "phpunit/php-file-iterator": "^5.0",
+                "phpunit/php-text-template": "^4.0",
+                "sebastian/code-unit-reverse-lookup": "^4.0",
+                "sebastian/complexity": "^4.0",
+                "sebastian/environment": "^7.0",
+                "sebastian/lines-of-code": "^3.0",
+                "sebastian/version": "^5.0",
                 "theseer/tokenizer": "^1.2.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "suggest": {
                 "ext-pcov": "PHP extension that provides line coverage",
@@ -9305,7 +9638,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "9.2-dev"
+                    "dev-main": "11.0-dev"
                 }
             },
             "autoload": {
@@ -9333,7 +9666,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26"
+                "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.5"
             },
             "funding": [
                 {
@@ -9341,32 +9675,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-03-06T12:58:08+00:00"
+            "time": "2024-07-03T05:05:37+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "3.0.6",
+            "version": "5.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+                "reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
-                "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6ed896bf50bbbfe4d504a33ed5886278c78e4a26",
+                "reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.0-dev"
+                    "dev-main": "5.0-dev"
                 }
             },
             "autoload": {
@@ -9393,7 +9727,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
-                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+                "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
+                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.1"
             },
             "funding": [
                 {
@@ -9401,28 +9736,28 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-12-02T12:48:52+00:00"
+            "time": "2024-07-03T05:06:37+00:00"
         },
         {
             "name": "phpunit/php-invoker",
-            "version": "3.1.1",
+            "version": "5.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-invoker.git",
-                "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+                "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
-                "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2",
+                "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
                 "ext-pcntl": "*",
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "suggest": {
                 "ext-pcntl": "*"
@@ -9430,7 +9765,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-main": "5.0-dev"
                 }
             },
             "autoload": {
@@ -9456,7 +9791,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
-                "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+                "security": "https://github.com/sebastianbergmann/php-invoker/security/policy",
+                "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1"
             },
             "funding": [
                 {
@@ -9464,32 +9800,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-09-28T05:58:55+00:00"
+            "time": "2024-07-03T05:07:44+00:00"
         },
         {
             "name": "phpunit/php-text-template",
-            "version": "2.0.4",
+            "version": "4.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-text-template.git",
-                "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+                "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
-                "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964",
+                "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-main": "4.0-dev"
                 }
             },
             "autoload": {
@@ -9515,7 +9851,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
-                "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+                "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
+                "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1"
             },
             "funding": [
                 {
@@ -9523,32 +9860,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T05:33:50+00:00"
+            "time": "2024-07-03T05:08:43+00:00"
         },
         {
             "name": "phpunit/php-timer",
-            "version": "5.0.3",
+            "version": "7.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-timer.git",
-                "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+                "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
-                "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
+                "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "5.0-dev"
+                    "dev-main": "7.0-dev"
                 }
             },
             "autoload": {
@@ -9574,7 +9911,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-timer/issues",
-                "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+                "security": "https://github.com/sebastianbergmann/php-timer/security/policy",
+                "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1"
             },
             "funding": [
                 {
@@ -9582,54 +9920,51 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T13:16:10+00:00"
+            "time": "2024-07-03T05:09:35+00:00"
         },
         {
             "name": "phpunit/phpunit",
-            "version": "9.6.7",
+            "version": "11.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2"
+                "reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
-                "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a7a29e8d3113806f18f99d670f580a30e8ffff39",
+                "reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39",
                 "shasum": ""
             },
             "require": {
-                "doctrine/instantiator": "^1.3.1 || ^2",
                 "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": ">=7.3",
-                "phpunit/php-code-coverage": "^9.2.13",
-                "phpunit/php-file-iterator": "^3.0.5",
-                "phpunit/php-invoker": "^3.1.1",
-                "phpunit/php-text-template": "^2.0.3",
-                "phpunit/php-timer": "^5.0.2",
-                "sebastian/cli-parser": "^1.0.1",
-                "sebastian/code-unit": "^1.0.6",
-                "sebastian/comparator": "^4.0.8",
-                "sebastian/diff": "^4.0.3",
-                "sebastian/environment": "^5.1.3",
-                "sebastian/exporter": "^4.0.5",
-                "sebastian/global-state": "^5.0.1",
-                "sebastian/object-enumerator": "^4.0.3",
-                "sebastian/resource-operations": "^3.0.3",
-                "sebastian/type": "^3.2",
-                "sebastian/version": "^3.0.2"
+                "myclabs/deep-copy": "^1.12.0",
+                "phar-io/manifest": "^2.0.4",
+                "phar-io/version": "^3.2.1",
+                "php": ">=8.2",
+                "phpunit/php-code-coverage": "^11.0.5",
+                "phpunit/php-file-iterator": "^5.0.1",
+                "phpunit/php-invoker": "^5.0.1",
+                "phpunit/php-text-template": "^4.0.1",
+                "phpunit/php-timer": "^7.0.1",
+                "sebastian/cli-parser": "^3.0.2",
+                "sebastian/code-unit": "^3.0.1",
+                "sebastian/comparator": "^6.0.1",
+                "sebastian/diff": "^6.0.2",
+                "sebastian/environment": "^7.2.0",
+                "sebastian/exporter": "^6.1.3",
+                "sebastian/global-state": "^7.0.2",
+                "sebastian/object-enumerator": "^6.0.1",
+                "sebastian/type": "^5.0.1",
+                "sebastian/version": "^5.0.1"
             },
             "suggest": {
-                "ext-soap": "To be able to generate mocks based on WSDL files",
-                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+                "ext-soap": "To be able to generate mocks based on WSDL files"
             },
             "bin": [
                 "phpunit"
@@ -9637,7 +9972,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "9.6-dev"
+                    "dev-main": "11.2-dev"
                 }
             },
             "autoload": {
@@ -9669,7 +10004,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.8"
             },
             "funding": [
                 {
@@ -9685,32 +10020,32 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-14T08:58:40+00:00"
+            "time": "2024-07-18T14:56:37+00:00"
         },
         {
             "name": "sebastian/cli-parser",
-            "version": "1.0.1",
+            "version": "3.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/cli-parser.git",
-                "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+                "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
-                "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180",
+                "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0-dev"
+                    "dev-main": "3.0-dev"
                 }
             },
             "autoload": {
@@ -9733,7 +10068,8 @@
             "homepage": "https://github.com/sebastianbergmann/cli-parser",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
-                "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+                "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
+                "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2"
             },
             "funding": [
                 {
@@ -9741,32 +10077,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-09-28T06:08:49+00:00"
+            "time": "2024-07-03T04:41:36+00:00"
         },
         {
             "name": "sebastian/code-unit",
-            "version": "1.0.8",
+            "version": "3.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/code-unit.git",
-                "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+                "reference": "6bb7d09d6623567178cf54126afa9c2310114268"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
-                "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268",
+                "reference": "6bb7d09d6623567178cf54126afa9c2310114268",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0-dev"
+                    "dev-main": "3.0-dev"
                 }
             },
             "autoload": {
@@ -9789,7 +10125,8 @@
             "homepage": "https://github.com/sebastianbergmann/code-unit",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/code-unit/issues",
-                "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+                "security": "https://github.com/sebastianbergmann/code-unit/security/policy",
+                "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1"
             },
             "funding": [
                 {
@@ -9797,32 +10134,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T13:08:54+00:00"
+            "time": "2024-07-03T04:44:28+00:00"
         },
         {
             "name": "sebastian/code-unit-reverse-lookup",
-            "version": "2.0.3",
+            "version": "4.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
-                "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+                "reference": "183a9b2632194febd219bb9246eee421dad8d45e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
-                "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e",
+                "reference": "183a9b2632194febd219bb9246eee421dad8d45e",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-main": "4.0-dev"
                 }
             },
             "autoload": {
@@ -9844,7 +10181,8 @@
             "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/2.0.3"
+                "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy",
+                "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1"
             },
             "funding": [
                 {
@@ -9852,34 +10190,36 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-09-28T05:30:19+00:00"
+            "time": "2024-07-03T04:45:54+00:00"
         },
         {
             "name": "sebastian/comparator",
-            "version": "4.0.8",
+            "version": "6.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/comparator.git",
-                "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
+                "reference": "131942b86d3587291067a94f295498ab6ac79c20"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
-                "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/131942b86d3587291067a94f295498ab6ac79c20",
+                "reference": "131942b86d3587291067a94f295498ab6ac79c20",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3",
-                "sebastian/diff": "^4.0",
-                "sebastian/exporter": "^4.0"
+                "ext-dom": "*",
+                "ext-mbstring": "*",
+                "php": ">=8.2",
+                "sebastian/diff": "^6.0",
+                "sebastian/exporter": "^6.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-main": "6.0-dev"
                 }
             },
             "autoload": {
@@ -9918,7 +10258,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/comparator/issues",
-                "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+                "security": "https://github.com/sebastianbergmann/comparator/security/policy",
+                "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.1"
             },
             "funding": [
                 {
@@ -9926,33 +10267,33 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-09-14T12:41:17+00:00"
+            "time": "2024-07-03T04:48:07+00:00"
         },
         {
             "name": "sebastian/complexity",
-            "version": "2.0.2",
+            "version": "4.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/complexity.git",
-                "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
+                "reference": "ee41d384ab1906c68852636b6de493846e13e5a0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
-                "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
+                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0",
+                "reference": "ee41d384ab1906c68852636b6de493846e13e5a0",
                 "shasum": ""
             },
             "require": {
-                "nikic/php-parser": "^4.7",
-                "php": ">=7.3"
+                "nikic/php-parser": "^5.0",
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-main": "4.0-dev"
                 }
             },
             "autoload": {
@@ -9975,7 +10316,8 @@
             "homepage": "https://github.com/sebastianbergmann/complexity",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/complexity/issues",
-                "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
+                "security": "https://github.com/sebastianbergmann/complexity/security/policy",
+                "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1"
             },
             "funding": [
                 {
@@ -9983,33 +10325,33 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T15:52:27+00:00"
+            "time": "2024-07-03T04:49:50+00:00"
         },
         {
             "name": "sebastian/diff",
-            "version": "4.0.4",
+            "version": "6.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/diff.git",
-                "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
+                "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
-                "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544",
+                "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3",
+                "phpunit/phpunit": "^11.0",
                 "symfony/process": "^4.2 || ^5"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-main": "6.0-dev"
                 }
             },
             "autoload": {
@@ -10041,7 +10383,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/diff/issues",
-                "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
+                "security": "https://github.com/sebastianbergmann/diff/security/policy",
+                "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2"
             },
             "funding": [
                 {
@@ -10049,27 +10392,27 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T13:10:38+00:00"
+            "time": "2024-07-03T04:53:05+00:00"
         },
         {
             "name": "sebastian/environment",
-            "version": "5.1.5",
+            "version": "7.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
+                "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
-                "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5",
+                "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "suggest": {
                 "ext-posix": "*"
@@ -10077,7 +10420,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "5.1-dev"
+                    "dev-main": "7.2-dev"
                 }
             },
             "autoload": {
@@ -10096,7 +10439,7 @@
                 }
             ],
             "description": "Provides functionality to handle HHVM/PHP environments",
-            "homepage": "http://www.github.com/sebastianbergmann/environment",
+            "homepage": "https://github.com/sebastianbergmann/environment",
             "keywords": [
                 "Xdebug",
                 "environment",
@@ -10104,7 +10447,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/environment/issues",
-                "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
+                "security": "https://github.com/sebastianbergmann/environment/security/policy",
+                "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0"
             },
             "funding": [
                 {
@@ -10112,34 +10456,34 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-03T06:03:51+00:00"
+            "time": "2024-07-03T04:54:44+00:00"
         },
         {
             "name": "sebastian/exporter",
-            "version": "4.0.5",
+            "version": "6.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
+                "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
-                "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e",
+                "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3",
-                "sebastian/recursion-context": "^4.0"
+                "ext-mbstring": "*",
+                "php": ">=8.2",
+                "sebastian/recursion-context": "^6.0"
             },
             "require-dev": {
-                "ext-mbstring": "*",
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-main": "6.1-dev"
                 }
             },
             "autoload": {
@@ -10181,7 +10525,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/exporter/issues",
-                "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
+                "security": "https://github.com/sebastianbergmann/exporter/security/policy",
+                "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3"
             },
             "funding": [
                 {
@@ -10189,38 +10534,35 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-09-14T06:03:37+00:00"
+            "time": "2024-07-03T04:56:19+00:00"
         },
         {
             "name": "sebastian/global-state",
-            "version": "5.0.5",
+            "version": "7.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/global-state.git",
-                "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
+                "reference": "3be331570a721f9a4b5917f4209773de17f747d7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
-                "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7",
+                "reference": "3be331570a721f9a4b5917f4209773de17f747d7",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3",
-                "sebastian/object-reflector": "^2.0",
-                "sebastian/recursion-context": "^4.0"
+                "php": ">=8.2",
+                "sebastian/object-reflector": "^4.0",
+                "sebastian/recursion-context": "^6.0"
             },
             "require-dev": {
                 "ext-dom": "*",
-                "phpunit/phpunit": "^9.3"
-            },
-            "suggest": {
-                "ext-uopz": "*"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "5.0-dev"
+                    "dev-main": "7.0-dev"
                 }
             },
             "autoload": {
@@ -10239,13 +10581,14 @@
                 }
             ],
             "description": "Snapshotting of global state",
-            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "homepage": "https://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/5.0.5"
+                "security": "https://github.com/sebastianbergmann/global-state/security/policy",
+                "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2"
             },
             "funding": [
                 {
@@ -10253,33 +10596,33 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-02-14T08:28:10+00:00"
+            "time": "2024-07-03T04:57:36+00:00"
         },
         {
             "name": "sebastian/lines-of-code",
-            "version": "1.0.3",
+            "version": "3.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/lines-of-code.git",
-                "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
+                "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
-                "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+                "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a",
+                "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a",
                 "shasum": ""
             },
             "require": {
-                "nikic/php-parser": "^4.6",
-                "php": ">=7.3"
+                "nikic/php-parser": "^5.0",
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0-dev"
+                    "dev-main": "3.0-dev"
                 }
             },
             "autoload": {
@@ -10302,7 +10645,8 @@
             "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/1.0.3"
+                "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
+                "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1"
             },
             "funding": [
                 {
@@ -10310,34 +10654,34 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-11-28T06:42:11+00:00"
+            "time": "2024-07-03T04:58:38+00:00"
         },
         {
             "name": "sebastian/object-enumerator",
-            "version": "4.0.4",
+            "version": "6.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/object-enumerator.git",
-                "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+                "reference": "f5b498e631a74204185071eb41f33f38d64608aa"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
-                "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa",
+                "reference": "f5b498e631a74204185071eb41f33f38d64608aa",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3",
-                "sebastian/object-reflector": "^2.0",
-                "sebastian/recursion-context": "^4.0"
+                "php": ">=8.2",
+                "sebastian/object-reflector": "^4.0",
+                "sebastian/recursion-context": "^6.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-main": "6.0-dev"
                 }
             },
             "autoload": {
@@ -10359,7 +10703,8 @@
             "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
-                "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+                "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy",
+                "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1"
             },
             "funding": [
                 {
@@ -10367,32 +10712,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T13:12:34+00:00"
+            "time": "2024-07-03T05:00:13+00:00"
         },
         {
             "name": "sebastian/object-reflector",
-            "version": "2.0.4",
+            "version": "4.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/object-reflector.git",
-                "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+                "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
-                "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9",
+                "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-main": "4.0-dev"
                 }
             },
             "autoload": {
@@ -10414,7 +10759,8 @@
             "homepage": "https://github.com/sebastianbergmann/object-reflector/",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
-                "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+                "security": "https://github.com/sebastianbergmann/object-reflector/security/policy",
+                "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1"
             },
             "funding": [
                 {
@@ -10422,32 +10768,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-10-26T13:14:26+00:00"
+            "time": "2024-07-03T05:01:32+00:00"
         },
         {
             "name": "sebastian/recursion-context",
-            "version": "4.0.5",
+            "version": "6.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/recursion-context.git",
-                "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
+                "reference": "694d156164372abbd149a4b85ccda2e4670c0e16"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
-                "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16",
+                "reference": "694d156164372abbd149a4b85ccda2e4670c0e16",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.3"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-main": "6.0-dev"
                 }
             },
             "autoload": {
@@ -10477,62 +10823,8 @@
             "homepage": "https://github.com/sebastianbergmann/recursion-context",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
-                "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
-            },
-            "funding": [
-                {
-                    "url": "https://github.com/sebastianbergmann",
-                    "type": "github"
-                }
-            ],
-            "time": "2023-02-03T06:07:39+00:00"
-        },
-        {
-            "name": "sebastian/resource-operations",
-            "version": "3.0.3",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/resource-operations.git",
-                "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
-                "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=7.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^9.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources",
-            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
-            "support": {
-                "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
-                "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+                "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
+                "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2"
             },
             "funding": [
                 {
@@ -10540,32 +10832,32 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-09-28T06:45:17+00:00"
+            "time": "2024-07-03T05:10:34+00:00"
         },
         {
             "name": "sebastian/type",
-            "version": "3.2.1",
+            "version": "5.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/type.git",
-                "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
+                "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
-                "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa",
+                "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.5"
+                "phpunit/phpunit": "^11.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.2-dev"
+                    "dev-main": "5.0-dev"
                 }
             },
             "autoload": {
@@ -10588,7 +10880,8 @@
             "homepage": "https://github.com/sebastianbergmann/type",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/type/issues",
-                "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
+                "security": "https://github.com/sebastianbergmann/type/security/policy",
+                "source": "https://github.com/sebastianbergmann/type/tree/5.0.1"
             },
             "funding": [
                 {
@@ -10596,29 +10889,29 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-03T06:13:03+00:00"
+            "time": "2024-07-03T05:11:49+00:00"
         },
         {
             "name": "sebastian/version",
-            "version": "3.0.2",
+            "version": "5.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "c6c1022351a901512170118436c764e473f6de8c"
+                "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
-                "reference": "c6c1022351a901512170118436c764e473f6de8c",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/45c9debb7d039ce9b97de2f749c2cf5832a06ac4",
+                "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.3"
+                "php": ">=8.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.0-dev"
+                    "dev-main": "5.0-dev"
                 }
             },
             "autoload": {
@@ -10641,7 +10934,8 @@
             "homepage": "https://github.com/sebastianbergmann/version",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/version/issues",
-                "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+                "security": "https://github.com/sebastianbergmann/version/security/policy",
+                "source": "https://github.com/sebastianbergmann/version/tree/5.0.1"
             },
             "funding": [
                 {
@@ -10649,20 +10943,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-09-28T06:39:44+00:00"
+            "time": "2024-07-03T05:13:08+00:00"
         },
         {
             "name": "spatie/backtrace",
-            "version": "1.4.0",
+            "version": "1.6.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/backtrace.git",
-                "reference": "ec4dd16476b802dbdc6b4467f84032837e316b8c"
+                "reference": "1a9a145b044677ae3424693f7b06479fc8c137a9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/backtrace/zipball/ec4dd16476b802dbdc6b4467f84032837e316b8c",
-                "reference": "ec4dd16476b802dbdc6b4467f84032837e316b8c",
+                "url": "https://api.github.com/repos/spatie/backtrace/zipball/1a9a145b044677ae3424693f7b06479fc8c137a9",
+                "reference": "1a9a145b044677ae3424693f7b06479fc8c137a9",
                 "shasum": ""
             },
             "require": {
@@ -10670,6 +10964,7 @@
             },
             "require-dev": {
                 "ext-json": "*",
+                "laravel/serializable-closure": "^1.3",
                 "phpunit/phpunit": "^9.3",
                 "spatie/phpunit-snapshot-assertions": "^4.2",
                 "symfony/var-dumper": "^5.1"
@@ -10699,7 +10994,7 @@
                 "spatie"
             ],
             "support": {
-                "source": "https://github.com/spatie/backtrace/tree/1.4.0"
+                "source": "https://github.com/spatie/backtrace/tree/1.6.2"
             },
             "funding": [
                 {
@@ -10711,43 +11006,117 @@
                     "type": "other"
                 }
             ],
-            "time": "2023-03-04T08:57:24+00:00"
+            "time": "2024-07-22T08:21:24+00:00"
+        },
+        {
+            "name": "spatie/error-solutions",
+            "version": "1.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/error-solutions.git",
+                "reference": "ae7393122eda72eed7cc4f176d1e96ea444f2d67"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/error-solutions/zipball/ae7393122eda72eed7cc4f176d1e96ea444f2d67",
+                "reference": "ae7393122eda72eed7cc4f176d1e96ea444f2d67",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "illuminate/broadcasting": "^10.0|^11.0",
+                "illuminate/cache": "^10.0|^11.0",
+                "illuminate/support": "^10.0|^11.0",
+                "livewire/livewire": "^2.11|^3.3.5",
+                "openai-php/client": "^0.10.1",
+                "orchestra/testbench": "^7.0|8.22.3|^9.0",
+                "pestphp/pest": "^2.20",
+                "phpstan/phpstan": "^1.11",
+                "psr/simple-cache": "^3.0",
+                "psr/simple-cache-implementation": "^3.0",
+                "spatie/ray": "^1.28",
+                "symfony/cache": "^5.4|^6.0|^7.0",
+                "symfony/process": "^5.4|^6.0|^7.0",
+                "vlucas/phpdotenv": "^5.5"
+            },
+            "suggest": {
+                "openai-php/client": "Require get solutions from OpenAI",
+                "simple-cache-implementation": "To cache solutions from OpenAI"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Ignition\\": "legacy/ignition",
+                    "Spatie\\ErrorSolutions\\": "src",
+                    "Spatie\\LaravelIgnition\\": "legacy/laravel-ignition"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ruben Van Assche",
+                    "email": "ruben@spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "This is my package error-solutions",
+            "homepage": "https://github.com/spatie/error-solutions",
+            "keywords": [
+                "error-solutions",
+                "spatie"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/error-solutions/issues",
+                "source": "https://github.com/spatie/error-solutions/tree/1.1.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2024-07-25T11:06:04+00:00"
         },
         {
             "name": "spatie/flare-client-php",
-            "version": "1.3.6",
+            "version": "1.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/flare-client-php.git",
-                "reference": "530ac81255af79f114344286e4275f8869c671e2"
+                "reference": "097040ff51e660e0f6fc863684ac4b02c93fa234"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/530ac81255af79f114344286e4275f8869c671e2",
-                "reference": "530ac81255af79f114344286e4275f8869c671e2",
+                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/097040ff51e660e0f6fc863684ac4b02c93fa234",
+                "reference": "097040ff51e660e0f6fc863684ac4b02c93fa234",
                 "shasum": ""
             },
             "require": {
-                "illuminate/pipeline": "^8.0|^9.0|^10.0",
+                "illuminate/pipeline": "^8.0|^9.0|^10.0|^11.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"
+                "spatie/backtrace": "^1.6.1",
+                "symfony/http-foundation": "^5.2|^6.0|^7.0",
+                "symfony/mime": "^5.2|^6.0|^7.0",
+                "symfony/process": "^5.2|^6.0|^7.0",
+                "symfony/var-dumper": "^5.2|^6.0|^7.0"
             },
             "require-dev": {
-                "dms/phpunit-arraysubset-asserts": "^0.3.0",
-                "pestphp/pest": "^1.20",
+                "dms/phpunit-arraysubset-asserts": "^0.5.0",
+                "pestphp/pest": "^1.20|^2.0",
                 "phpstan/extension-installer": "^1.1",
                 "phpstan/phpstan-deprecation-rules": "^1.0",
                 "phpstan/phpstan-phpunit": "^1.0",
-                "spatie/phpunit-snapshot-assertions": "^4.0"
+                "spatie/phpunit-snapshot-assertions": "^4.0|^5.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.1.x-dev"
+                    "dev-main": "1.3.x-dev"
                 }
             },
             "autoload": {
@@ -10772,7 +11141,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/flare-client-php/issues",
-                "source": "https://github.com/spatie/flare-client-php/tree/1.3.6"
+                "source": "https://github.com/spatie/flare-client-php/tree/1.7.0"
             },
             "funding": [
                 {
@@ -10780,41 +11149,41 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-04-12T07:57:12+00:00"
+            "time": "2024-06-12T14:39:14+00:00"
         },
         {
             "name": "spatie/ignition",
-            "version": "1.6.0",
+            "version": "1.15.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/ignition.git",
-                "reference": "fbcfcabc44e506e40c4d72fd4ddf465e272a600e"
+                "reference": "e3a68e137371e1eb9edc7f78ffa733f3b98991d2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/ignition/zipball/fbcfcabc44e506e40c4d72fd4ddf465e272a600e",
-                "reference": "fbcfcabc44e506e40c4d72fd4ddf465e272a600e",
+                "url": "https://api.github.com/repos/spatie/ignition/zipball/e3a68e137371e1eb9edc7f78ffa733f3b98991d2",
+                "reference": "e3a68e137371e1eb9edc7f78ffa733f3b98991d2",
                 "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"
+                "spatie/error-solutions": "^1.0",
+                "spatie/flare-client-php": "^1.7",
+                "symfony/console": "^5.4|^6.0|^7.0",
+                "symfony/var-dumper": "^5.4|^6.0|^7.0"
             },
             "require-dev": {
-                "illuminate/cache": "^9.52",
+                "illuminate/cache": "^9.52|^10.0|^11.0",
                 "mockery/mockery": "^1.4",
-                "pestphp/pest": "^1.20",
+                "pestphp/pest": "^1.20|^2.0",
                 "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",
+                "symfony/cache": "^5.4|^6.0|^7.0",
+                "symfony/process": "^5.4|^6.0|^7.0",
                 "vlucas/phpdotenv": "^5.5"
             },
             "suggest": {
@@ -10863,45 +11232,46 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-04-27T08:40:07+00:00"
+            "time": "2024-06-12T14:55:22+00:00"
         },
         {
             "name": "spatie/laravel-ignition",
-            "version": "1.6.4",
+            "version": "2.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-ignition.git",
-                "reference": "1a2b4bd3d48c72526c0ba417687e5c56b5cf49bc"
+                "reference": "3c067b75bfb50574db8f7e2c3978c65eed71126c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/1a2b4bd3d48c72526c0ba417687e5c56b5cf49bc",
-                "reference": "1a2b4bd3d48c72526c0ba417687e5c56b5cf49bc",
+                "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/3c067b75bfb50574db8f7e2c3978c65eed71126c",
+                "reference": "3c067b75bfb50574db8f7e2c3978c65eed71126c",
                 "shasum": ""
             },
             "require": {
                 "ext-curl": "*",
                 "ext-json": "*",
                 "ext-mbstring": "*",
-                "illuminate/support": "^8.77|^9.27",
-                "monolog/monolog": "^2.3",
-                "php": "^8.0",
-                "spatie/flare-client-php": "^1.0.1",
-                "spatie/ignition": "^1.4.1",
-                "symfony/console": "^5.0|^6.0",
-                "symfony/var-dumper": "^5.0|^6.0"
+                "illuminate/support": "^10.0|^11.0",
+                "php": "^8.1",
+                "spatie/ignition": "^1.15",
+                "symfony/console": "^6.2.3|^7.0",
+                "symfony/var-dumper": "^6.2.3|^7.0"
             },
             "require-dev": {
-                "filp/whoops": "^2.14",
-                "livewire/livewire": "^2.8|dev-develop",
-                "mockery/mockery": "^1.4",
-                "nunomaduro/larastan": "^1.0",
-                "orchestra/testbench": "^6.23|^7.0",
-                "pestphp/pest": "^1.20",
-                "phpstan/extension-installer": "^1.1",
-                "phpstan/phpstan-deprecation-rules": "^1.0",
-                "phpstan/phpstan-phpunit": "^1.0",
-                "spatie/laravel-ray": "^1.27"
+                "livewire/livewire": "^2.11|^3.3.5",
+                "mockery/mockery": "^1.5.1",
+                "openai-php/client": "^0.8.1",
+                "orchestra/testbench": "8.22.3|^9.0",
+                "pestphp/pest": "^2.34",
+                "phpstan/extension-installer": "^1.3.1",
+                "phpstan/phpstan-deprecation-rules": "^1.1.1",
+                "phpstan/phpstan-phpunit": "^1.3.16",
+                "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": {
@@ -10953,34 +11323,31 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-03T19:28:04+00:00"
+            "time": "2024-06-12T15:01:18+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v6.2.10",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "61916f3861b1e9705b18cfde723921a71dd1559d"
+                "reference": "fa34c77015aa6720469db7003567b9f772492bf2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/61916f3861b1e9705b18cfde723921a71dd1559d",
-                "reference": "61916f3861b1e9705b18cfde723921a71dd1559d",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2",
+                "reference": "fa34c77015aa6720469db7003567b9f772492bf2",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.1",
+                "php": ">=8.2",
                 "symfony/polyfill-ctype": "^1.8"
             },
             "conflict": {
-                "symfony/console": "<5.4"
+                "symfony/console": "<6.4"
             },
             "require-dev": {
-                "symfony/console": "^5.4|^6.0"
-            },
-            "suggest": {
-                "symfony/console": "For validating YAML files using the lint command"
+                "symfony/console": "^6.4|^7.0"
             },
             "bin": [
                 "Resources/bin/yaml-lint"
@@ -11011,7 +11378,7 @@
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v6.2.10"
+                "source": "https://github.com/symfony/yaml/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -11027,20 +11394,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-04-28T13:25:36+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "theseer/tokenizer",
-            "version": "1.2.1",
+            "version": "1.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/theseer/tokenizer.git",
-                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
-                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
                 "shasum": ""
             },
             "require": {
@@ -11069,7 +11436,7 @@
             "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"
+                "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
             },
             "funding": [
                 {
@@ -11077,7 +11444,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-07-28T10:34:58+00:00"
+            "time": "2024-03-03T12:36:25+00:00"
         }
     ],
     "aliases": [],
@@ -11086,12 +11453,14 @@
     "prefer-stable": true,
     "prefer-lowest": false,
     "platform": {
-        "php": "^8.1",
-        "ext-intl": "*"
+        "php": "^8.2",
+        "ext-intl": "*",
+        "ext-mysqli": "*",
+        "ext-curl": "*"
     },
     "platform-dev": [],
     "platform-overrides": {
-        "php": "8.1"
+        "php": "8.2"
     },
-    "plugin-api-version": "2.1.0"
+    "plugin-api-version": "2.6.0"
 }

From 98b5b1876dd518e1181d53bfba6845a8505d31ab Mon Sep 17 00:00:00 2001
From: Jens <34610614+AGuyNamedJens@users.noreply.github.com>
Date: Fri, 2 Aug 2024 09:26:10 +0200
Subject: [PATCH 458/514] [Feature] Discord role on purchase (#984)

* Initial commit, addition to the Settings

* [Feat] Discord Settings added

* Refactor: Create a generic add/remove role function to DiscordUser

* [Feat] Add or Remove role on Creation or Deletion
---
 .../Controllers/Admin/ServerController.php    | 40 ++++++++++++++++++-
 .../Controllers/Auth/SocialiteController.php  | 11 +----
 app/Http/Controllers/ServerController.php     | 34 +++++++++++++++-
 app/Models/DiscordUser.php                    | 36 +++++++++++++++++
 app/Settings/DiscordSettings.php              | 14 +++++++
 ...2024_06_25_133205_add_discord_settings.php | 18 +++++++++
 6 files changed, 140 insertions(+), 13 deletions(-)
 create mode 100644 database/settings/2024_06_25_133205_add_discord_settings.php

diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index b2775bb1c..087dbf83e 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -5,6 +5,7 @@
 use App\Http\Controllers\Controller;
 use App\Models\Server;
 use App\Models\User;
+use App\Settings\DiscordSettings;
 use App\Settings\LocaleSettings;
 use App\Settings\PterodactylSettings;
 use App\Classes\PterodactylClient;
@@ -73,7 +74,7 @@ public function edit(Server $server)
      * @param  Request  $request
      * @param  Server  $server
      */
-    public function update(Request $request, Server $server)
+    public function update(Request $request, Server $server, DiscordSettings $discord_settings)
     {
         $request->validate([
             'identifier' => 'required|string',
@@ -92,8 +93,29 @@ public function update(Request $request, Server $server)
                     return redirect()->back()->with('error', 'Failed to update server owner on pterodactyl');
                 }
 
+                // Attempt to remove/add roles respectively
+                try {
+                    if($discord_settings->role_on_purchase) {
+                        // remove the role from the old owner
+                        $oldOwner = User::findOrFail($server->user_id);
+                        $discordUser = $oldOwner->discordUser;
+                        if ($discordUser && $oldOwner->servers->count() <= 1) {
+                            $discordUser->addOrRemoveRole('remove', $discord_settings->role_id_on_purchase);
+                        }
+
+                        // add the role to the new owner
+                        $discordUser = $user->discordUser;
+                        if ($discordUser && $user->servers->count() >= 1) {
+                            $discordUser->addOrRemoveRole('add', $discord_settings->role_id_on_purchase);
+                        }
+                    }
+                } catch (Exception $e) {
+                    log::debug('Failed to update discord roles' . $e->getMessage());
+                }
+
                 // update the owner on the database
                 $server->user_id = $user->id;
+
             } catch (Exception $e) {
                 return redirect()->back()->with('error', 'Internal Server Error');
             }
@@ -115,10 +137,24 @@ public function update(Request $request, Server $server)
      * @param  Server  $server
      * @return RedirectResponse|Response
      */
-    public function destroy(Server $server)
+    public function destroy(Server $server, DiscordSettings $discord_settings)
     {
         $this->checkPermission(self::DELETE_PERMISSION);
         try {
+            // Remove role from discord
+            try {
+                if($discord_settings->role_on_purchase) {
+                    $user = User::findOrFail($server->user_id);
+                    $discordUser = $user->discordUser;
+                    if($discordUser && $user->servers->count() <= 1) {
+                        $discordUser->addOrRemoveRole('remove', $discord_settings->role_id_on_purchase);
+                    }
+                }
+            } catch (Exception $e) {
+                log::debug('Failed to update discord roles' . $e->getMessage());
+            }
+
+            // Attempt to remove the server from pterodactyl
             $server->delete();
 
             return redirect()->route('admin.servers.index')->with('success', __('Server removed'));
diff --git a/app/Http/Controllers/Auth/SocialiteController.php b/app/Http/Controllers/Auth/SocialiteController.php
index 4e495d435..02904c51f 100644
--- a/app/Http/Controllers/Auth/SocialiteController.php
+++ b/app/Http/Controllers/Auth/SocialiteController.php
@@ -73,15 +73,8 @@ public function callback(DiscordSettings $discord_settings, UserSettings $user_s
 
             //give user a role in the discord server
             if (! empty($roleId)) {
-                $response = Http::withHeaders(
-                    [
-                        'Authorization' => 'Bot '.$botToken,
-                        'Content-Type' => 'application/json',
-                    ]
-                )->put(
-                    "https://discord.com/api/guilds/{$guildId}/members/{$discord->id}/roles/{$roleId}",
-                    ['access_token' => $discord->token]
-                );
+                // Function addOrRemoveRole is defined in app/Models/DiscordUser.php
+                $user->discordUser->addOrRemoveRole('add', $roleId);
             }
         }
 
diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index f9f76e19f..7f5919b4f 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -8,7 +8,9 @@
 use App\Models\Pterodactyl\Node;
 use App\Models\Product;
 use App\Models\Server;
+use App\Models\User;
 use App\Notifications\ServerCreationError;
+use App\Settings\DiscordSettings;
 use Carbon\Carbon;
 use App\Settings\UserSettings;
 use App\Settings\ServerSettings;
@@ -21,6 +23,7 @@
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Request as FacadesRequest;
 
 class ServerController extends Controller
@@ -176,7 +179,7 @@ private function validateConfigurationRules(UserSettings $user_settings, ServerS
     }
 
     /** Store a newly created resource in storage. */
-    public function store(Request $request, UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $generalSettings)
+    public function store(Request $request, UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $generalSettings, DiscordSettings $discord_settings)
     {
         /** @var Location $location */
         /** @var Egg $egg */
@@ -235,6 +238,20 @@ public function store(Request $request, UserSettings $user_settings, ServerSetti
         // Charge first billing cycle
         $request->user()->decrement('credits', $server->product->price);
 
+        // Add role from discord
+        try {
+            if($discord_settings->role_on_purchase) {
+                $user = $request->user();
+                $discordUser = $user->discordUser;
+                if($discordUser && $user->servers->count() >= 1) {
+                    $discordUser->addOrRemoveRole('add', $discord_settings->role_id_on_purchase);
+                }
+            }
+        } catch (Exception $e) {
+            log::debug('Failed to update discord roles' . $e->getMessage());
+        }
+
+
         return redirect()->route('servers.index')->with('success', __('Server created'));
     }
 
@@ -266,9 +283,22 @@ private function serverCreationFailed(Response $response, Server $server)
     }
 
     /** Remove the specified resource from storage. */
-    public function destroy(Server $server)
+    public function destroy(Server $server, DiscordSettings $discord_settings)
     {
         try {
+            // Remove role from discord
+            try {
+                if($discord_settings->role_on_purchase) {
+                    $user = User::findOrFail($server->user_id);
+                    $discordUser = $user->discordUser;
+                    if($discordUser && $user->servers->count() <= 1) {
+                        $discordUser->addOrRemoveRole('remove', $discord_settings->role_id_on_purchase);
+                    }
+                }
+            } catch (Exception $e) {
+                log::debug('Failed to update discord roles' . $e->getMessage());
+            }
+
             $server->delete();
 
             return redirect()->route('servers.index')->with('success', __('Server removed'));
diff --git a/app/Models/DiscordUser.php b/app/Models/DiscordUser.php
index 03051ea32..900e8c625 100644
--- a/app/Models/DiscordUser.php
+++ b/app/Models/DiscordUser.php
@@ -5,6 +5,7 @@
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Support\Facades\Http;
 
 class DiscordUser extends Model
 {
@@ -42,4 +43,39 @@ public function getAvatar()
     {
         return 'https://cdn.discordapp.com/avatars/'.$this->id.'/'.$this->avatar.'.png';
     }
+
+
+    /**
+     * Add or remove role on discord server
+     * @param string $action The action to perform (add or remove)
+     * @param string $role_id The Role ID to add or remove
+     * @return mixed
+     */
+    public function addOrRemoveRole(string $action, string $role_id): mixed
+    {
+        $discordSettings = app('discord_settings');
+        return match ($action) {
+            'add' => Http::withHeaders(
+                [
+                    'Authorization' => 'Bot ' . $discordSettings->bot_token,
+                    'Content-Type' => 'application/json',
+                    'X-Audit-Log-Reason' => 'Role added by panel'
+                ]
+            )->put(
+                "https://discord.com/api/guilds/{$discordSettings->guild_id}/members/{$this->id}/roles/{$discordSettings->role_id}",
+                ['access_token' => $discordSettings->token]
+            ),
+            'remove' => Http::withHeaders(
+                [
+                    'Authorization' => 'Bot ' . $discordSettings->bot_token,
+                    'Content-Type' => 'application/json',
+                    'X-Audit-Log-Reason' => 'Role removed by panel'
+                ]
+            )->remove(
+                "https://discord.com/api/guilds/{$discordSettings->guild_id}/members/{$this->id}/roles/{$discordSettings->role_id}",
+                ['access_token' => $discordSettings->token]
+            ),
+            default => null,
+        };
+    }
 }
diff --git a/app/Settings/DiscordSettings.php b/app/Settings/DiscordSettings.php
index 79981c71b..69284e01d 100644
--- a/app/Settings/DiscordSettings.php
+++ b/app/Settings/DiscordSettings.php
@@ -12,6 +12,8 @@ class DiscordSettings extends Settings
     public ?string $guild_id;
     public ?string $invite_url;
     public ?string $role_id;
+    public ?bool $role_on_purchase;
+    public ?string $role_id_on_purchase;
 
     public static function group(): string
     {
@@ -31,6 +33,8 @@ public static function getValidations()
             'guild_id' => 'nullable|string',
             'invite_url' => 'nullable|string|url',
             'role_id' => 'nullable|string',
+            'role_on_purchase' => 'nullable|string',
+            'role_id_on_purchase' => 'nullable|string',
         ];
     }
 
@@ -73,6 +77,16 @@ public static function getOptionInputData()
                 'type' => 'string',
                 'description' => 'The role ID for your Discord server.',
             ],
+            'role_on_purchase' => [
+                'label' => 'Role on Purchase',
+                'type' => 'boolean',
+                'description' => 'Give the user a role on purchase (removes when user has no active servers)',
+            ],
+            'role_id_on_purchase' => [
+                'label' => 'Role ID on Purchase',
+                'type' => 'string',
+                'description' => 'The role ID for your Discord server on purchase.',
+            ],
         ];
     }
 }
diff --git a/database/settings/2024_06_25_133205_add_discord_settings.php b/database/settings/2024_06_25_133205_add_discord_settings.php
new file mode 100644
index 000000000..b73729f7d
--- /dev/null
+++ b/database/settings/2024_06_25_133205_add_discord_settings.php
@@ -0,0 +1,18 @@
+<?php
+
+use Spatie\LaravelSettings\Migrations\SettingsMigration;
+
+class AddDiscordSettings extends SettingsMigration
+{
+    public function up(): void
+    {
+        $this->migrator->add('discord.role_on_purchase', null);
+        $this->migrator->add('discord.role_id_on_purchase', null);
+    }
+
+    public function down(): void
+    {
+        $this->migrator->delete('discord.role_on_purchase');
+        $this->migrator->delete('discord.role_id_on_purchase');
+    }
+}

From 730c9dd4a962a6f781abafccdc7cdb18d22ed07a Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Wed, 7 Aug 2024 21:08:13 -0600
Subject: [PATCH 459/514] feat: Added select & deselect all eggs

---
 .../views/admin/products/create.blade.php      | 18 +++++++++++++++++-
 .../views/admin/products/edit.blade.php        | 18 +++++++++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/themes/default/views/admin/products/create.blade.php b/themes/default/views/admin/products/create.blade.php
index c6c5427f6..bfbfcdcfc 100644
--- a/themes/default/views/admin/products/create.blade.php
+++ b/themes/default/views/admin/products/create.blade.php
@@ -307,7 +307,13 @@ class="custom-select @error('nodes') is-invalid @enderror" name="nodes[]"
 
 
                                 <div class="form-group">
-                                    <label for="eggs">{{ __('Eggs') }}</label>
+                                    <div class="d-flex justify-content-between align-items-center mb-2">
+                                        <label for="eggs" class="mb-0">{{ __('Eggs') }}</label>
+                                        <div>
+                                            <button type="button" id="select-all-eggs" class="btn btn-sm btn-secondary">{{ __('Select All') }}</button>
+                                            <button type="button" id="deselect-all-eggs" class="btn btn-sm btn-secondary ml-2">{{ __('Deselect All') }}</button>
+                                        </div>
+                                    </div>
                                     <select id="eggs" style="width:100%"
                                         class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
                                         multiple="multiple" autocomplete="off">
@@ -350,6 +356,16 @@ class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
         document.addEventListener('DOMContentLoaded', function() {
             $('[data-toggle="popover"]').popover();
             $('.custom-select').select2();
+
+            document.getElementById('select-all-eggs').addEventListener('click', function() {
+                $('#eggs option').prop('selected', true);
+                $('#eggs').trigger('change');
+            });
+
+            document.getElementById('deselect-all-eggs').addEventListener('click', function() {
+                $('#eggs option').prop('selected', false);
+                $('#eggs').trigger('change');
+            });
         });
     </script>
 @endsection
diff --git a/themes/default/views/admin/products/edit.blade.php b/themes/default/views/admin/products/edit.blade.php
index 8f7649580..b371ea7fb 100644
--- a/themes/default/views/admin/products/edit.blade.php
+++ b/themes/default/views/admin/products/edit.blade.php
@@ -315,7 +315,13 @@ class="custom-select @error('nodes') is-invalid @enderror" name="nodes[]"
                                 </div>
 
                                 <div class="form-group">
-                                    <label for="eggs">Eggs</label>
+                                    <div class="d-flex justify-content-between align-items-center mb-2">
+                                        <label for="eggs" class="mb-0">{{ __('Eggs') }}</label>
+                                        <div>
+                                            <button type="button" id="select-all-eggs" class="btn btn-sm btn-secondary">{{ __('Select All') }}</button>
+                                            <button type="button" id="deselect-all-eggs" class="btn btn-sm btn-secondary ml-2">{{ __('Deselect All') }}</button>
+                                        </div>
+                                    </div>
                                     <select id="eggs" style="width:100%"
                                         class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
                                         multiple="multiple" autocomplete="off">
@@ -351,6 +357,16 @@ class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
     <script>
         document.addEventListener('DOMContentLoaded', (event) => {
             $('.custom-select').select2();
+
+            document.getElementById('select-all-eggs').addEventListener('click', function() {
+                $('#eggs option').prop('selected', true);
+                $('#eggs').trigger('change');
+            });
+
+            document.getElementById('deselect-all-eggs').addEventListener('click', function() {
+                $('#eggs option').prop('selected', false);
+                $('#eggs').trigger('change');
+            });
         })
     </script>
     <script>

From 700a46037735009a64af8affd33730f07669f434 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Sat, 17 Aug 2024 03:15:20 +0000
Subject: [PATCH 460/514] style: :lipstick: Fixed color and size of the footer

---
 public/installer/styles.css              | 8 ++++++++
 public/installer/views/layout-bottom.php | 4 ++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/public/installer/styles.css b/public/installer/styles.css
index b7db03605..c6d52afd0 100644
--- a/public/installer/styles.css
+++ b/public/installer/styles.css
@@ -956,6 +956,14 @@ video {
   outline-color: #ca8a04;
 }
 
+.left-0 {
+  left: 0px;
+}
+
+.right-0 {
+  right: 0px;
+}
+
 @media (min-width: 640px) {
   .sm\:w-auto {
     width: auto;
diff --git a/public/installer/views/layout-bottom.php b/public/installer/views/layout-bottom.php
index 944ac0107..60e1efca0 100644
--- a/public/installer/views/layout-bottom.php
+++ b/public/installer/views/layout-bottom.php
@@ -4,8 +4,8 @@
 <!-- any middle view here -->
 
 
-    <footer class="fixed bottom-0 w-full bg-gray-800 bg-opacity-20 text-center py-2 text-xs">
-        &copy; 2024 CtrlPanel | installer v2.0.0
+    <footer class="fixed bottom-0 left-0 right-0 bg-[#1D2125] bg-opacity-20 text-center py-2 text-xs">
+        &copy; <?php echo date("Y"); ?> CtrlPanel | installer v2.0.0
     </footer>
 
     </body>

From cf6eba954ba22a7eb79af02065f19c40505cee20 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Sat, 17 Aug 2024 03:16:29 +0000
Subject: [PATCH 461/514] style: :lipstick: Subtitles are now centered

---
 public/installer/views/layout-top.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/installer/views/layout-top.php b/public/installer/views/layout-top.php
index 42003869b..60c084b89 100644
--- a/public/installer/views/layout-top.php
+++ b/public/installer/views/layout-top.php
@@ -64,7 +64,7 @@ function cardStart($title, $subtitle = null): string
             </div>
             <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
                 <h2 class='text-xl text-center mb-2'>$title</h2>"
-                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
+                . (isset($subtitle) ? "<p class='text-neutral-400 mb-1 text-center'>$subtitle</p>" : "");
 }
 ?>
 <!-- any middle view here -->

From 116d82180557af6911980285d9625cc1df1b8835 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Sat, 17 Aug 2024 03:20:05 +0000
Subject: [PATCH 462/514] style: :lipstick: Changed color of the back button,
 UTF arrows replaced with SVG icons

---
 public/installer/styles.css                       | 12 ++++++++++--
 public/installer/views/admin-creation.php         | 15 +++++++++------
 .../installer/views/dashboard-configuration.php   | 15 +++++++++------
 public/installer/views/database-configuration.php | 15 +++++++++------
 public/installer/views/database-migration.php     | 15 +++++++++------
 public/installer/views/email-configuration.php    | 15 +++++++++------
 public/installer/views/mandatory-checks.php       | 15 +++++++++------
 .../installer/views/pterodactyl-configuration.php | 15 +++++++++------
 public/installer/views/redis-configuration.php    | 15 +++++++++------
 public/installer/views/timezone-configuration.php | 15 +++++++++------
 10 files changed, 91 insertions(+), 56 deletions(-)

diff --git a/public/installer/styles.css b/public/installer/styles.css
index c6d52afd0..c9ed45534 100644
--- a/public/installer/styles.css
+++ b/public/installer/styles.css
@@ -649,6 +649,14 @@ video {
   margin-top: 1rem;
 }
 
+.mr-1 {
+  margin-right: 0.25rem;
+}
+
+.ml-1 {
+  margin-left: 0.25rem;
+}
+
 .box-border {
   box-sizing: border-box;
 }
@@ -758,9 +766,9 @@ video {
   background-color: rgb(34 197 94 / 0.9);
 }
 
-.bg-red-300 {
+.bg-red-500 {
   --tw-bg-opacity: 1;
-  background-color: rgb(252 165 165 / var(--tw-bg-opacity));
+  background-color: rgb(239 68 68 / var(--tw-bg-opacity));
 }
 
 .bg-sky-500 {
diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index ef528555f..694574b4e 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -44,22 +44,25 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index 856f8df45..46b8f5b8e 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -38,22 +38,25 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index ca34a4a00..3542afee8 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -71,22 +71,25 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index 85f0e6779..764eb5f91 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -19,22 +19,25 @@
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index 55ea14363..c548a9e53 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -70,15 +70,17 @@
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
@@ -90,8 +92,9 @@
             </button>
         </a>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/mandatory-checks.php b/public/installer/views/mandatory-checks.php
index 4713c4581..40733eacf 100644
--- a/public/installer/views/mandatory-checks.php
+++ b/public/installer/views/mandatory-checks.php
@@ -51,22 +51,25 @@
     if ($_SESSION['is_previous_button_available'] == true) {
         ?>
         <a href="?step=previous">
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
         </a>
         <?php
     } else {
         ?>
-        <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-            &#8592; Back
+        <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+            Back
         </button>
         <?php
     }
     ?>
     <a href="?step=next">
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="mandatory">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </a>
 </div>
diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index 5d74bd444..6ed17a6e8 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -48,22 +48,25 @@
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index 04e4586d3..ad5fdc575 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -47,22 +47,25 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="redisSetup">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 7806c76b2..66dca3817 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -37,22 +37,25 @@
         if ($_SESSION['is_previous_button_available'] == true) {
             ?>
             <a href="?step=previous">
-                <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-red-300 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
-                    &#8592; Back
+                <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-red-500 hover:bg-red-400 shadow-red-200 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-red-500">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                    Back
                 </button>
             </a>
             <?php
         } else {
             ?>
-            <button type="button" id="backButton" class="px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
-                &#8592; Back
+            <button type="button" id="backButton" class="flex items-center px-4 py-2 font-bold rounded-md bg-gray-200 text-gray-500 shadow-inner cursor-not-allowed" disabled>
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="mr-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9.586 4l-6.586 6.586a2 2 0 0 0 0 2.828l6.586 6.586a2 2 0 0 0 2.18 .434l.145 -.068a2 2 0 0 0 1.089 -1.78v-2.586h7a2 2 0 0 0 2 -2v-4l-.005 -.15a2 2 0 0 0 -1.995 -1.85l-7 -.001v-2.585a2 2 0 0 0 -3.414 -1.414z" /></svg>
+                Back
             </button>
             <?php
         }
         ?>
 
-        <button type="submit" class="px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="timezoneConfig">
-            Next &#8594;
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+            Next
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
     </div>
 </form>

From 6c6bf2129bb1cbd1d7650b9ce97b6ba1025749be Mon Sep 17 00:00:00 2001
From: jameskitt616 <52933658+jameskitt616@users.noreply.github.com>
Date: Sun, 22 Sep 2024 11:16:11 +0200
Subject: [PATCH 463/514] Replace mysql/redis installer host value fields with
 placeholders

---
 public/installer/views/database-configuration.php | 2 +-
 public/installer/views/redis-configuration.php    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/public/installer/views/database-configuration.php b/public/installer/views/database-configuration.php
index 3542afee8..b0ba51ad7 100644
--- a/public/installer/views/database-configuration.php
+++ b/public/installer/views/database-configuration.php
@@ -25,7 +25,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
                 <div class="flex flex-col mb-3">
                     <label for="databasehost">Database Host</label>
                     <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required
-                           value="<?php echo(determineIfRunningInDocker() ? 'mysql' : '127.0.0.1') ?>"
+                           placeholder="e.g. localhost, 10.x.x.x, mysql, 192.168.x.x"
                            class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                 </div>
             </div>
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index ad5fdc575..bd475c6dd 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -17,7 +17,7 @@
                 <div class="flex flex-col mb-3">
                     <label for="redishost">Redis Host</label>
                     <input x-model="redishost" id="redishost" name="redishost" type="text" required
-                            value="<?php echo(determineIfRunningInDocker() ? 'redis' : '127.0.0.1') ?>"
+                            placeholder="e.g. localhost, 127.0.0.1, 10.x.x.x, redis, 192.168.x.x"
                             class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
                 </div>
             </div>

From 3b60ef4c7491ebac3b15dc9ceaef279d84786752 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:01:24 -0600
Subject: [PATCH 464/514] feat: Creation of env file before use

---
 public/installer/index.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/public/installer/index.php b/public/installer/index.php
index a51c67455..70dac50c6 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -6,6 +6,10 @@
 
 session_start();
 
+if (!file_exists('../../.env')) {
+    echo shell_exec('cp ../../.env.example ../../.env');
+}
+
 use DevCoder\DotEnv;
 
 // Include systems
@@ -32,10 +36,6 @@
     exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
 }
 
-if (!file_exists('../../.env')) {
-    echo run_console('cp ../../.env.example ../../.env');
-}
-
 // load all the .env value in php env
 (new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
 
@@ -85,7 +85,7 @@
 include "./views/{$viewName}.php";
 include './views/layout-bottom.php';
 
-// setting / reseting the error message
+// setting / resetting the error message
 $_SESSION['error-message'] = null;
 
 ?>
\ No newline at end of file

From f3cf7107e29c8664e4d4f82db0101cc53714e198 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:01:48 -0600
Subject: [PATCH 465/514] feat: Unnecessary import removed

---
 public/installer/src/forms/smtp.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/public/installer/src/forms/smtp.php b/public/installer/src/forms/smtp.php
index b2165d7b1..28c6b500f 100644
--- a/public/installer/src/forms/smtp.php
+++ b/public/installer/src/forms/smtp.php
@@ -3,7 +3,6 @@
 use DevCoder\DotEnv;
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\PHPMailer;
-use Predis\Client;
 
 (new DotEnv(dirname(__FILE__, 5) . '/.env'))->load();
 

From 491f75a6b849f94ad087ed6c62688399f3a40cdd Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:01:56 -0600
Subject: [PATCH 466/514] feat: Added exit

---
 public/installer/src/functions/installer.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/public/installer/src/functions/installer.php b/public/installer/src/functions/installer.php
index 169931ea4..b9732eff0 100644
--- a/public/installer/src/functions/installer.php
+++ b/public/installer/src/functions/installer.php
@@ -11,6 +11,7 @@ function next_step(): void
 {
     $_SESSION['current_installation_step']++;
     header("LOCATION: index.php");
+    exit();
 }
 
 ?>

From b90b366df677968ce667d42b0e9ae399a33fa84f Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:02:16 -0600
Subject: [PATCH 467/514] fix: Submit name

---
 public/installer/views/admin-creation.php          | 2 +-
 public/installer/views/dashboard-configuration.php | 2 +-
 public/installer/views/database-migration.php      | 2 +-
 public/installer/views/email-configuration.php     | 2 +-
 public/installer/views/mandatory-checks.php        | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/public/installer/views/admin-creation.php b/public/installer/views/admin-creation.php
index 694574b4e..96705f831 100644
--- a/public/installer/views/admin-creation.php
+++ b/public/installer/views/admin-creation.php
@@ -60,7 +60,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         }
         ?>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
diff --git a/public/installer/views/dashboard-configuration.php b/public/installer/views/dashboard-configuration.php
index 46b8f5b8e..f6368e63d 100644
--- a/public/installer/views/dashboard-configuration.php
+++ b/public/installer/views/dashboard-configuration.php
@@ -54,7 +54,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         }
         ?>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
diff --git a/public/installer/views/database-migration.php b/public/installer/views/database-migration.php
index 764eb5f91..adaf381d6 100644
--- a/public/installer/views/database-migration.php
+++ b/public/installer/views/database-migration.php
@@ -35,7 +35,7 @@
         }
         ?>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
diff --git a/public/installer/views/email-configuration.php b/public/installer/views/email-configuration.php
index c548a9e53..7afab1bad 100644
--- a/public/installer/views/email-configuration.php
+++ b/public/installer/views/email-configuration.php
@@ -92,7 +92,7 @@
             </button>
         </a>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
diff --git a/public/installer/views/mandatory-checks.php b/public/installer/views/mandatory-checks.php
index 40733eacf..24c0aa6a7 100644
--- a/public/installer/views/mandatory-checks.php
+++ b/public/installer/views/mandatory-checks.php
@@ -67,7 +67,7 @@
     }
     ?>
     <a href="?step=next">
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>

From 5474902bcc8282dfe9d4f389614e840f1a56122c Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:02:29 -0600
Subject: [PATCH 468/514] fix: Submit name

---
 public/installer/views/pterodactyl-configuration.php | 2 +-
 public/installer/views/redis-configuration.php       | 2 +-
 public/installer/views/timezone-configuration.php    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/public/installer/views/pterodactyl-configuration.php b/public/installer/views/pterodactyl-configuration.php
index 6ed17a6e8..cacce33f7 100644
--- a/public/installer/views/pterodactyl-configuration.php
+++ b/public/installer/views/pterodactyl-configuration.php
@@ -64,7 +64,7 @@
         }
         ?>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
diff --git a/public/installer/views/redis-configuration.php b/public/installer/views/redis-configuration.php
index bd475c6dd..54bc220fc 100644
--- a/public/installer/views/redis-configuration.php
+++ b/public/installer/views/redis-configuration.php
@@ -63,7 +63,7 @@ class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-m
         }
         ?>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="redisSetup">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>
diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 66dca3817..3766e73ff 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -53,7 +53,7 @@
         }
         ?>
 
-        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">
+        <button type="submit" class="flex items-center px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="timezoneConfig">
             Next
             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="ml-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" /></svg>
         </button>

From 2a9866e460bf18ae990e63401192971b9a4ba90c Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:04:07 -0600
Subject: [PATCH 469/514] fix: Early creation of env file

---
 .../installer/views/installation-complete.php | 37 +++++++++++--------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/public/installer/views/installation-complete.php b/public/installer/views/installation-complete.php
index 027784714..48605f71a 100644
--- a/public/installer/views/installation-complete.php
+++ b/public/installer/views/installation-complete.php
@@ -1,22 +1,27 @@
-
 <!-- top layout here -->
 
 <?php
-$lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
-fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
-fclose($lockfile);
+// Check if the installation is already locked
+if (!file_exists('../../install.lock')) {
+    echo cardStart(
+        $title = "Installation Complete!",
+        $subtitle = "You may navigate to your Dashboard now and log in!"
+    );
+    ?>
 
-echo cardStart(
-    $title = "Installation Complete!",
-    $subtitle = "You may navigate to your Dashboard now and log in!"
-);
-?>
+    <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
+        <button
+            class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
+            Let's Go!
+        </button>
+    </a>
 
-<a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center">
-    <button
-        class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">
-        Lets Go!
-    </button>
-</a>
+    <?php
+    // Create the lock file after displaying the completion message
+    $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
+    fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
+    fclose($lockfile);
+}
+?>
 
-<!-- bottom layout here -->
+<!-- bottom layout here -->
\ No newline at end of file

From 152020694b8106fb5d857ed104cc45731c9e9c21 Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 15:06:36 -0600
Subject: [PATCH 470/514] fix: Comment

---
 public/installer/index.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/installer/index.php b/public/installer/index.php
index 70dac50c6..403ca3cc5 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -1,5 +1,5 @@
 <?php
-// repport all error
+// report all error
 ini_set('display_errors', 1);
 ini_set('display_startup_errors', 1);
 error_reporting(E_ALL);

From 1192b3478c38bccc23b73ca79fb7389ffa6a87bc Mon Sep 17 00:00:00 2001
From: Zastinian <zastinian@gmail.com>
Date: Sat, 5 Oct 2024 19:37:08 -0600
Subject: [PATCH 471/514] feat: Removing unnecessary comments

---
 public/installer/views/installation-complete.php | 2 --
 1 file changed, 2 deletions(-)

diff --git a/public/installer/views/installation-complete.php b/public/installer/views/installation-complete.php
index 48605f71a..56b77fe4b 100644
--- a/public/installer/views/installation-complete.php
+++ b/public/installer/views/installation-complete.php
@@ -1,7 +1,6 @@
 <!-- top layout here -->
 
 <?php
-// Check if the installation is already locked
 if (!file_exists('../../install.lock')) {
     echo cardStart(
         $title = "Installation Complete!",
@@ -17,7 +16,6 @@ class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 sh
     </a>
 
     <?php
-    // Create the lock file after displaying the completion message
     $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
     fwrite($lockfile, 'the installation is locked, delete this file to unlock it');
     fclose($lockfile);

From 9b01eea8f306219193f3b68c5131eefbc02c3cb4 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 8 Nov 2024 20:53:18 +0100
Subject: [PATCH 472/514] Fix Ticket Settings in migration || Fix credit
 purchase

---
 app/Listeners/UserPayment.php                                 | 2 +-
 .../settings/2023_02_04_181156_create_ticket_settings.php     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Listeners/UserPayment.php b/app/Listeners/UserPayment.php
index 476573e19..9e1066ef1 100644
--- a/app/Listeners/UserPayment.php
+++ b/app/Listeners/UserPayment.php
@@ -49,7 +49,7 @@ public function handle(PaymentEvent $event)
         $shopProduct = $event->shopProduct;
 
         // only update user if payment is paid
-        if ($event->payment->status != PaymentStatus::PAID->value) {
+        if ($event->payment->status != PaymentStatus::PAID) {
             return;
         }
 
diff --git a/database/settings/2023_02_04_181156_create_ticket_settings.php b/database/settings/2023_02_04_181156_create_ticket_settings.php
index b4cfd8f2f..f893d2270 100644
--- a/database/settings/2023_02_04_181156_create_ticket_settings.php
+++ b/database/settings/2023_02_04_181156_create_ticket_settings.php
@@ -10,8 +10,8 @@ public function up(): void
         $table_exists = DB::table('settings_old')->exists();
 
         // Get the user-set configuration values from the old table.
-        $this->migrator->add('ticket.enabled', $table_exists ? $this->getOldValue('SETTINGS::TICKET:ENABLED') : 'true');
-        $this->migrator->add('ticket.notify', $table_exists ? $this->getOldValue('SETTINGS::TICKET:NOTIFY') : 'all');
+        $this->migrator->add('ticket.enabled', 'true');
+        $this->migrator->add('ticket.notify', 'all');
     }
 
     public function down(): void

From de283330438ed9f2ce84f1f5c42f4345548d3e1c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 8 Nov 2024 21:09:25 +0100
Subject: [PATCH 473/514] Fix ticket creation

---
 app/Http/Controllers/TicketsController.php | 25 ++++++++++++----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index de59bf883..c8c177b2e 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -11,6 +11,7 @@
 use App\Notifications\Ticket\Admin\AdminCreateNotification;
 use App\Notifications\Ticket\Admin\AdminReplyNotification;
 use App\Notifications\Ticket\User\CreateNotification;
+use App\Settings\GeneralSettings;
 use App\Settings\LocaleSettings;
 use App\Settings\PterodactylSettings;
 use App\Settings\TicketSettings;
@@ -33,18 +34,20 @@ public function index(LocaleSettings $locale_settings, TicketSettings $ticketSet
         ]);
     }
 
-    public function store(Request $request, TicketSettings $ticket_settings)
+    public function store(Request $request, GeneralSettings $generalSettings)
     {
-        $this->validate(
-            $request,
-            [
-                'title' => 'required',
-                'ticketcategory' => 'required',
-                'priority' => 'required',
-                'message' => 'required',
-                'g-recaptcha-response' => ['required', 'recaptcha'],
-            ]
-        );
+       $validateData =  [
+            'title' => 'required',
+            'ticketcategory' => 'required',
+            'priority' => 'required',
+            'message' => 'required',
+
+        ];
+        if ($generalSettings->recaptcha_enabled){
+            $validateData['g-recaptcha-response'] = ['required', 'recaptcha'];
+        }
+
+        $this->validate($request, $validateData);
         $ticket = new Ticket(
             [
                 'title' => $request->input('title'),

From f2b6147c40778dba3f02952fc57352002f63ff0f Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 8 Nov 2024 21:17:55 +0100
Subject: [PATCH 474/514] temp remove encryption since its bugged and we never
 had it before aswell

---
 .../2023_02_01_181334_create_pterodactyl_settings.php         | 4 ++--
 database/settings/2023_02_01_181453_create_mail_settings.php  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
index dbbb93b67..f2ed645a5 100644
--- a/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
+++ b/database/settings/2023_02_01_181334_create_pterodactyl_settings.php
@@ -9,8 +9,8 @@ public function up(): void
     {
         $table_exists = DB::table('settings_old')->exists();
 
-        $this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN', '') : env('PTERODACTYL_TOKEN', ''));
-        $this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN', '') : '');
+        $this->migrator->add('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN', '') : env('PTERODACTYL_TOKEN', ''));
+        $this->migrator->add('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN', '') : '');
         $this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL', '') : env('PTERODACTYL_URL', ''));
         $this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT', 200) : 200);
     }
diff --git a/database/settings/2023_02_01_181453_create_mail_settings.php b/database/settings/2023_02_01_181453_create_mail_settings.php
index b7d2c0d38..5dd15cab4 100644
--- a/database/settings/2023_02_01_181453_create_mail_settings.php
+++ b/database/settings/2023_02_01_181453_create_mail_settings.php
@@ -13,7 +13,7 @@ public function up(): void
         $this->migrator->add('mail.mail_host', $table_exists ? $this->getOldValue('SETTINGS::MAIL:HOST') : env('MAIL_HOST', 'localhost'));
         $this->migrator->add('mail.mail_port', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PORT') : env('MAIL_PORT', 25));
         $this->migrator->add('mail.mail_username', $table_exists ? $this->getOldValue('SETTINGS::MAIL:USERNAME') : env('MAIL_USERNAME', ''));
-        $this->migrator->addEncrypted('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
+        $this->migrator->add('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
         $this->migrator->add('mail.mail_encryption', $table_exists ? $this->getOldValue('SETTINGS::MAIL:ENCRYPTION') : env('MAIL_ENCRYPTION', 'tls'));
         $this->migrator->add('mail.mail_from_address', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_ADDRESS') : env('MAIL_FROM_ADDRESS', 'example@example.com'));
         $this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'CtrlPanel.gg'));

From 106b82bab9cf33bcbd554240257e8c010f337bd5 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 8 Nov 2024 21:26:46 +0100
Subject: [PATCH 475/514] encryption fix

---
 app/Settings/MailSettings.php        | 3 ++-
 app/Settings/PterodactylSettings.php | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php
index c3a9a367f..75bc106ff 100644
--- a/app/Settings/MailSettings.php
+++ b/app/Settings/MailSettings.php
@@ -19,6 +19,7 @@ public static function group(): string
     {
         return 'mail';
     }
+    /*
 
     public static function encrypted(): array
     {
@@ -26,7 +27,7 @@ public static function encrypted(): array
             'mail_password',
         ];
     }
-
+*/
     public function setConfig()
     {
         try {
diff --git a/app/Settings/PterodactylSettings.php b/app/Settings/PterodactylSettings.php
index c96933867..fa158120f 100644
--- a/app/Settings/PterodactylSettings.php
+++ b/app/Settings/PterodactylSettings.php
@@ -15,7 +15,7 @@ public static function group(): string
     {
         return 'pterodactyl';
     }
-
+/*
     public static function encrypted(): array
     {
         return [
@@ -23,7 +23,7 @@ public static function encrypted(): array
             'user_token',
         ];
     }
-
+*/
     /**
      * Get url with ensured ending backslash
      *

From 1d78861898feaf307afda5cc8d1ba9e1abad363f Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Fri, 8 Nov 2024 22:08:10 +0100
Subject: [PATCH 476/514] fix free products

---
 app/Http/Controllers/Admin/PaymentController.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 0b11597ef..82efc3b5f 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers\Admin;
 
+use App\Enums\PaymentStatus;
 use App\Events\CouponUsedEvent;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
@@ -108,7 +109,7 @@ public function handleFreeProduct(ShopProduct $shopProduct)
             'payment_id' => uniqid(),
             'payment_method' => 'free',
             'type' => $shopProduct->type,
-            'status' => 'paid',
+            'status' => PaymentStatus::PAID,
             'amount' => $shopProduct->quantity,
             'price' => $shopProduct->price - ($shopProduct->price * PartnerDiscount::getDiscount() / 100),
             'tax_value' => $shopProduct->getTaxValue(),

From fbe8d5ce02823e88c3a9f62858f1b4ac3cc18e7d Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 01:37:15 +0100
Subject: [PATCH 477/514] Permissions Cleanup and fixes  as #952

---
 .../Controllers/Admin/LegalController.php     |  2 +-
 .../Controllers/Admin/ProductController.php   |  3 +-
 .../Controllers/Admin/SettingsController.php  |  4 +
 app/Http/Controllers/Admin/UserController.php | 64 ++++++++-----
 app/Http/Controllers/Controller.php           | 17 ++++
 config/permissions_web.php                    | 91 ++++++++++---------
 6 files changed, 112 insertions(+), 69 deletions(-)

diff --git a/app/Http/Controllers/Admin/LegalController.php b/app/Http/Controllers/Admin/LegalController.php
index 27c858fba..27f24aa4e 100644
--- a/app/Http/Controllers/Admin/LegalController.php
+++ b/app/Http/Controllers/Admin/LegalController.php
@@ -33,7 +33,7 @@ public function index()
     }
 
     public function update(Request $request){
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkPermission(self::WRITE_PERMISSION);
 
         $tos = $request->tos;
         $privacy = $request->privacy;
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index 6ddae3e38..d250307fe 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -20,7 +20,8 @@
 class ProductController extends Controller
 {
     const READ_PERMISSION = "admin.products.read";
-    const WRITE_PERMISSION = "admin.products.write";
+
+    const WRITE_PERMISSION = "admin.products.create";
     const EDIT_PERMISSION = "admin.products.edit";
     const DELETE_PERMISSION = "admin.products.delete";
     /**
diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index 988603220..8cee2f582 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -15,6 +15,8 @@
 
 class SettingsController extends Controller
 {
+    const ICON_PERMISSION = "admin.icons.edit";
+
 
 
     /**
@@ -142,6 +144,8 @@ public function update(Request $request)
 
     public function updateIcons(Request $request)
     {
+        $this->checkPermission(self::ICON_PERMISSION);
+
         $request->validate([
             'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
             'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 57fc53cd2..82e670024 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -38,12 +38,15 @@ class UserController extends Controller
     const CHANGE_USERNAME_PERMISSION = "admin.users.write.username";
     const CHANGE_PASSWORD_PERMISSION = "admin.users.write.password";
     const CHANGE_ROLE_PERMISSION ="admin.users.write.role";
-    const CHANGE_REFERAL_PERMISSION ="admin.users.write.referral";
+    const CHANGE_REFERRAL_PERMISSION ="admin.users.write.referral";
     const CHANGE_PTERO_PERMISSION = "admin.users.write.pterodactyl";
+
+    const CHANGE_SERVERLIMIT_PERMISSION = "admin.users.write.serverlimit";
     const DELETE_PERMISSION = "admin.users.delete";
     const NOTIFY_PERMISSION = "admin.users.notify";
     const LOGIN_PERMISSION = "admin.users.login_as";
 
+
     private $pterodactyl;
 
     public function __construct(PterodactylSettings $ptero_settings)
@@ -127,7 +130,9 @@ public function json(Request $request)
      */
     public function edit(User $user, GeneralSettings $general_settings)
     {
-        $this->checkPermission(self::WRITE_PERMISSION);
+        $allConstants = (new \ReflectionClass(__CLASS__))->getConstants();
+        $permissions = array_filter($allConstants, fn($key) => str_starts_with($key, 'admin.users.write'));
+        $this->checkAnyPermission($permissions);
 
         $roles = Role::all();
         return view('admin.users.edit')->with([
@@ -169,34 +174,47 @@ public function update(Request $request, User $user)
             ]);
         }
 
-        if (!is_null($request->input('new_password')) && $this->can(self::CHANGE_PASSWORD_PERMISSION)) {
+        $dataArray = [];
+
+        if ($this->canAny([self::CHANGE_USERNAME_PERMISSION, self::WRITE_PERMISSION]) && $request->filled('name')) {
+            $dataArray['name'] = $request->input('name');
+        }
+
+        if ($this->canAny([self::CHANGE_CREDITS_PERMISSION, self::WRITE_PERMISSION]) && $request->filled('credits')) {
+            $dataArray['credits'] = $request->input('credits');
+        }
+
+        if ($this->canAny([self::CHANGE_PTERO_PERMISSION, self::WRITE_PERMISSION]) && $request->filled('pterodactyl_id')) {
+            $dataArray['pterodactyl_id'] = $request->input('pterodactyl_id');
+        }
+
+        if ($this->canAny([self::CHANGE_REFERRAL_PERMISSION, self::WRITE_PERMISSION]) && $request->filled('referral_code')) {
+            $dataArray['referral_code'] = $request->input('referral_code');
+        }
+
+        if ($this->canAny([self::CHANGE_EMAIL_PERMISSION, self::WRITE_PERMISSION]) && $request->filled('email')) {
+            $dataArray['email'] = $request->input('email');
+        }
+
+        if ($this->canAny([self::CHANGE_SERVERLIMIT_PERMISSION, self::WRITE_PERMISSION]) && $request->filled('server_limit')) {
+            $dataArray['server_limit'] = $request->input('server_limit');
+        }
+
+
+// Update password separately with validation, if permission is granted
+        if (!is_null($request->input('new_password')) && $this->canAny([self::CHANGE_PASSWORD_PERMISSION, self::WRITE_PERMISSION])) {
             $request->validate([
                 'new_password' => 'required|string|min:8',
                 'new_password_confirmation' => 'required|same:new_password',
             ]);
 
-            $user->update([
-                'password' => Hash::make($request->input('new_password')),
-            ]);
+            $dataArray['password'] = Hash::make($request->input('new_password'));
         }
 
-        // if($this->can(self::CHANGE_USERNAME_PERMISSION)){
-        //    $user->name = $request->name;
-        // }
-        // if($this->can(self::CHANGE_CREDITS_PERMISSION)){
-        //     $user->credits = $request->credits;
-        // }
-        // if($this->can(self::CHANGE_PTERO_PERMISSION)){
-        //     $user->pterodactyl_id = $request->pterodactyl_id;
-        // }
-        // if($this->can(self::CHANGE_REFERAL_PERMISSION)){
-        //     $user->referral_code = $request->referral_code;
-        // }
-        // if($this->can(self::CHANGE_EMAIL_PERMISSION)){
-        //     $user->email = $request->email;
-        // }
-
-        $user->update($data);
+// Only update with the collected data
+        if (!empty($dataArray)) {
+            $user->update($dataArray);
+        }
 
         event(new UserUpdateCreditsEvent($user));
 
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index 49d020497..b6060d827 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -29,6 +29,16 @@ public function checkPermission(string $permission)
         }
     }
 
+    public function checkAnyPermission(iterable $permission)
+    {
+        /** @var User $user */
+        $user = Auth::user();
+
+        if (!$user->canAny($permission)) {
+            abort(403, __('User does not have the right permissions.'));
+        }
+    }
+
     /**
      * Check if user has permissions
      *
@@ -42,4 +52,11 @@ public function can(string $permission): bool
 
         return $user->can($permission);
     }
+    public function canAny(iterable $permission): bool
+    {
+        /** @var User $user */
+        $user = Auth::user();
+
+        return $user->canAny($permission);
+    }
 }
diff --git a/config/permissions_web.php b/config/permissions_web.php
index 1e67f65fc..38033129d 100644
--- a/config/permissions_web.php
+++ b/config/permissions_web.php
@@ -7,21 +7,21 @@
 
     'All Permissions' => '*',
 
-    'View Roles' => 'admin.roles.read',
+    'View Roles Backend' => 'admin.roles.read',
     'Create Role' => 'admin.roles.create',
     'Edit Role' => 'admin.roles.edit',
     'Delete Role' => 'admin.roles.delete',
 
 
-    'View Tickets' => 'admin.tickets.read',
-    'Manage Ticket' => 'admin.tickets.write',
-    'Receive Ticket Notifications' => 'admin.tickets.get_notification',
+    'View Tickets Backend' => 'admin.tickets.read',
+    'Manage Ticket Backend' => 'admin.tickets.write',
+    'Receive new Ticket Notifications' => 'admin.tickets.get_notification',
 
     'Create Ticket Category' => 'admin.tickets.category.read',
-    'Manage Ticket Category' => 'admin.tickets.category.write',
+    'Manage Ticket Category Backend' => 'admin.tickets.category.write',
 
-    'View Blacklist Tickets' => 'admin.ticket_blacklist.read',
-    'Manage Blacklist Tickets' => 'admin.ticket_blacklist.write',
+    'View Ticket-Blacklist' => 'admin.ticket_blacklist.read',
+    'Manage Ticket-Blacklist' => 'admin.ticket_blacklist.write',
 
     'View Overview' => 'admin.overview.read',
     'Overview Sync' => 'admin.overview.sync',
@@ -29,54 +29,57 @@
     'View Api Keys' => 'admin.api.read',
     'Manage Api Keys' => 'admin.api.write',
 
-    'View Users' => 'admin.users.read',
-    'Manage Users' => 'admin.users.write',
+    'View User List' => 'admin.users.read',
+    'Edit anything on User' => 'admin.users.write',
     'Suspend Users' => 'admin.users.suspend',
-    'Manage User Credits' => 'admin.users.write.credits',
-    'Manage User Name' => 'admin.users.write.username',
-    'Manage User Email' => 'admin.users.write.email',
-    'Manage User Password' => 'admin.users.write.password',
-    'Manage User Role' => 'admin.users.write.role',
-    'Manage User Referral' => 'admin.users.write.referral',
-    'Manage User Pterodactyl' => 'admin.users.write.pterodactyl',
+    'Edit User Credits' => 'admin.users.write.credits',
+    'Edit User Name' => 'admin.users.write.username',
+    'Edit User Email' => 'admin.users.write.email',
+    'Edit User Password' => 'admin.users.write.password',
+    'Edit User Role' => 'admin.users.write.role',
+    'Edit User Referral' => 'admin.users.write.referral',
+    'Edit User Pterodactyl' => 'admin.users.write.pterodactyl',
+    'Edit User Serverlimit' => 'admin.users.write.serverlimit',
+
+    "Manage Icons" => "admin.icons.edit",
 
     'Notify Users' => 'admin.users.notify',
     'Login As User' => 'admin.users.login_as',
     'Delete User' => 'admin.users.delete',
 
-    'View Servers' => 'admin.servers.read',
-    'Manage Servers' => 'admin.servers.write',
-    'Suspend Server' => 'admin.servers.suspend',
-    'Change Server Owner' => 'admin.servers.write.owner',
-    'Manage Server Identifier' => 'admin.servers.write.identifier',
-    'Create Server' => 'admin.servers.bypass_creation_enabled',
-    'Delete Server' => 'admin.servers.delete',
+    'View Server List' => 'admin.servers.read',
+    'Manage all Servers' => 'admin.servers.write',
+    'Suspend any Server' => 'admin.servers.suspend',
+    'Change any Servers Owner' => 'admin.servers.write.owner',
+    'Manage any Servers Identifier' => 'admin.servers.write.identifier',
+    'Bypass Server-creation restriction ' => 'admin.servers.bypass_creation_enabled',
+    'Delete any Servers' => 'admin.servers.delete',
 
-    'View Products' => 'admin.products.read',
+    'View Product List' => 'admin.products.read',
     'Create Product' => 'admin.products.create',
     'Edit Product' => 'admin.products.edit',
     'Delete Product' => 'admin.products.delete',
 
-    'View Store' => 'admin.store.read',
-    'Manage Store' => 'admin.store.write',
+    'View Store Backend' => 'admin.store.read',
+    'Manage Store Backend' => 'admin.store.write',
     'Disable Store' => 'admin.store.disable',
 
-    'View Vouchers' => 'admin.voucher.read',
-    'Manage Voucher' => 'admin.voucher.write',
+    'View Vouchers Backend' => 'admin.voucher.read',
+    'Manage Voucher Backend' => 'admin.voucher.write',
 
-    'View Useful Links' => 'admin.useful_links.read',
-    'Manage Useful Links' => 'admin.useful_links.write',
+    'View Useful Links Backend' => 'admin.useful_links.read',
+    'Manage Useful Links Backend' => 'admin.useful_links.write',
 
-    'View Legal' => 'admin.legal.read',
-    'Manage Legal' => 'admin.legal.write',
+    'View Legal Backend' => 'admin.legal.read',
+    'Manage Legal Backend' => 'admin.legal.write',
 
-    'View Payments' => 'admin.payments.read',
+    'View Payments Backend' => 'admin.payments.read',
 
-    'View Partners' => 'admin.partners.read',
-    'Manage Partners' => 'admin.partners.write',
+    'View Partners Backend' => 'admin.partners.read',
+    'Manage Partners Backend' => 'admin.partners.write',
 
-    'View Coupons' => 'admin.coupons.read',
-    'Manage Coupons' => 'admin.coupons.write',
+    'View Coupons Backend' => 'admin.coupons.read',
+    'Manage Coupons Backend' => 'admin.coupons.write',
 
     'View Logs' => 'admin.logs.read',
 
@@ -121,7 +124,7 @@
 
     'View Mercado Pago Settings' => 'settings.mercadopago.read',
     'Manage Mercado Pago Settings' => 'settings.mercadopago.write',
-  
+
     'View Stripe Settings' => 'settings.stripe.read',
     'Manage Stripe Settings' => 'settings.stripe.write',
 
@@ -131,10 +134,10 @@
     /*
      * Permissions for users
     */
-    'User Create Server' => 'user.server.create',
-    'User Upgrade Server' => 'user.server.upgrade',
-    'User Shop Buy' => 'user.shop.buy',
-    'User View Tickets' => 'user.ticket.read',
-    'User Manage Ticket' => 'user.ticket.write',
-    'User View Referral' => 'user.referral',
+    'Customer Create Server' => 'user.server.create',
+    'Customer Upgrade Server' => 'user.server.upgrade',
+    'Customer Shop Buy' => 'user.shop.buy',
+    'Customer View Supportticket' => 'user.ticket.read',
+    'Customer Write Supportticket' => 'user.ticket.write',
+    'Customer View Referral' => 'user.referral',
 ];

From c0dbba0344251f7173e4b636fb937222bb393bae Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 01:55:13 +0100
Subject: [PATCH 478/514] Overhaul the Permissions on Controllers

---
 app/Http/Controllers/Admin/ApplicationApiController.php | 2 +-
 app/Http/Controllers/Admin/CouponController.php         | 2 +-
 app/Http/Controllers/Admin/LegalController.php          | 2 +-
 app/Http/Controllers/Admin/OverViewController.php       | 2 +-
 app/Http/Controllers/Admin/PartnerController.php        | 2 +-
 app/Http/Controllers/Admin/ProductController.php        | 5 +++--
 app/Http/Controllers/Admin/RoleController.php           | 3 ++-
 app/Http/Controllers/Admin/ServerController.php         | 7 +++++--
 app/Http/Controllers/Admin/ShopProductController.php    | 2 +-
 app/Http/Controllers/Admin/TicketCategoryController.php | 2 +-
 app/Http/Controllers/Admin/TicketsController.php        | 6 +++---
 app/Http/Controllers/Admin/UsefulLinkController.php     | 2 +-
 app/Http/Controllers/Admin/UserController.php           | 5 ++++-
 app/Http/Controllers/Admin/VoucherController.php        | 2 +-
 14 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/app/Http/Controllers/Admin/ApplicationApiController.php b/app/Http/Controllers/Admin/ApplicationApiController.php
index f6c00bbd8..f53a4fb42 100644
--- a/app/Http/Controllers/Admin/ApplicationApiController.php
+++ b/app/Http/Controllers/Admin/ApplicationApiController.php
@@ -25,7 +25,7 @@ class ApplicationApiController extends Controller
      */
     public function index(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION,self::WRITE_PERMISSION]);
 
         return view('admin.api.index', [
             'locale_datatables' => $locale_settings->datatables
diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php
index 71caaf31c..d7d796b20 100644
--- a/app/Http/Controllers/Admin/CouponController.php
+++ b/app/Http/Controllers/Admin/CouponController.php
@@ -23,7 +23,7 @@ class CouponController extends Controller
      */
     public function index(LocaleSettings $localeSettings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::WRITE_PERMISSION,self::READ_PERMISSION]);
 
         return view('admin.coupons.index', [
             'locale_datatables' => $localeSettings->datatables
diff --git a/app/Http/Controllers/Admin/LegalController.php b/app/Http/Controllers/Admin/LegalController.php
index 27f24aa4e..2f101e356 100644
--- a/app/Http/Controllers/Admin/LegalController.php
+++ b/app/Http/Controllers/Admin/LegalController.php
@@ -19,7 +19,7 @@ class LegalController extends Controller
      */
     public function index()
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION,self::WRITE_PERMISSION]);
 
         $tos = File::get(Theme::path($path = 'views', "default") . '/information/tos-content.blade.php');
         $privacy = File::get(Theme::path($path = 'views', "default") . '/information/privacy-content.blade.php');
diff --git a/app/Http/Controllers/Admin/OverViewController.php b/app/Http/Controllers/Admin/OverViewController.php
index 2b0a4f69d..6d9ebab80 100644
--- a/app/Http/Controllers/Admin/OverViewController.php
+++ b/app/Http/Controllers/Admin/OverViewController.php
@@ -32,7 +32,7 @@ public function __construct(PterodactylSettings $ptero_settings)
 
     public function index(GeneralSettings $general_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION,self::SYNC_PERMISSION]);
 
         //Get counters
         $counters = collect();
diff --git a/app/Http/Controllers/Admin/PartnerController.php b/app/Http/Controllers/Admin/PartnerController.php
index 8b65eec3f..3b641c5f2 100644
--- a/app/Http/Controllers/Admin/PartnerController.php
+++ b/app/Http/Controllers/Admin/PartnerController.php
@@ -15,7 +15,7 @@ class PartnerController extends Controller
     const WRITE_PERMISSION = "admin.partners.write";
     public function index(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::WRITE_PERMISSION,self::READ_PERMISSION]);
 
         return view('admin.partners.index', [
             'locale_datatables' => $locale_settings->datatables
diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php
index d250307fe..2778dd6f5 100644
--- a/app/Http/Controllers/Admin/ProductController.php
+++ b/app/Http/Controllers/Admin/ProductController.php
@@ -31,7 +31,8 @@ class ProductController extends Controller
      */
     public function index(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $allConstants = (new \ReflectionClass(__CLASS__))->getConstants();
+        $this->checkAnyPermission($allConstants);
 
         return view('admin.products.index', [
             'locale_datatables' => $locale_settings->datatables
@@ -113,7 +114,7 @@ public function store(Request $request)
      */
     public function show(Product $product, UserSettings $user_settings, GeneralSettings $general_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION,self::WRITE_PERMISSION]);
 
         return view('admin.products.show', [
             'product' => $product,
diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 3ce5ad5bb..0d09c5d5f 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -31,7 +31,8 @@ class RoleController extends Controller
     public function index(Request $request)
     {
 
-        $this->checkPermission(self::READ_PERMISSION);
+        $allConstants = (new \ReflectionClass(__CLASS__))->getConstants();
+        $this->checkAnyPermission($allConstants);
 
         //datatables
         if ($request->ajax()) {
diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php
index 087dbf83e..4d83d39c8 100644
--- a/app/Http/Controllers/Admin/ServerController.php
+++ b/app/Http/Controllers/Admin/ServerController.php
@@ -42,7 +42,8 @@ public function __construct(PterodactylSettings $ptero_settings)
      */
     public function index(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $allConstants = (new \ReflectionClass(__CLASS__))->getConstants();
+        $this->checkAnyPermission($allConstants);
 
         return view('admin.servers.index', [
             'locale_datatables' => $locale_settings->datatables
@@ -57,7 +58,9 @@ public function index(LocaleSettings $locale_settings)
      */
     public function edit(Server $server)
     {
-        $this->checkPermission(self::WRITE_PERMISSION);
+        $allConstants = (new \ReflectionClass(__CLASS__))->getConstants();
+        $permissions = array_filter($allConstants, fn($key) => str_starts_with($key, 'admin.servers.write'));
+        $this->checkAnyPermission($permissions);
 
         // get all users from the database
         $users = User::all();
diff --git a/app/Http/Controllers/Admin/ShopProductController.php b/app/Http/Controllers/Admin/ShopProductController.php
index db07916a8..4ed07ba3c 100644
--- a/app/Http/Controllers/Admin/ShopProductController.php
+++ b/app/Http/Controllers/Admin/ShopProductController.php
@@ -28,7 +28,7 @@ class ShopProductController extends Controller
      */
     public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION, self::WRITE_PERMISSION]);
 
         $isStoreEnabled = $general_settings->store_enabled;
 
diff --git a/app/Http/Controllers/Admin/TicketCategoryController.php b/app/Http/Controllers/Admin/TicketCategoryController.php
index 3d4d8e879..b0ae8e21b 100644
--- a/app/Http/Controllers/Admin/TicketCategoryController.php
+++ b/app/Http/Controllers/Admin/TicketCategoryController.php
@@ -19,7 +19,7 @@ class TicketCategoryController extends Controller
      */
     public function index()
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION, self::WRITE_PERMISSION]);
 
         $categories = TicketCategory::all();
         return view('admin.ticket.category')->with("categories",$categories);
diff --git a/app/Http/Controllers/Admin/TicketsController.php b/app/Http/Controllers/Admin/TicketsController.php
index 025c58de3..ec1d6578d 100644
--- a/app/Http/Controllers/Admin/TicketsController.php
+++ b/app/Http/Controllers/Admin/TicketsController.php
@@ -25,7 +25,7 @@ class TicketsController extends Controller
     const BLACKLIST_WRITE_PERMISSION ='admin.ticket_blacklist.write';
     public function index(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION, self::WRITE_PERMISSION]);
 
         return view('admin.ticket.index', [
             'tickets' => Ticket::orderBy('id', 'desc')->paginate(10),
@@ -36,7 +36,7 @@ public function index(LocaleSettings $locale_settings)
 
     public function show($ticket_id, PterodactylSettings $ptero_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION, self::WRITE_PERMISSION]);
         try {
         $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
         } catch (Exception $e)
@@ -186,7 +186,7 @@ public function dataTable()
 
     public function blacklist(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::BLACKLIST_READ_PERMISSION);
+        $this->checkAnyPermission([self::BLACKLIST_READ_PERMISSION, self::BLACKLIST_WRITE_PERMISSION]);
 
         return view('admin.ticket.blacklist', [
             'locale_datatables' => $locale_settings->datatables
diff --git a/app/Http/Controllers/Admin/UsefulLinkController.php b/app/Http/Controllers/Admin/UsefulLinkController.php
index 17f8774b2..55a62d684 100644
--- a/app/Http/Controllers/Admin/UsefulLinkController.php
+++ b/app/Http/Controllers/Admin/UsefulLinkController.php
@@ -24,7 +24,7 @@ class UsefulLinkController extends Controller
      */
     public function index(LocaleSettings $locale_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION, self::WRITE_PERMISSION]);
         return view('admin.usefullinks.index', [
             'locale_datatables' => $locale_settings->datatables
         ]);
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 82e670024..3cc7709f9 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -62,7 +62,10 @@ public function __construct(PterodactylSettings $ptero_settings)
      */
     public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $allConstants = (new \ReflectionClass(__CLASS__))->getConstants();
+        $this->checkAnyPermission($allConstants);
+
+        //$this->checkPermission(self::READ_PERMISSION);
 
         return view('admin.users.index', [
             'locale_datatables' => $locale_settings->datatables,
diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php
index b42d5094c..4e65e7d54 100644
--- a/app/Http/Controllers/Admin/VoucherController.php
+++ b/app/Http/Controllers/Admin/VoucherController.php
@@ -28,7 +28,7 @@ class VoucherController extends Controller
      */
     public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
     {
-        $this->checkPermission(self::READ_PERMISSION);
+        $this->checkAnyPermission([self::READ_PERMISSION, self::WRITE_PERMISSION]);
 
         return view('admin.vouchers.index', [
             'locale_datatables' => $locale_settings->datatables,

From 4b96e9f52f9cb1e64864a0ab5a6edcc4fd3b163c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 02:37:41 +0100
Subject: [PATCH 479/514] Fix sales Tax || Fix Icons edit Permission

---
 app/Models/ShopProduct.php                      |  4 +++-
 app/Settings/GeneralSettings.php                | 17 +++++++----------
 ...023_02_01_164731_create_general_settings.php |  8 ++++++++
 .../views/admin/settings/index.blade.php        |  2 ++
 4 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/app/Models/ShopProduct.php b/app/Models/ShopProduct.php
index 8e8a2260b..4515f5d79 100644
--- a/app/Models/ShopProduct.php
+++ b/app/Models/ShopProduct.php
@@ -2,6 +2,7 @@
 
 namespace App\Models;
 
+use App\Settings\GeneralSettings;
 use Hidehalo\Nanoid\Client;
 use Illuminate\Database\Eloquent\Model;
 use NumberFormatter;
@@ -73,7 +74,8 @@ public function formatToCurrency($value, $locale = 'en_US')
      */
     public function getTaxPercent()
     {
-        $tax = config('SETTINGS::PAYMENTS:SALES_TAX');
+        $generalSettings = new GeneralSettings();
+        $tax = $generalSettings->sales_tax;
 
         return $tax < 0 ? 0 : $tax;
     }
diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 23c0c0f76..3c3310a88 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -7,6 +7,7 @@
 class GeneralSettings extends Settings
 {
     public bool $store_enabled;
+    public ?int $sales_tax;
     public string $credits_display_name;
     public bool $recaptcha_enabled;
     public ?string $recaptcha_site_key;
@@ -34,6 +35,7 @@ public static function getValidations()
     {
         return [
             'store_enabled' => 'nullable|string',
+            'sales_tax' => 'nullable|number',
             'credits_display_name' => 'required|string',
             'recaptcha_enabled' => 'nullable|string',
             'recaptcha_site_key' => 'nullable|string',
@@ -60,21 +62,16 @@ public static function getOptionInputData()
                 'label' => 'Enable Store',
                 'description' => 'Enable the store for users to purchase credits.'
             ],
+            'sales_tax' => [
+                'type' => 'number',
+                'label' => 'Sales Tax in %',
+                'description' => 'Your countrys sales tax in %'
+            ],
             'credits_display_name' => [
                 'type' => 'string',
                 'label' => 'Credits Display Name',
                 'description' => 'The name of the currency used.'
             ],
-            'initial_user_credits' => [
-                'type' => 'number',
-                'label' => 'Initial User Credits',
-                'description' => 'The amount of credits a user gets when they register.'
-            ],
-            'initial_server_limit' => [
-                'type' => 'number',
-                'label' => 'Initial Server Limit',
-                'description' => 'The amount of servers a user can create when they register.'
-            ],
             'recaptcha_enabled' => [
                 'type' => 'boolean',
                 'label' => 'Enable reCAPTCHA',
diff --git a/database/settings/2023_02_01_164731_create_general_settings.php b/database/settings/2023_02_01_164731_create_general_settings.php
index 06c876c5b..e799e4406 100644
--- a/database/settings/2023_02_01_164731_create_general_settings.php
+++ b/database/settings/2023_02_01_164731_create_general_settings.php
@@ -11,6 +11,7 @@ public function up(): void
 
         // Get the user-set configuration values from the old table.
         $this->migrator->add('general.store_enabled',  true);
+        $this->migrator->add('general.sales_tax', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:SALES_TAX', '0') : '0');
         $this->migrator->add('general.credits_display_name', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits') : 'Credits');
         $this->migrator->add('general.recaptcha_site_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SITE_KEY") : env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'));
         $this->migrator->add('general.recaptcha_secret_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SECRET_KEY") : env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'));
@@ -31,6 +32,12 @@ public function down(): void
                 'type' => 'string',
                 'description' => 'The name of the credits on the panel.'
             ],
+            [
+                'key' => 'SETTINGS::PAYMENTS:SALES_TAX',
+                'value' => $this->getNewValue('sales_tax', 'general'),
+                'type' => 'string',
+                'description' => 'Sales tax in %.'
+            ],
             [
                 'key' => 'SETTINGS::SYSTEM:ALERT_ENABLED',
                 'value' => $this->getNewValue('alert_enabled', 'general'),
@@ -83,6 +90,7 @@ public function down(): void
         ]);
         try {
             $this->migrator->delete('general.store_enabled');
+            $this->migrator->delete('general.sales_tax');
             $this->migrator->delete('general.credits_display_name');
             $this->migrator->delete('general.recaptcha_site_key');
             $this->migrator->delete('general.recaptcha_secret_key');
diff --git a/themes/default/views/admin/settings/index.blade.php b/themes/default/views/admin/settings/index.blade.php
index 4d07a9e31..3789727d6 100644
--- a/themes/default/views/admin/settings/index.blade.php
+++ b/themes/default/views/admin/settings/index.blade.php
@@ -47,6 +47,7 @@
                             <nav class="mt-1">
                                 <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="tablist"
                                     data-accordion="false">
+                                  @can("admin.icons.edit")
                                     <li class="nav-item border-bottom-0">
                                         <a href="#icons" class="nav-link" data-toggle="pill" role="tab">
                                             <i class="nav-icon fas fa-image"></i>
@@ -55,6 +56,7 @@
                                             </p>
                                         </a>
                                     </li>
+                                  @endcan
                                     @foreach ($settings as $category => $options)
                                         @if (!str_contains($options['settings_class'], 'Extension'))
                                             @canany(['settings.' . strtolower($category) . '.read', 'settings.' .

From 00b0615a8ae894f33e318e47d8765188da3f7b67 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 11:32:38 +0100
Subject: [PATCH 480/514] better settings descriptions

---
 app/Settings/LocaleSettings.php      | 2 +-
 app/Settings/PterodactylSettings.php | 2 +-
 app/Settings/ReferralSettings.php    | 2 +-
 app/Settings/WebsiteSettings.php     | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/Settings/LocaleSettings.php b/app/Settings/LocaleSettings.php
index 4e38cbe2f..32006f572 100644
--- a/app/Settings/LocaleSettings.php
+++ b/app/Settings/LocaleSettings.php
@@ -67,7 +67,7 @@ public static function getOptionInputData()
             'dynamic' => [
                 'label' => 'Dynamic Locale',
                 'type' => 'boolean',
-                'description' => 'Whether to use the dynamic locale.',
+                'description' => 'Whether to choose the language automatically based on the Geolocation of the client.',
             ],
         ];
     }
diff --git a/app/Settings/PterodactylSettings.php b/app/Settings/PterodactylSettings.php
index fa158120f..6ece4a975 100644
--- a/app/Settings/PterodactylSettings.php
+++ b/app/Settings/PterodactylSettings.php
@@ -75,7 +75,7 @@ public static function getOptionInputData()
             'per_page_limit' => [
                 'label' => 'Per Page Limit',
                 'type' => 'number',
-                'description' => 'The number of servers to show per page.',
+                'description' => 'The number of servers to show per page for the API call. Only change this when needed.',
             ],
         ];
     }
diff --git a/app/Settings/ReferralSettings.php b/app/Settings/ReferralSettings.php
index b08923fde..de16ff89d 100644
--- a/app/Settings/ReferralSettings.php
+++ b/app/Settings/ReferralSettings.php
@@ -54,7 +54,7 @@ public static function getOptionInputData()
             'reward' => [
                 'label' => 'Reward',
                 'type' => 'number',
-                'description' => 'Reward for the referrer.',
+                'description' => 'Reward in credits for the referrer.',
             ],
             'mode' => [
                 'label' => 'Mode',
diff --git a/app/Settings/WebsiteSettings.php b/app/Settings/WebsiteSettings.php
index e6607c210..f768b0212 100644
--- a/app/Settings/WebsiteSettings.php
+++ b/app/Settings/WebsiteSettings.php
@@ -91,7 +91,7 @@ public static function getOptionInputData()
             'seo_description' => [
                 'label' => 'SEO Description',
                 'type' => 'string',
-                'description' => 'The description of the website.',
+                'description' => 'The description of the website shown in the Meta tag (for example when sending the URL in discord).',
             ],
             'enable_login_logo' => [
                 'label' => 'Enable Login Logo',

From 60489a00d6494fca8fba41d17cd8abd92f680b02 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 11:40:07 +0100
Subject: [PATCH 481/514] fix sales tax validator

---
 app/Settings/GeneralSettings.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 3c3310a88..1b8e26944 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -35,7 +35,7 @@ public static function getValidations()
     {
         return [
             'store_enabled' => 'nullable|string',
-            'sales_tax' => 'nullable|number',
+            'sales_tax' => 'nullable|numeric',
             'credits_display_name' => 'required|string',
             'recaptcha_enabled' => 'nullable|string',
             'recaptcha_site_key' => 'nullable|string',

From 43e12c3dd6341aa0bcb066e0591cb2ac426ca68b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 18:47:34 +0100
Subject: [PATCH 482/514] remove unused classes

---
 routes/web.php | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/routes/web.php b/routes/web.php
index 7d56e5f04..f0f6cd61b 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -1,10 +1,5 @@
 <?php
 
-use App\Classes\Settings\Invoices;
-use App\Classes\Settings\Language;
-use App\Classes\Settings\Misc;
-use App\Classes\Settings\Payments;
-use App\Classes\Settings\System;
 use App\Http\Controllers\Admin\ActivityLogController;
 use App\Http\Controllers\Admin\ApplicationApiController;
 use App\Http\Controllers\Admin\InvoiceController;

From 393cbde662c7e54829e296eb5815794490d925c7 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 19:05:01 +0100
Subject: [PATCH 483/514] add validation to tickets

---
 app/Http/Controllers/TicketsController.php         | 14 +++++++-------
 .../2024_06_25_133205_add_discord_settings.php     |  4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index c8c177b2e..56a27c0f5 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -36,14 +36,14 @@ public function index(LocaleSettings $locale_settings, TicketSettings $ticketSet
 
     public function store(Request $request, GeneralSettings $generalSettings)
     {
-       $validateData =  [
-            'title' => 'required',
-            'ticketcategory' => 'required',
-            'priority' => 'required',
-            'message' => 'required',
-
+        $validateData = [
+            'title' => 'required|string|max:255',
+            'ticketcategory' => 'required|numeric',
+            'priority' => ['required', 'in:Low,Medium,High'],
+            'message' => 'required|string|min:10|max:2000',
         ];
-        if ($generalSettings->recaptcha_enabled){
+
+        if ($generalSettings->recaptcha_enabled) {
             $validateData['g-recaptcha-response'] = ['required', 'recaptcha'];
         }
 
diff --git a/database/settings/2024_06_25_133205_add_discord_settings.php b/database/settings/2024_06_25_133205_add_discord_settings.php
index b73729f7d..1ed0ae241 100644
--- a/database/settings/2024_06_25_133205_add_discord_settings.php
+++ b/database/settings/2024_06_25_133205_add_discord_settings.php
@@ -6,8 +6,8 @@ class AddDiscordSettings extends SettingsMigration
 {
     public function up(): void
     {
-        $this->migrator->add('discord.role_on_purchase', null);
-        $this->migrator->add('discord.role_id_on_purchase', null);
+        $this->migrator->add('discord.role_on_purchase', false);
+        $this->migrator->add('discord.role_id_on_purchase', "");
     }
 
     public function down(): void

From d3b0d5a255a1101e8c02b75cb627627efb0349fb Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 20:12:43 +0100
Subject: [PATCH 484/514] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9c5dcfb90..20df67211 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@ Follow the [documentation](https://ctrlpanel.gg/docs/intro) to know how to insta
 
 ### MarketPlace
 
-If you need more functionality, check out [Marketplace](https://market.ctrlpanel.gg/resources/).
+If you need more functionality, check out [Marketplace](https://market.ctrlpanel.gg/).
 
 ## 🆙 How to Update
 

From ccb46f140a554c8aa3dce4f10f83917928619b37 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 21:00:15 +0100
Subject: [PATCH 485/514] fix role on discord select

---
 app/Settings/DiscordSettings.php | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/app/Settings/DiscordSettings.php b/app/Settings/DiscordSettings.php
index 69284e01d..40cc21458 100644
--- a/app/Settings/DiscordSettings.php
+++ b/app/Settings/DiscordSettings.php
@@ -77,9 +77,14 @@ public static function getOptionInputData()
                 'type' => 'string',
                 'description' => 'The role ID for your Discord server.',
             ],
+
             'role_on_purchase' => [
                 'label' => 'Role on Purchase',
-                'type' => 'boolean',
+                'type' => 'select',
+                'options' => [
+                    '0' => 'Disabled',
+                    '1' => 'Enabled'
+                ],
                 'description' => 'Give the user a role on purchase (removes when user has no active servers)',
             ],
             'role_id_on_purchase' => [

From 8ed6b52913c32f8cf712b292080de87029ddfdd4 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 23:23:34 +0100
Subject: [PATCH 486/514] fix discord linking finally

---
 .../Controllers/Auth/SocialiteController.php  |  8 ++---
 app/Models/DiscordUser.php                    |  7 +++--
 app/Providers/AppServiceProvider.php          |  7 +++++
 app/Providers/DiscordServiceProvider.php      | 30 +++++++++++++++++++
 app/Settings/DiscordSettings.php              |  4 +--
 config/app.php                                |  1 +
 config/services.php                           | 10 +------
 7 files changed, 49 insertions(+), 18 deletions(-)
 create mode 100644 app/Providers/DiscordServiceProvider.php

diff --git a/app/Http/Controllers/Auth/SocialiteController.php b/app/Http/Controllers/Auth/SocialiteController.php
index 02904c51f..af0ad213e 100644
--- a/app/Http/Controllers/Auth/SocialiteController.php
+++ b/app/Http/Controllers/Auth/SocialiteController.php
@@ -17,9 +17,9 @@ public function redirect(DiscordSettings $discord_settings)
     {
         $scopes = !empty($discord_settings->bot_token) && !empty($discord_settings->guild_id) ? ['guilds.join'] : [];
 
-        return Socialite::driver('discord')
+        return ( Socialite::driver('discord')
             ->scopes($scopes)
-            ->redirect();
+            ->redirect());
     }
 
     public function callback(DiscordSettings $discord_settings, UserSettings $user_settings)
@@ -70,11 +70,11 @@ public function callback(DiscordSettings $discord_settings, UserSettings $user_s
                 "https://discord.com/api/guilds/{$guildId}/members/{$discord->id}",
                 ['access_token' => $discord->token]
             );
-
+            $discordUser = $user->discordUser;
             //give user a role in the discord server
             if (! empty($roleId)) {
                 // Function addOrRemoveRole is defined in app/Models/DiscordUser.php
-                $user->discordUser->addOrRemoveRole('add', $roleId);
+                $discordUser->addOrRemoveRole('add', $roleId);
             }
         }
 
diff --git a/app/Models/DiscordUser.php b/app/Models/DiscordUser.php
index 900e8c625..fd2940c1d 100644
--- a/app/Models/DiscordUser.php
+++ b/app/Models/DiscordUser.php
@@ -2,6 +2,7 @@
 
 namespace App\Models;
 
+use App\Settings\DiscordSettings;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -53,7 +54,7 @@ public function getAvatar()
      */
     public function addOrRemoveRole(string $action, string $role_id): mixed
     {
-        $discordSettings = app('discord_settings');
+        $discordSettings = app(DiscordSettings::class);
         return match ($action) {
             'add' => Http::withHeaders(
                 [
@@ -63,7 +64,7 @@ public function addOrRemoveRole(string $action, string $role_id): mixed
                 ]
             )->put(
                 "https://discord.com/api/guilds/{$discordSettings->guild_id}/members/{$this->id}/roles/{$discordSettings->role_id}",
-                ['access_token' => $discordSettings->token]
+                ['access_token' => $discordSettings->bot_token]
             ),
             'remove' => Http::withHeaders(
                 [
@@ -73,7 +74,7 @@ public function addOrRemoveRole(string $action, string $role_id): mixed
                 ]
             )->remove(
                 "https://discord.com/api/guilds/{$discordSettings->guild_id}/members/{$this->id}/roles/{$discordSettings->role_id}",
-                ['access_token' => $discordSettings->token]
+                ['access_token' => $discordSettings->bot_token]
             ),
             default => null,
         };
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 5e1f05d05..cfef99b9d 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -3,10 +3,12 @@
 namespace App\Providers;
 
 use App\Models\UsefulLink;
+use App\Settings\DiscordSettings;
 use App\Settings\GeneralSettings;
 use App\Settings\MailSettings;
 use Exception;
 use Illuminate\Pagination\Paginator;
+use Illuminate\Support\Facades\Event;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\URL;
@@ -37,6 +39,10 @@ public function boot()
         Paginator::useBootstrap();
         Schema::defaultStringLength(191);
 
+        Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
+            $event->extendSocialite('discord', \SocialiteProviders\Discord\Provider::class);
+        });
+
         Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) {
             $ok = true;
             $result = [];
@@ -103,6 +109,7 @@ public function boot()
 
             $settings = $this->app->make(MailSettings::class);
             $settings->setConfig();
+
         } catch (Exception $e) {
             Log::error("Couldnt load Settings. Probably the installation is not completet. " . $e);
         }
diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
new file mode 100644
index 000000000..30d0dd0b7
--- /dev/null
+++ b/app/Providers/DiscordServiceProvider.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\Facades\Config;
+use Illuminate\Support\ServiceProvider;
+use App\Settings\DiscordSettings;
+
+class DiscordServiceProvider extends ServiceProvider
+{
+    public function register()
+    {
+        // No need to register anything
+    }
+
+    public function boot()
+    {
+        // Retrieve Discord settings from the Spatie settings class
+        $discordSettings = app(DiscordSettings::class);
+
+        // Inject the settings into the config
+        Config::set('services.discord.client_id', $discordSettings->client_id);
+        Config::set('services.discord.client_secret', $discordSettings->client_secret);
+        Config::set('services.discord.redirect', env('APP_URL', 'http://localhost') . '/auth/callback');
+
+        // optional
+        Config::set('services.discord.allow_gif_avatars', (bool)env('DISCORD_AVATAR_GIF', true));
+        Config::set('services.discord.avatar_default_extension', env('DISCORD_EXTENSION_DEFAULT', 'jpg'));
+    }
+}
diff --git a/app/Settings/DiscordSettings.php b/app/Settings/DiscordSettings.php
index 40cc21458..c2ad55395 100644
--- a/app/Settings/DiscordSettings.php
+++ b/app/Settings/DiscordSettings.php
@@ -75,7 +75,7 @@ public static function getOptionInputData()
             'role_id' => [
                 'label' => 'Role ID',
                 'type' => 'string',
-                'description' => 'The role ID for your Discord server.',
+                'description' => 'Role to give users when linking their discord Account.',
             ],
 
             'role_on_purchase' => [
@@ -85,7 +85,7 @@ public static function getOptionInputData()
                     '0' => 'Disabled',
                     '1' => 'Enabled'
                 ],
-                'description' => 'Give the user a role on purchase (removes when user has no active servers)',
+                'description' => 'Give the user a role on purchase of Credits/Servers (removes when user has no active servers)',
             ],
             'role_id_on_purchase' => [
                 'label' => 'Role ID on Purchase',
diff --git a/config/app.php b/config/app.php
index 9d82ff72b..bc976a3b5 100644
--- a/config/app.php
+++ b/config/app.php
@@ -212,6 +212,7 @@
         Yajra\DataTables\DataTablesServiceProvider::class,
         KKomelin\TranslatableStringExporter\Providers\ExporterServiceProvider::class,
         Biscolab\ReCaptcha\ReCaptchaServiceProvider::class,
+        App\Providers\DiscordServiceProvider::class,
     ],
 
     /*
diff --git a/config/services.php b/config/services.php
index aedb7007c..4ca9034f5 100644
--- a/config/services.php
+++ b/config/services.php
@@ -1,5 +1,6 @@
 <?php
 
+
 return [
 
     /*
@@ -31,14 +32,5 @@
         'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
     ],
 
-    'discord' => [
-        'client_id' => env('DISCORD_CLIENT_ID'),
-        'client_secret' => env('DISCORD_CLIENT_SECRET'),
-        'redirect' => env('APP_URL', 'http://localhost').'/auth/callback',
-
-        // optional
-        'allow_gif_avatars' => (bool) env('DISCORD_AVATAR_GIF', true),
-        'avatar_default_extension' => env('DISCORD_EXTENSION_DEFAULT', 'jpg'), // only pick from jpg, png, webp
-    ],
 
 ];

From 81d55e4b97424e55ab24a31d413e8753c77bd30d Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Sun, 10 Nov 2024 23:34:03 +0100
Subject: [PATCH 487/514] add user to discord role after purchase fix

---
 app/Listeners/UserPayment.php | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/app/Listeners/UserPayment.php b/app/Listeners/UserPayment.php
index 9e1066ef1..cb75f589f 100644
--- a/app/Listeners/UserPayment.php
+++ b/app/Listeners/UserPayment.php
@@ -5,6 +5,7 @@
 use App\Enums\PaymentStatus;
 use App\Events\PaymentEvent;
 use App\Models\User;
+use App\Settings\DiscordSettings;
 use Illuminate\Support\Facades\DB;
 use App\Models\PartnerDiscount;
 use App\Settings\GeneralSettings;
@@ -23,18 +24,28 @@ class UserPayment
 
     private $credits_display_name;
 
+    private $role_id_on_purchase;
+
+    private $role_on_purchase;
+
+    private $bot_token;
+
     /**
      * Create the event listener.
      *
      * @return void
      */
-    public function __construct(UserSettings $user_settings, ReferralSettings $referral_settings, GeneralSettings $general_settings)
+    public function __construct(UserSettings $user_settings, ReferralSettings $referral_settings, GeneralSettings $general_settings, DiscordSettings $discord_settings)
     {
         $this->server_limit_after_irl_purchase = $user_settings->server_limit_after_irl_purchase;
         $this->referral_mode = $referral_settings->mode;
         $this->referral_percentage = $referral_settings->percentage;
         $this->referral_always_give_commission = $referral_settings->always_give_commission;
         $this->credits_display_name = $general_settings->credits_display_name;
+        $this->role_id_on_purchase = $discord_settings->role_id_on_purchase;
+        $this->role_on_purchase = $discord_settings->role_on_purchase;
+        $this->bot_token = $discord_settings->bot_token;
+
     }
 
     /**
@@ -58,6 +69,7 @@ public function handle(PaymentEvent $event)
             $user->update(['server_limit' => $this->server_limit_after_irl_purchase]);
         }
 
+
         //update User with bought item
         if ($shopProduct->type == "Credits") {
             $user->increment('credits', $shopProduct->quantity);
@@ -99,6 +111,18 @@ public function handle(PaymentEvent $event)
             }
         }
 
+        //set discord role
+        if(!empty($this->bot_token) && $this->role_on_purchase && !empty($this->role_id_on_purchase)) {
+            $discordUser = $user->discordUser;
+            $discordUser->addOrRemoveRole('add', $this->role_id_on_purchase);
+
+            activity()
+                ->performedOn($user)
+                ->causedBy($user)
+                ->log('was added  to role ' . $this->role_id_on_purchase . " on Discord");
+        }
+
+
         // LOGS PAYMENT IN THE ACTIVITY LOG
         activity()
             ->performedOn($user)

From 03c2cac26e4aae95138572993ffdf9275528d31e Mon Sep 17 00:00:00 2001
From: Dennis <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 08:55:11 +0100
Subject: [PATCH 488/514] Update SettingsController.php - Remove discord
 settings

---
 app/Http/Controllers/Admin/SettingsController.php | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
index e50ea7b19..3725801ff 100644
--- a/app/Http/Controllers/Admin/SettingsController.php
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -9,7 +9,6 @@
 use Illuminate\Contracts\View\View;
 use Illuminate\Http\Response;
 use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\Redirect;
 use Illuminate\Support\Facades\Validator;
 use Qirolab\Theme\Theme;
@@ -123,19 +122,6 @@ public function update(Request $request)
             $rp = new \ReflectionProperty($settingsClass, $key);
             $rpType = $rp->getType();
 
-            // Check if the settingsclass is a DiscordSettings class
-            if($settings_class == 'App\Settings\DiscordSettings') {
-                if($key === 'client_id' || $key === 'client_secret') {
-
-                    $env = file_get_contents(base_path('.env'));
-                    $env = preg_replace('/DISCORD_CLIENT_ID=(.*)/', 'DISCORD_CLIENT_ID=' . $request->input('client_id'), $env);
-                    $env = preg_replace('/DISCORD_CLIENT_SECRET=(.*)/', 'DISCORD_CLIENT_SECRET=' . $request->input('client_secret'), $env);
-                    file_put_contents(base_path('.env'), $env);
-
-                    Artisan::call('config:clear');
-                }
-            }
-
             if ($rpType == 'bool') {
                 $settingsClass->$key = $request->has($key);
                 continue;

From 23bd41d7fff4ee921cec424702ddc725baa778f8 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 10:04:43 +0100
Subject: [PATCH 489/514] Update TicketsController.php

---
 app/Http/Controllers/TicketsController.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/Http/Controllers/TicketsController.php b/app/Http/Controllers/TicketsController.php
index eee949081..447e0cc8d 100644
--- a/app/Http/Controllers/TicketsController.php
+++ b/app/Http/Controllers/TicketsController.php
@@ -20,7 +20,7 @@
 use Illuminate\Support\Facades\Notification;
 use Illuminate\Support\Facades\RateLimiter;
 use Illuminate\Support\Str;
-use App\Settings\GeneralSettings;
+
 
 class TicketsController extends Controller
 {
@@ -42,7 +42,7 @@ public function store(Request $request, GeneralSettings $generalSettings)
         if (RateLimiter::tooManyAttempts('ticket-send:'.Auth::user()->id, $perMinute = 1)) {
             return redirect()->back()->with('error', __('Please wait before creating a new Ticket'));
         }
-      
+
         $validateData = [
             'title' => 'required|string|max:255',
             'ticketcategory' => 'required|numeric',
@@ -55,7 +55,7 @@ public function store(Request $request, GeneralSettings $generalSettings)
         }
 
         $this->validate($request, $validateData);
-      
+
         $ticket = new Ticket(
             [
                 'title' => $request->input('title'),

From e762b36690940b45599d9a4cee7f1666210517d6 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 10:27:46 +0100
Subject: [PATCH 490/514] change version to 1.0

---
 config/app.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/app.php b/config/app.php
index bc976a3b5..bdece1310 100644
--- a/config/app.php
+++ b/config/app.php
@@ -4,7 +4,7 @@
 
 return [
 
-    'version' => '0.10',
+    'version' => '1.0',
 
     /*
     |--------------------------------------------------------------------------

From c64954ef0acfcacc1f5a0917768f7105eba29618 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 11:42:43 +0100
Subject: [PATCH 491/514] Update DiscordServiceProvider.php

---
 app/Providers/DiscordServiceProvider.php | 28 ++++++++++++++++--------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index 30d0dd0b7..d8f778800 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -15,16 +15,26 @@ public function register()
 
     public function boot()
     {
-        // Retrieve Discord settings from the Spatie settings class
-        $discordSettings = app(DiscordSettings::class);
+        if (config('app.key') == null) return;
 
-        // Inject the settings into the config
-        Config::set('services.discord.client_id', $discordSettings->client_id);
-        Config::set('services.discord.client_secret', $discordSettings->client_secret);
-        Config::set('services.discord.redirect', env('APP_URL', 'http://localhost') . '/auth/callback');
+        try {
+            if (DB::table('settings')->where('name','client_id')->where('group','discord')->exists()) {
+                // Retrieve Discord settings from the Spatie settings class
+                $discordSettings = app(DiscordSettings::class);
 
-        // optional
-        Config::set('services.discord.allow_gif_avatars', (bool)env('DISCORD_AVATAR_GIF', true));
-        Config::set('services.discord.avatar_default_extension', env('DISCORD_EXTENSION_DEFAULT', 'jpg'));
+                // Inject the settings into the config
+                Config::set('services.discord.client_id', $discordSettings->client_id);
+                Config::set('services.discord.client_secret', $discordSettings->client_secret);
+                Config::set('services.discord.redirect', env('APP_URL', 'http://localhost') . '/auth/callback');
+
+                // optional
+                Config::set('services.discord.allow_gif_avatars', (bool)env('DISCORD_AVATAR_GIF', true));
+                Config::set('services.discord.avatar_default_extension', env('DISCORD_EXTENSION_DEFAULT', 'jpg'));
+            } else{
+                Log::error("Setting for Discord not found");
+            }
+        } catch (Exception $e) {
+            Log::error("Couldnt find settings. Probably the installation is not completet. " . $e);
+        }
     }
 }

From 0c78f1768e905c357ab368725636e10186d19467 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 11:47:51 +0100
Subject: [PATCH 492/514] Update DiscordServiceProvider.php

---
 app/Providers/DiscordServiceProvider.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index d8f778800..48cfa49ca 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -3,6 +3,8 @@
 namespace App\Providers;
 
 use Illuminate\Support\Facades\Config;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\ServiceProvider;
 use App\Settings\DiscordSettings;
 

From b10dc36714fffe8d8c4b8cca61197ebd7bdbd7b6 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 11:58:00 +0100
Subject: [PATCH 493/514] Update DiscordServiceProvider.php

---
 app/Providers/DiscordServiceProvider.php | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index 48cfa49ca..5980b46b1 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -3,7 +3,6 @@
 namespace App\Providers;
 
 use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\ServiceProvider;
 use App\Settings\DiscordSettings;
@@ -20,9 +19,8 @@ public function boot()
         if (config('app.key') == null) return;
 
         try {
-            if (DB::table('settings')->where('name','client_id')->where('group','discord')->exists()) {
+            $discordSettings = app(DiscordSettings::class);
                 // Retrieve Discord settings from the Spatie settings class
-                $discordSettings = app(DiscordSettings::class);
 
                 // Inject the settings into the config
                 Config::set('services.discord.client_id', $discordSettings->client_id);
@@ -32,9 +30,7 @@ public function boot()
                 // optional
                 Config::set('services.discord.allow_gif_avatars', (bool)env('DISCORD_AVATAR_GIF', true));
                 Config::set('services.discord.avatar_default_extension', env('DISCORD_EXTENSION_DEFAULT', 'jpg'));
-            } else{
-                Log::error("Setting for Discord not found");
-            }
+
         } catch (Exception $e) {
             Log::error("Couldnt find settings. Probably the installation is not completet. " . $e);
         }

From 34407aff9913bcd1b0b154229f77179ff3cf7f8b Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 14:20:50 +0100
Subject: [PATCH 494/514] Update DiscordServiceProvider.php

---
 app/Providers/DiscordServiceProvider.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index 5980b46b1..85d5965cb 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -19,7 +19,7 @@ public function boot()
         if (config('app.key') == null) return;
 
         try {
-            $discordSettings = app(DiscordSettings::class);
+            $discordSettings = $this->app->make(DiscordSettings::class);
                 // Retrieve Discord settings from the Spatie settings class
 
                 // Inject the settings into the config

From 5d03a7444b7a9cc5ef7675db63fb8dc5078dd7e7 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 14:22:51 +0100
Subject: [PATCH 495/514] Update DiscordServiceProvider.php

---
 app/Providers/DiscordServiceProvider.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index 85d5965cb..019fa33b8 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -23,8 +23,8 @@ public function boot()
                 // Retrieve Discord settings from the Spatie settings class
 
                 // Inject the settings into the config
-                Config::set('services.discord.client_id', $discordSettings->client_id);
-                Config::set('services.discord.client_secret', $discordSettings->client_secret);
+                Config::set('services.discord.client_id', $discordSettings->client_id ?: "");
+                Config::set('services.discord.client_secret', $discordSettings->client_secret ?: "");
                 Config::set('services.discord.redirect', env('APP_URL', 'http://localhost') . '/auth/callback');
 
                 // optional

From b980a091ddcf14dbf7e10ea57d69522b47869b3c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 14:48:22 +0100
Subject: [PATCH 496/514] Fix discord settings omg

---
 app/Providers/DiscordServiceProvider.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index 019fa33b8..79baf51ca 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -4,6 +4,7 @@
 
 use Illuminate\Support\Facades\Config;
 use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\ServiceProvider;
 use App\Settings\DiscordSettings;
 
@@ -17,6 +18,7 @@ public function register()
     public function boot()
     {
         if (config('app.key') == null) return;
+        if(!Schema::hasTable('old_settings')){ return;}
 
         try {
             $discordSettings = $this->app->make(DiscordSettings::class);

From 0bc842c1179aea2e8b5e41555abf53b8c54a10e5 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 11 Nov 2024 15:06:35 +0100
Subject: [PATCH 497/514] Change checking Method

---
 app/Providers/DiscordServiceProvider.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/Providers/DiscordServiceProvider.php b/app/Providers/DiscordServiceProvider.php
index 79baf51ca..4d0e7b514 100644
--- a/app/Providers/DiscordServiceProvider.php
+++ b/app/Providers/DiscordServiceProvider.php
@@ -7,6 +7,7 @@
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\ServiceProvider;
 use App\Settings\DiscordSettings;
+use Exception;
 
 class DiscordServiceProvider extends ServiceProvider
 {
@@ -18,7 +19,7 @@ public function register()
     public function boot()
     {
         if (config('app.key') == null) return;
-        if(!Schema::hasTable('old_settings')){ return;}
+        if (!Schema::hasColumn('settings', 'payload')) return;
 
         try {
             $discordSettings = $this->app->make(DiscordSettings::class);

From f061d0fba4c9b2980614e4adde927be099fb678c Mon Sep 17 00:00:00 2001
From: S0ly <86328249+S0ly@users.noreply.github.com>
Date: Tue, 12 Nov 2024 19:52:35 +0100
Subject: [PATCH 498/514] fix: correctly display version

---
 config/app.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config/app.php b/config/app.php
index bdece1310..7c7b09a3d 100644
--- a/config/app.php
+++ b/config/app.php
@@ -4,7 +4,7 @@
 
 return [
 
-    'version' => '1.0',
+    'version' => '1.0.0',
 
     /*
     |--------------------------------------------------------------------------

From 7e61f16cf69505d6ebab88b867075888c6631125 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 13 Nov 2024 09:27:26 +0100
Subject: [PATCH 499/514] fix some payment related stuff

---
 app/Extensions/PaymentGateways/PayPal/PayPalExtension.php | 3 ++-
 app/Http/Controllers/Admin/PaymentController.php          | 2 +-
 app/Models/ShopProduct.php                                | 2 +-
 app/Traits/Coupon.php                                     | 2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index 981d86ef2..c86973e54 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -57,7 +57,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                         'breakdown' => [
                             'item_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
-                                'value' => $totalPriceString
+                                'value' => $shopProduct->price,
                             ],
                             'tax_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
@@ -75,6 +75,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
             ]
         ];
 
+
         try {
             // Call API with your client and get a response for your call
             $response = self::getPayPalClient()->execute($request);
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index 82efc3b5f..adafe1d8c 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -141,7 +141,7 @@ public function pay(Request $request)
             $paymentGateway = $request->payment_method;
             $couponCode = $request->coupon_code;
 
-            $subtotal = $shopProduct->price;
+            $subtotal = $shopProduct->getTotalPrice();
 
             // Apply Coupon
             if ($couponCode) {
diff --git a/app/Models/ShopProduct.php b/app/Models/ShopProduct.php
index 4515f5d79..278183dc8 100644
--- a/app/Models/ShopProduct.php
+++ b/app/Models/ShopProduct.php
@@ -75,7 +75,7 @@ public function formatToCurrency($value, $locale = 'en_US')
     public function getTaxPercent()
     {
         $generalSettings = new GeneralSettings();
-        $tax = $generalSettings->sales_tax;
+        $tax = intval($generalSettings->sales_tax);
 
         return $tax < 0 ? 0 : $tax;
     }
diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php
index f1d06d27d..7c01efae7 100644
--- a/app/Traits/Coupon.php
+++ b/app/Traits/Coupon.php
@@ -73,7 +73,7 @@ public function isCouponValid(string $couponCode, User $user, string $productId)
     {
         if (is_null($couponCode)) return false;
 
-        $coupon = CouponModel::where('code', $couponCode)->first();
+        $coupon = CouponModel::where('code', $couponCode)->firstOrFail();
         $shopProduct = ShopProduct::findOrFail($productId);
 
         if ($coupon->getStatus() == 'USES_LIMIT_REACHED') {

From ba585b70ead1e13b631c1e6b6101d245ccb2915d Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 13 Nov 2024 13:05:24 +0100
Subject: [PATCH 500/514] Fix Paymentgateways with coupon and tax

---
 .../PaymentGateways/PayPal/PayPalExtension.php      | 13 +++++++------
 .../PaymentGateways/Stripe/StripeExtension.php      |  8 +++-----
 app/Http/Controllers/Admin/PaymentController.php    | 13 +++++++------
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
index c86973e54..04eb97ed9 100644
--- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
+++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
@@ -2,17 +2,13 @@
 
 namespace App\Extensions\PaymentGateways\PayPal;
 
-use App\Events\CouponUsedEvent;
 use App\Events\PaymentEvent;
 use App\Events\UserUpdateCreditsEvent;
-use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
 use App\Classes\PaymentExtension;
 use App\Enums\PaymentStatus;
-use App\Models\PartnerDiscount;
 use App\Models\Payment;
 use App\Models\ShopProduct;
 use App\Models\User;
-use App\Models\Coupon;
 use App\Traits\Coupon as CouponTrait;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
@@ -57,12 +53,16 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                         'breakdown' => [
                             'item_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
-                                'value' => $shopProduct->price,
+                                'value' => $totalPriceString,
                             ],
+
+                            /* Removed due to errors in the coupon discount calculation. Its not used in other paymentgateways aswell and basically nice to have but unnessecary
+
                             'tax_total' => [
                                 'currency_code' => strtoupper($shopProduct->currency_code),
-                                'value' => $shopProduct->getTaxValue(),
+                                'value' => round($shopProduct->getTaxValue(), 2),
                             ]
+                            */
                         ]
                     ]
                 ]
@@ -76,6 +76,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
         ];
 
 
+
         try {
             // Call API with your client and get a response for your call
             $response = self::getPayPalClient()->execute($request);
diff --git a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
index b96134317..d2003fe20 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
@@ -5,14 +5,10 @@
 use App\Classes\AbstractExtension;
 use App\Enums\PaymentStatus;
 use App\Events\PaymentEvent;
-use App\Events\CouponUsedEvent;
 use App\Events\UserUpdateCreditsEvent;
-use App\Extensions\PaymentGateways\Stripe\StripeSettings;
-use App\Models\PartnerDiscount;
 use App\Models\Payment;
 use App\Models\ShopProduct;
 use App\Models\User;
-use App\Models\Coupon;
 use App\Traits\Coupon as CouponTrait;
 use App\Notifications\ConfirmPaymentNotification;
 use Exception;
@@ -59,6 +55,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                     ],
                     'quantity' => 1,
                 ],
+                /* Removed due to errors in the coupon discount calculation. Its not used in other paymentgateways aswell and basically nice to have but unnessecary
                 [
                     'price_data' => [
                         'currency' => $shopProduct->currency_code,
@@ -66,10 +63,11 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                             'name' => __('Tax'),
                             'description' => $shopProduct->getTaxPercent() . '%',
                         ],
-                        'unit_amount_decimal' => round($shopProduct->getTaxValue(), 2) * 100,
+                        'unit_amount_decimal' => round($shopProduct->getTaxValue(), 2),
                     ],
                     'quantity' => 1,
                 ],
+                */
             ],
 
             'mode' => 'payment',
diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php
index adafe1d8c..3d2da91e7 100644
--- a/app/Http/Controllers/Admin/PaymentController.php
+++ b/app/Http/Controllers/Admin/PaymentController.php
@@ -147,6 +147,8 @@ public function pay(Request $request)
             if ($couponCode) {
                 if ($this->isCouponValid($couponCode, $user, $shopProduct->id)) {
                     $subtotal = $this->applyCoupon($couponCode, $subtotal);
+                    event(new CouponUsedEvent($couponCode));
+
                 }
             }
 
@@ -155,13 +157,15 @@ public function pay(Request $request)
             if ($subtotal <= 0) {
                 if ($couponCode) {
                     event(new CouponUsedEvent($couponCode));
+
                 }
 
                 return $this->handleFreeProduct($shopProduct);
             }
-
             // Format the total price to a readable string
             $totalPriceString = number_format($subtotal, 2, '.', '');
+            //reset the price after coupon use
+            $shopProduct->price = $totalPriceString;
 
             // create a new payment
             $payment = Payment::create([
@@ -171,10 +175,10 @@ public function pay(Request $request)
                 'type' => $shopProduct->type,
                 'status' => 'open',
                 'amount' => $shopProduct->quantity,
-                'price' => $totalPriceString,
+                'price' => $shopProduct->price,
                 'tax_value' => $shopProduct->getTaxValue(),
                 'tax_percent' => $shopProduct->getTaxPercent(),
-                'total_price' => $shopProduct->getTotalPrice(),
+                'total_price' => $totalPriceString,
                 'currency_code' => $shopProduct->currency_code,
                 'shop_item_product_id' => $shopProduct->id,
             ]);
@@ -182,9 +186,6 @@ public function pay(Request $request)
             $paymentGatewayExtension = ExtensionHelper::getExtensionClass($paymentGateway);
             $redirectUrl = $paymentGatewayExtension::getRedirectUrl($payment, $shopProduct, $totalPriceString);
 
-            if ($couponCode) {
-                event(new CouponUsedEvent($couponCode));
-            }
         } catch (Exception $e) {
             Log::error($e->getMessage());
             return redirect()->route('store.index')->with('error', __('Oops, something went wrong! Please try again later.'));

From 846b1a9cfecb5ad6e7e95134efcf074ec95a1aec Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Wed, 13 Nov 2024 13:08:54 +0100
Subject: [PATCH 501/514] cleanup double route

---
 routes/web.php | 2 --
 1 file changed, 2 deletions(-)

diff --git a/routes/web.php b/routes/web.php
index a8dd8242e..308549d46 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -128,8 +128,6 @@
         Route::get('roles/datatable', [RoleController::class, 'datatable'])->name('roles.datatable');
         Route::resource('roles', RoleController::class);
         //overview
-        Route::get('legal', [OverViewController::class, 'index'])->name('overview.index');
-
         Route::get('overview', [OverViewController::class, 'index'])->name('overview.index');
         Route::get('overview/sync', [OverViewController::class, 'syncPterodactyl'])->name('overview.sync');
 

From 9a747b4c580ede96f77394fc24f9f119a66ba747 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Wed, 13 Nov 2024 16:17:56 +0200
Subject: [PATCH 502/514] feat(installer): :globe_with_meridians: add UTC
 timezone option as default in installer

---
 public/installer/views/timezone-configuration.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/public/installer/views/timezone-configuration.php b/public/installer/views/timezone-configuration.php
index 3766e73ff..9aaaf595d 100644
--- a/public/installer/views/timezone-configuration.php
+++ b/public/installer/views/timezone-configuration.php
@@ -16,6 +16,7 @@
                 <div class="flex flex-col mb-3">
                     <label for="timezone">Timezone</label>
                     <select id="timezone" name="timezone" required class="px-2 py-2 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
+                        <option value="UTC" selected>UTC</option>
                         <?php
                         foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) {
                             if ($timezoneIdentifier === 'UTC') {

From 5aff7bf0b5c75f39cf177eeb9f61bec71414e5d5 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Wed, 13 Nov 2024 16:20:37 +0200
Subject: [PATCH 503/514] chore(installer): :wrench: increase minimum supported
 PHP version to 8.2

---
 public/installer/src/functions/environment.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/installer/src/functions/environment.php b/public/installer/src/functions/environment.php
index c98223212..456680673 100644
--- a/public/installer/src/functions/environment.php
+++ b/public/installer/src/functions/environment.php
@@ -52,7 +52,7 @@ function checkExtensions(): array
 }
 
 $requirements = [
-    'minPhp' => '8.1',
+    'minPhp' => '8.2',
     'maxPhp' => '8.4', // This version is not supported
     'mysql' => '5.7.22',
 ];

From a3bd771f8d01db4c899827abdd2d4a1eb6710d19 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 14 Nov 2024 13:01:29 +0100
Subject: [PATCH 504/514] Fix getAllExtensionClasses()

---
 app/Helpers/ExtensionHelper.php | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/app/Helpers/ExtensionHelper.php b/app/Helpers/ExtensionHelper.php
index f465078b0..fd2e653cc 100644
--- a/app/Helpers/ExtensionHelper.php
+++ b/app/Helpers/ExtensionHelper.php
@@ -62,13 +62,19 @@ public static function getAllExtensionClasses()
     {
         $extensions = self::getAllExtensions();
 
-        // replace all slashes with backslashes
-        $extensions = array_map(fn ($item) => str_replace('/', '\\', $item), $extensions);
-        // add the ExtensionClass to the end of the namespace
-        $extensions = array_map(fn ($item) => $item . '\\' . basename($item) . 'Extension', $extensions);
-        // filter out non existing extension classes
+        // Replace slashes with backslashes and add the gateway name with "Extension" at the end
+        $extensions = array_map(function ($item) {
+            // Convert to backslashes
+            $item = str_replace('/', '\\', $item);
+            // Get the last part of the path as the gateway name
+            $gatewayName = explode('\\', $item);
+            
+            // Construct the full class namespace
+            return $item . '\\' . end($gatewayName) . 'Extension';
+        }, $extensions);
+
+        // Filter out non-existing extension classes
         $extensions = array_filter($extensions, fn ($item) => class_exists($item));
-
         return $extensions;
     }
 

From 98921c14fa6602fbba5de57c6b1944252c996660 Mon Sep 17 00:00:00 2001
From: MrWeez <arsenyplis2018@gmail.com>
Date: Thu, 14 Nov 2024 15:17:30 +0200
Subject: [PATCH 505/514] =?UTF-8?q?fix(installer):=20=F0=9F=90=9B=20remove?=
 =?UTF-8?q?=20=3Fstep=20parameter=20from=20URL=20to=20prevent=20unintended?=
 =?UTF-8?q?=20navigation=20on=20page=20reload?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: S0ly <86328249+S0ly@users.noreply.github.com>
---
 public/installer/index.php | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/public/installer/index.php b/public/installer/index.php
index 403ca3cc5..600a3297e 100644
--- a/public/installer/index.php
+++ b/public/installer/index.php
@@ -62,16 +62,28 @@
 
 if (isset($_GET['step'])) {
     $stepValue = $_GET['step'];
+    $currentStep = $_SESSION['current_installation_step'];
 
-    if (is_numeric($stepValue) && $stepValue >= 1 && $stepValue <= $_SESSION['last_installation_step']) {
-        // Step is valid numeric within range:
-        $_SESSION['current_installation_step'] = $stepValue;
-    } elseif (strtolower($stepValue) === 'next' && $_SESSION['current_installation_step'] < $_SESSION['last_installation_step']) {
-        // Move to next step:
+    if (strtolower($stepValue) === 'next' && $currentStep < $_SESSION['last_installation_step']) {
         $_SESSION['current_installation_step']++;
-    } elseif (strtolower($stepValue) === 'previous' && $_SESSION['current_installation_step'] > 1) {
-        // Move to previous step:
-        $_SESSION['current_installation_step']--;
+        // Redirect to clean URL after processing
+        header('Location: index.php');
+        exit;
+    }
+    elseif (strtolower($stepValue) === 'previous' && $currentStep > 1) {
+        if ($stepConfig[$currentStep - 1]['is_revertable']) {
+            $_SESSION['current_installation_step']--;
+            header('Location: index.php');
+            exit;
+        }
+    }
+    elseif (is_numeric($stepValue)) {
+        // Only allow accessing previous or current steps
+        if ($stepValue <= $currentStep && $stepValue >= 1 && $stepValue <= $_SESSION['last_installation_step']) {
+            $_SESSION['current_installation_step'] = $stepValue;
+        }
+        header('Location: index.php');
+        exit;
     }
 }
 
@@ -85,7 +97,7 @@
 include "./views/{$viewName}.php";
 include './views/layout-bottom.php';
 
-// setting / resetting the error message
+// setting / reseting the error message
 $_SESSION['error-message'] = null;
 
 ?>
\ No newline at end of file

From f36b1d34194a039fafd3606933450677c6cecb5c Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 14 Nov 2024 22:26:41 +0100
Subject: [PATCH 506/514] fix mercado payment gateway

---
 .../PaymentGateways/MercadoPago/MercadoPagoExtension.php      | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
index 82a067722..be280ba51 100644
--- a/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
+++ b/app/Extensions/PaymentGateways/MercadoPago/MercadoPagoExtension.php
@@ -125,11 +125,11 @@ static function Webhook(Request $request): JsonResponse
                 if ($notification == '123456') return response()->json(['success' => true], 200);
 
                 /**
-                 * Check action have payment.*, 
+                 * Check action have payment.*,
                  * what is expected for this type of api
                  */
                 if (str_contains($action, 'payment')) {
-                    $url = "https://api.mercadopago.com/v1/payments/" . $notificationId;
+                    $url = "https://api.mercadopago.com/v1/payments/" . $notification;
                     $settings = new MercadoPagoSettings();
                     $response = Http::withHeaders([
                         'Content-Type' => 'application/json',

From 04130ed76552794f12bc6e2cf0eb8d645990a55a Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Mon, 18 Nov 2024 09:09:26 +0100
Subject: [PATCH 507/514] fix stripe

---
 .../PaymentGateways/Stripe/StripeExtension.php           | 9 ++++++++-
 app/Helpers/ExtensionHelper.php                          | 5 +++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
index d2003fe20..12f80844f 100644
--- a/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
+++ b/app/Extensions/PaymentGateways/Stripe/StripeExtension.php
@@ -51,7 +51,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
                             'name' => $shopProduct->display,
                             'description' => $shopProduct->description,
                         ],
-                        'unit_amount_decimal' => $totalPriceString,
+                        'unit_amount_decimal' => self::priceInCents($totalPriceString),
                     ],
                     'quantity' => 1,
                 ],
@@ -363,4 +363,11 @@ public static function checkPriceAmount(float $amount,  string $currencyCode, st
         ];
         return $amount >= $minimums[$currencyCode][$payment_method];
     }
+    public static function priceInCents($price){
+        $centPrice = str_replace(".", "", $price);
+        $centPrice = str_replace(",", "", $centPrice);
+        //$centPrice = str_pad($centPrice, 4, '0', STR_PAD_RIGHT);
+        return $centPrice;
+    }
+
 }
diff --git a/app/Helpers/ExtensionHelper.php b/app/Helpers/ExtensionHelper.php
index fd2e653cc..6bf0d3726 100644
--- a/app/Helpers/ExtensionHelper.php
+++ b/app/Helpers/ExtensionHelper.php
@@ -68,9 +68,10 @@ public static function getAllExtensionClasses()
             $item = str_replace('/', '\\', $item);
             // Get the last part of the path as the gateway name
             $gatewayName = explode('\\', $item);
-            
+            $gatewayName = array_pop($gatewayName);
+
             // Construct the full class namespace
-            return $item . '\\' . end($gatewayName) . 'Extension';
+            return $item . '\\' . $gatewayName . 'Extension';
         }, $extensions);
 
         // Filter out non-existing extension classes

From 29b706245a2024eb3df5a1766fb16031f02462eb Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 18 Nov 2024 12:48:22 +0100
Subject: [PATCH 508/514] fix: Do not unnullify columns

---
 ..._add_required_nullable_and_text_columns.php | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php b/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php
index 41f2c6c0f..a28f51083 100644
--- a/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php
+++ b/database/migrations/2024_07_24_175733_add_required_nullable_and_text_columns.php
@@ -28,19 +28,5 @@ public function up(): void
     /**
      * Reverse the migrations.
      */
-    public function down(): void
-    {
-        Schema::table('locations', function (Blueprint $table) {
-            $table->string('description')->change();
-        });
-        Schema::table('nodes', function (Blueprint $table) {
-            $table->string('description')->change();
-        });
-        Schema::table('nests', function (Blueprint $table) {
-            $table->string('description')->change();
-        });
-        Schema::table('eggs', function (Blueprint $table) {
-            $table->string('description')->change();
-        });
-    }
-};
\ No newline at end of file
+    public function down(): void {}
+};

From 3c49a01607d7a2e99e9c0d6468f117511c4d6023 Mon Sep 17 00:00:00 2001
From: IceToast <social@icetoast.de>
Date: Mon, 18 Nov 2024 12:48:33 +0100
Subject: [PATCH 509/514] chore: Update deps

---
 composer.lock | 1174 +++++++++++++++++++++++--------------------------
 1 file changed, 557 insertions(+), 617 deletions(-)

diff --git a/composer.lock b/composer.lock
index 20e494507..c8907a7ff 100644
--- a/composer.lock
+++ b/composer.lock
@@ -8,16 +8,16 @@
     "packages": [
         {
             "name": "aws/aws-crt-php",
-            "version": "v1.2.6",
+            "version": "v1.2.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/awslabs/aws-crt-php.git",
-                "reference": "a63485b65b6b3367039306496d49737cf1995408"
+                "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/a63485b65b6b3367039306496d49737cf1995408",
-                "reference": "a63485b65b6b3367039306496d49737cf1995408",
+                "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e",
+                "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e",
                 "shasum": ""
             },
             "require": {
@@ -56,22 +56,22 @@
             ],
             "support": {
                 "issues": "https://github.com/awslabs/aws-crt-php/issues",
-                "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.6"
+                "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7"
             },
-            "time": "2024-06-13T17:21:28+00:00"
+            "time": "2024-10-18T22:15:13+00:00"
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.316.3",
+            "version": "3.328.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "e832e594b3c213760e067e15ef2739f77505e832"
+                "reference": "a99b58e166ae367f2b067937afb04e843e900745"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e832e594b3c213760e067e15ef2739f77505e832",
-                "reference": "e832e594b3c213760e067e15ef2739f77505e832",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a99b58e166ae367f2b067937afb04e843e900745",
+                "reference": "a99b58e166ae367f2b067937afb04e843e900745",
                 "shasum": ""
             },
             "require": {
@@ -124,7 +124,10 @@
                 ],
                 "psr-4": {
                     "Aws\\": "src/"
-                }
+                },
+                "exclude-from-classmap": [
+                    "src/data/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -151,9 +154,9 @@
             "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.316.3"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.328.0"
             },
-            "time": "2024-07-12T18:07:23+00:00"
+            "time": "2024-11-15T19:06:57+00:00"
         },
         {
             "name": "barryvdh/laravel-dompdf",
@@ -510,16 +513,16 @@
         },
         {
             "name": "doctrine/dbal",
-            "version": "4.0.4",
+            "version": "4.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "50fda19f80724b55ff770bb4ff352407008e63c5"
+                "reference": "dadd35300837a3a2184bd47d403333b15d0a9bd0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/50fda19f80724b55ff770bb4ff352407008e63c5",
-                "reference": "50fda19f80724b55ff770bb4ff352407008e63c5",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/dadd35300837a3a2184bd47d403333b15d0a9bd0",
+                "reference": "dadd35300837a3a2184bd47d403333b15d0a9bd0",
                 "shasum": ""
             },
             "require": {
@@ -532,16 +535,16 @@
                 "doctrine/coding-standard": "12.0.0",
                 "fig/log-test": "^1",
                 "jetbrains/phpstorm-stubs": "2023.2",
-                "phpstan/phpstan": "1.11.5",
+                "phpstan/phpstan": "1.12.6",
                 "phpstan/phpstan-phpunit": "1.4.0",
                 "phpstan/phpstan-strict-rules": "^1.6",
-                "phpunit/phpunit": "10.5.22",
+                "phpunit/phpunit": "10.5.30",
                 "psalm/plugin-phpunit": "0.19.0",
                 "slevomat/coding-standard": "8.13.1",
-                "squizlabs/php_codesniffer": "3.10.1",
+                "squizlabs/php_codesniffer": "3.10.2",
                 "symfony/cache": "^6.3.8|^7.0",
                 "symfony/console": "^5.4|^6.3|^7.0",
-                "vimeo/psalm": "5.24.0"
+                "vimeo/psalm": "5.25.0"
             },
             "suggest": {
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -598,7 +601,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/4.0.4"
+                "source": "https://github.com/doctrine/dbal/tree/4.2.1"
             },
             "funding": [
                 {
@@ -614,7 +617,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-19T11:57:23+00:00"
+            "time": "2024-10-10T18:01:27+00:00"
         },
         {
             "name": "doctrine/deprecations",
@@ -895,16 +898,16 @@
         },
         {
             "name": "dragonmantank/cron-expression",
-            "version": "v3.3.3",
+            "version": "v3.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/dragonmantank/cron-expression.git",
-                "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a"
+                "reference": "8c784d071debd117328803d86b2097615b457500"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
-                "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
+                "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500",
+                "reference": "8c784d071debd117328803d86b2097615b457500",
                 "shasum": ""
             },
             "require": {
@@ -917,10 +920,14 @@
             "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",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.x-dev"
+                }
+            },
             "autoload": {
                 "psr-4": {
                     "Cron\\": "src/Cron/"
@@ -944,7 +951,7 @@
             ],
             "support": {
                 "issues": "https://github.com/dragonmantank/cron-expression/issues",
-                "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3"
+                "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0"
             },
             "funding": [
                 {
@@ -952,7 +959,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-08-10T19:36:49+00:00"
+            "time": "2024-10-09T13:47:03+00:00"
         },
         {
             "name": "egulias/email-validator",
@@ -1398,16 +1405,16 @@
         },
         {
             "name": "guzzlehttp/promises",
-            "version": "2.0.3",
+            "version": "2.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/promises.git",
-                "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8"
+                "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8",
-                "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
+                "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
                 "shasum": ""
             },
             "require": {
@@ -1461,7 +1468,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/promises/issues",
-                "source": "https://github.com/guzzle/promises/tree/2.0.3"
+                "source": "https://github.com/guzzle/promises/tree/2.0.4"
             },
             "funding": [
                 {
@@ -1477,7 +1484,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-18T10:29:17+00:00"
+            "time": "2024-10-17T10:06:22+00:00"
         },
         {
             "name": "guzzlehttp/psr7",
@@ -1805,16 +1812,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v11.18.1",
+            "version": "v11.32.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8"
+                "reference": "bc2aad63f83ee5089be7b21cf29d645ccf31e927"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/b19ba518c56852567e99fbae9321bc436c2cc5a8",
-                "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/bc2aad63f83ee5089be7b21cf29d645ccf31e927",
+                "reference": "bc2aad63f83ee5089be7b21cf29d645ccf31e927",
                 "shasum": ""
             },
             "require": {
@@ -1833,7 +1840,7 @@
                 "fruitcake/php-cors": "^1.3",
                 "guzzlehttp/guzzle": "^7.8",
                 "guzzlehttp/uri-template": "^1.0",
-                "laravel/prompts": "^0.1.18",
+                "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0",
                 "laravel/serializable-closure": "^1.3",
                 "league/commonmark": "^2.2.1",
                 "league/flysystem": "^3.8.0",
@@ -1876,6 +1883,7 @@
                 "illuminate/bus": "self.version",
                 "illuminate/cache": "self.version",
                 "illuminate/collections": "self.version",
+                "illuminate/concurrency": "self.version",
                 "illuminate/conditionable": "self.version",
                 "illuminate/config": "self.version",
                 "illuminate/console": "self.version",
@@ -1918,7 +1926,7 @@
                 "league/flysystem-sftp-v3": "^3.0",
                 "mockery/mockery": "^1.6",
                 "nyholm/psr7": "^1.2",
-                "orchestra/testbench-core": "^9.1.5",
+                "orchestra/testbench-core": "^9.5",
                 "pda/pheanstalk": "^5.0",
                 "phpstan/phpstan": "^1.11.5",
                 "phpunit/phpunit": "^10.5|^11.0",
@@ -1976,6 +1984,8 @@
                     "src/Illuminate/Events/functions.php",
                     "src/Illuminate/Filesystem/functions.php",
                     "src/Illuminate/Foundation/helpers.php",
+                    "src/Illuminate/Log/functions.php",
+                    "src/Illuminate/Support/functions.php",
                     "src/Illuminate/Support/helpers.php"
                 ],
                 "psr-4": {
@@ -2007,25 +2017,25 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-07-26T10:39:29+00:00"
+            "time": "2024-11-15T17:04:33+00:00"
         },
         {
             "name": "laravel/prompts",
-            "version": "v0.1.24",
+            "version": "v0.3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/prompts.git",
-                "reference": "409b0b4305273472f3754826e68f4edbd0150149"
+                "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/prompts/zipball/409b0b4305273472f3754826e68f4edbd0150149",
-                "reference": "409b0b4305273472f3754826e68f4edbd0150149",
+                "url": "https://api.github.com/repos/laravel/prompts/zipball/0e0535747c6b8d6d10adca8b68293cf4517abb0f",
+                "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f",
                 "shasum": ""
             },
             "require": {
+                "composer-runtime-api": "^2.2",
                 "ext-mbstring": "*",
-                "illuminate/collections": "^10.0|^11.0",
                 "php": "^8.1",
                 "symfony/console": "^6.2|^7.0"
             },
@@ -2034,8 +2044,9 @@
                 "laravel/framework": ">=10.17.0 <10.25.0"
             },
             "require-dev": {
+                "illuminate/collections": "^10.0|^11.0",
                 "mockery/mockery": "^1.5",
-                "pestphp/pest": "^2.3",
+                "pestphp/pest": "^2.3|^3.4",
                 "phpstan/phpstan": "^1.11",
                 "phpstan/phpstan-mockery": "^1.1"
             },
@@ -2045,7 +2056,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "0.1.x-dev"
+                    "dev-main": "0.3.x-dev"
                 }
             },
             "autoload": {
@@ -2063,32 +2074,33 @@
             "description": "Add beautiful and user-friendly forms to your command-line applications.",
             "support": {
                 "issues": "https://github.com/laravel/prompts/issues",
-                "source": "https://github.com/laravel/prompts/tree/v0.1.24"
+                "source": "https://github.com/laravel/prompts/tree/v0.3.2"
             },
-            "time": "2024-06-17T13:58:22+00:00"
+            "time": "2024-11-12T14:59:47+00:00"
         },
         {
             "name": "laravel/serializable-closure",
-            "version": "v1.3.3",
+            "version": "v1.3.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/serializable-closure.git",
-                "reference": "3dbf8a8e914634c48d389c1234552666b3d43754"
+                "reference": "f865a58ea3a0107c336b7045104c75243fa59d96"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754",
-                "reference": "3dbf8a8e914634c48d389c1234552666b3d43754",
+                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f865a58ea3a0107c336b7045104c75243fa59d96",
+                "reference": "f865a58ea3a0107c336b7045104c75243fa59d96",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.3|^8.0"
             },
             "require-dev": {
-                "nesbot/carbon": "^2.61",
+                "illuminate/support": "^8.0|^9.0|^10.0|^11.0",
+                "nesbot/carbon": "^2.61|^3.0",
                 "pestphp/pest": "^1.21.3",
                 "phpstan/phpstan": "^1.8.2",
-                "symfony/var-dumper": "^5.4.11"
+                "symfony/var-dumper": "^5.4.11|^6.2.0|^7.0.0"
             },
             "type": "library",
             "extra": {
@@ -2125,20 +2137,20 @@
                 "issues": "https://github.com/laravel/serializable-closure/issues",
                 "source": "https://github.com/laravel/serializable-closure"
             },
-            "time": "2023-11-08T14:08:06+00:00"
+            "time": "2024-11-11T17:06:04+00:00"
         },
         {
             "name": "laravel/socialite",
-            "version": "v5.15.1",
+            "version": "v5.16.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/socialite.git",
-                "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029"
+                "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/socialite/zipball/cc02625f0bd1f95dc3688eb041cce0f1e709d029",
-                "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029",
+                "url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
+                "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
                 "shasum": ""
             },
             "require": {
@@ -2197,20 +2209,20 @@
                 "issues": "https://github.com/laravel/socialite/issues",
                 "source": "https://github.com/laravel/socialite"
             },
-            "time": "2024-06-28T20:09:34+00:00"
+            "time": "2024-09-03T09:46:57+00:00"
         },
         {
             "name": "laravel/tinker",
-            "version": "v2.9.0",
+            "version": "v2.10.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/tinker.git",
-                "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe"
+                "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe",
-                "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe",
+                "url": "https://api.github.com/repos/laravel/tinker/zipball/ba4d51eb56de7711b3a37d63aa0643e99a339ae5",
+                "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5",
                 "shasum": ""
             },
             "require": {
@@ -2261,9 +2273,9 @@
             ],
             "support": {
                 "issues": "https://github.com/laravel/tinker/issues",
-                "source": "https://github.com/laravel/tinker/tree/v2.9.0"
+                "source": "https://github.com/laravel/tinker/tree/v2.10.0"
             },
-            "time": "2024-01-04T16:10:04+00:00"
+            "time": "2024-09-23T13:32:56+00:00"
         },
         {
             "name": "laravel/ui",
@@ -2396,16 +2408,16 @@
         },
         {
             "name": "league/commonmark",
-            "version": "2.5.1",
+            "version": "2.5.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/commonmark.git",
-                "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c"
+                "reference": "b650144166dfa7703e62a22e493b853b58d874b0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c",
-                "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c",
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0",
+                "reference": "b650144166dfa7703e62a22e493b853b58d874b0",
                 "shasum": ""
             },
             "require": {
@@ -2418,8 +2430,8 @@
             },
             "require-dev": {
                 "cebe/markdown": "^1.0",
-                "commonmark/cmark": "0.31.0",
-                "commonmark/commonmark.js": "0.31.0",
+                "commonmark/cmark": "0.31.1",
+                "commonmark/commonmark.js": "0.31.1",
                 "composer/package-versions-deprecated": "^1.8",
                 "embed/embed": "^4.4",
                 "erusev/parsedown": "^1.0",
@@ -2498,7 +2510,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-24T12:52:09+00:00"
+            "time": "2024-08-16T11:46:16+00:00"
         },
         {
             "name": "league/config",
@@ -2584,16 +2596,16 @@
         },
         {
             "name": "league/flysystem",
-            "version": "3.28.0",
+            "version": "3.29.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem.git",
-                "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c"
+                "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c",
-                "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319",
+                "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319",
                 "shasum": ""
             },
             "require": {
@@ -2661,22 +2673,22 @@
             ],
             "support": {
                 "issues": "https://github.com/thephpleague/flysystem/issues",
-                "source": "https://github.com/thephpleague/flysystem/tree/3.28.0"
+                "source": "https://github.com/thephpleague/flysystem/tree/3.29.1"
             },
-            "time": "2024-05-22T10:09:12+00:00"
+            "time": "2024-10-08T08:58:34+00:00"
         },
         {
             "name": "league/flysystem-aws-s3-v3",
-            "version": "3.28.0",
+            "version": "3.29.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
-                "reference": "22071ef1604bc776f5ff2468ac27a752514665c8"
+                "reference": "c6ff6d4606e48249b63f269eba7fabdb584e76a9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/22071ef1604bc776f5ff2468ac27a752514665c8",
-                "reference": "22071ef1604bc776f5ff2468ac27a752514665c8",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/c6ff6d4606e48249b63f269eba7fabdb584e76a9",
+                "reference": "c6ff6d4606e48249b63f269eba7fabdb584e76a9",
                 "shasum": ""
             },
             "require": {
@@ -2716,22 +2728,22 @@
                 "storage"
             ],
             "support": {
-                "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.28.0"
+                "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.29.0"
             },
-            "time": "2024-05-06T20:05:52+00:00"
+            "time": "2024-08-17T13:10:48+00:00"
         },
         {
             "name": "league/flysystem-local",
-            "version": "3.28.0",
+            "version": "3.29.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem-local.git",
-                "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40"
+                "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/13f22ea8be526ea58c2ddff9e158ef7c296e4f40",
-                "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27",
+                "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27",
                 "shasum": ""
             },
             "require": {
@@ -2765,22 +2777,22 @@
                 "local"
             ],
             "support": {
-                "source": "https://github.com/thephpleague/flysystem-local/tree/3.28.0"
+                "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0"
             },
-            "time": "2024-05-06T20:05:52+00:00"
+            "time": "2024-08-09T21:24:39+00:00"
         },
         {
             "name": "league/mime-type-detection",
-            "version": "1.15.0",
+            "version": "1.16.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/mime-type-detection.git",
-                "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301"
+                "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
-                "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
+                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9",
+                "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9",
                 "shasum": ""
             },
             "require": {
@@ -2811,7 +2823,7 @@
             "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.15.0"
+                "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0"
             },
             "funding": [
                 {
@@ -2823,7 +2835,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-28T23:22:08+00:00"
+            "time": "2024-09-21T08:32:55+00:00"
         },
         {
             "name": "league/oauth1-client",
@@ -2970,16 +2982,16 @@
         },
         {
             "name": "monolog/monolog",
-            "version": "3.7.0",
+            "version": "3.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/monolog.git",
-                "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8"
+                "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8",
-                "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67",
+                "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67",
                 "shasum": ""
             },
             "require": {
@@ -2999,12 +3011,14 @@
                 "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": "^10.5.17",
+                "php-console/php-console": "^3.1.8",
+                "phpstan/phpstan": "^2",
+                "phpstan/phpstan-deprecation-rules": "^2",
+                "phpstan/phpstan-strict-rules": "^2",
+                "phpunit/phpunit": "^10.5.17 || ^11.0.7",
                 "predis/predis": "^1.1 || ^2",
-                "ruflin/elastica": "^7",
+                "rollbar/rollbar": "^4.0",
+                "ruflin/elastica": "^7 || ^8",
                 "symfony/mailer": "^5.4 || ^6",
                 "symfony/mime": "^5.4 || ^6"
             },
@@ -3055,7 +3069,7 @@
             ],
             "support": {
                 "issues": "https://github.com/Seldaek/monolog/issues",
-                "source": "https://github.com/Seldaek/monolog/tree/3.7.0"
+                "source": "https://github.com/Seldaek/monolog/tree/3.8.0"
             },
             "funding": [
                 {
@@ -3067,20 +3081,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-28T09:40:51+00:00"
+            "time": "2024-11-12T13:57:08+00:00"
         },
         {
             "name": "mtdowling/jmespath.php",
-            "version": "2.7.0",
+            "version": "2.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/jmespath/jmespath.php.git",
-                "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b"
+                "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/bbb69a935c2cbb0c03d7f481a238027430f6440b",
-                "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b",
+                "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc",
+                "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc",
                 "shasum": ""
             },
             "require": {
@@ -3097,7 +3111,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.7-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -3131,26 +3145,26 @@
             ],
             "support": {
                 "issues": "https://github.com/jmespath/jmespath.php/issues",
-                "source": "https://github.com/jmespath/jmespath.php/tree/2.7.0"
+                "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0"
             },
-            "time": "2023-08-25T10:54:48+00:00"
+            "time": "2024-09-04T18:46:31+00:00"
         },
         {
             "name": "nesbot/carbon",
-            "version": "3.7.0",
+            "version": "3.8.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139"
+                "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cb4374784c87d0a0294e8513a52eb63c0aff3139",
-                "reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947",
+                "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947",
                 "shasum": ""
             },
             "require": {
-                "carbonphp/carbon-doctrine-types": "*",
+                "carbonphp/carbon-doctrine-types": "<100.0",
                 "ext-json": "*",
                 "php": "^8.1",
                 "psr/clock": "^1.0",
@@ -3239,28 +3253,28 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-16T22:29:20+00:00"
+            "time": "2024-11-07T17:46:48+00:00"
         },
         {
             "name": "nette/schema",
-            "version": "v1.3.0",
+            "version": "v1.3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nette/schema.git",
-                "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188"
+                "reference": "da801d52f0354f70a638673c4a0f04e16529431d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
-                "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
+                "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d",
+                "reference": "da801d52f0354f70a638673c4a0f04e16529431d",
                 "shasum": ""
             },
             "require": {
                 "nette/utils": "^4.0",
-                "php": "8.1 - 8.3"
+                "php": "8.1 - 8.4"
             },
             "require-dev": {
-                "nette/tester": "^2.4",
+                "nette/tester": "^2.5.2",
                 "phpstan/phpstan-nette": "^1.0",
                 "tracy/tracy": "^2.8"
             },
@@ -3299,26 +3313,26 @@
             ],
             "support": {
                 "issues": "https://github.com/nette/schema/issues",
-                "source": "https://github.com/nette/schema/tree/v1.3.0"
+                "source": "https://github.com/nette/schema/tree/v1.3.2"
             },
-            "time": "2023-12-11T11:54:22+00:00"
+            "time": "2024-10-06T23:10:23+00:00"
         },
         {
             "name": "nette/utils",
-            "version": "v4.0.4",
+            "version": "v4.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nette/utils.git",
-                "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218"
+                "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
-                "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
+                "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
+                "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.0 <8.4"
+                "php": "8.0 - 8.4"
             },
             "conflict": {
                 "nette/finder": "<3",
@@ -3385,22 +3399,22 @@
             ],
             "support": {
                 "issues": "https://github.com/nette/utils/issues",
-                "source": "https://github.com/nette/utils/tree/v4.0.4"
+                "source": "https://github.com/nette/utils/tree/v4.0.5"
             },
-            "time": "2024-01-17T16:50:36+00:00"
+            "time": "2024-08-07T15:39:19+00:00"
         },
         {
             "name": "nikic/php-parser",
-            "version": "v5.1.0",
+            "version": "v5.3.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1"
+                "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1",
-                "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b",
+                "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b",
                 "shasum": ""
             },
             "require": {
@@ -3443,38 +3457,37 @@
             ],
             "support": {
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
-                "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0"
+                "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1"
             },
-            "time": "2024-07-01T20:03:41+00:00"
+            "time": "2024-10-08T18:51:32+00:00"
         },
         {
             "name": "nunomaduro/termwind",
-            "version": "v2.0.1",
+            "version": "v2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nunomaduro/termwind.git",
-                "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a"
+                "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/58c4c58cf23df7f498daeb97092e34f5259feb6a",
-                "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a",
+                "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/42c84e4e8090766bbd6445d06cd6e57650626ea3",
+                "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3",
                 "shasum": ""
             },
             "require": {
                 "ext-mbstring": "*",
                 "php": "^8.2",
-                "symfony/console": "^7.0.4"
+                "symfony/console": "^7.1.5"
             },
             "require-dev": {
-                "ergebnis/phpstan-rules": "^2.2.0",
-                "illuminate/console": "^11.0.0",
-                "laravel/pint": "^1.14.0",
-                "mockery/mockery": "^1.6.7",
-                "pestphp/pest": "^2.34.1",
-                "phpstan/phpstan": "^1.10.59",
-                "phpstan/phpstan-strict-rules": "^1.5.2",
-                "symfony/var-dumper": "^7.0.4",
+                "illuminate/console": "^11.28.0",
+                "laravel/pint": "^1.18.1",
+                "mockery/mockery": "^1.6.12",
+                "pestphp/pest": "^2.36.0",
+                "phpstan/phpstan": "^1.12.6",
+                "phpstan/phpstan-strict-rules": "^1.6.1",
+                "symfony/var-dumper": "^7.1.5",
                 "thecodingmachine/phpstan-strict-rules": "^1.0.0"
             },
             "type": "library",
@@ -3517,7 +3530,7 @@
             ],
             "support": {
                 "issues": "https://github.com/nunomaduro/termwind/issues",
-                "source": "https://github.com/nunomaduro/termwind/tree/v2.0.1"
+                "source": "https://github.com/nunomaduro/termwind/tree/v2.2.0"
             },
             "funding": [
                 {
@@ -3533,7 +3546,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-03-06T16:17:14+00:00"
+            "time": "2024-10-15T16:15:16+00:00"
         },
         {
             "name": "paragonie/constant_time_encoding",
@@ -3702,7 +3715,7 @@
             "support": {
                 "source": "https://github.com/paypal/Checkout-PHP-SDK/tree/1.0.2"
             },
-            "abandoned": true,
+            "abandoned": "paypal/paypal-server-sdk",
             "time": "2021-09-21T20:57:38+00:00"
         },
         {
@@ -3893,23 +3906,23 @@
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "1.8.2",
+            "version": "1.10.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "153ae662783729388a584b4361f2545e4d841e3c"
+                "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
-                "reference": "153ae662783729388a584b4361f2545e4d841e3c",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+                "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
                 "shasum": ""
             },
             "require": {
                 "doctrine/deprecations": "^1.0",
                 "php": "^7.3 || ^8.0",
                 "phpdocumentor/reflection-common": "^2.0",
-                "phpstan/phpdoc-parser": "^1.13"
+                "phpstan/phpdoc-parser": "^1.18|^2.0"
             },
             "require-dev": {
                 "ext-tokenizer": "*",
@@ -3945,9 +3958,9 @@
             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
             "support": {
                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
             },
-            "time": "2024-02-23T11:10:43+00:00"
+            "time": "2024-11-09T15:12:26+00:00"
         },
         {
             "name": "phpoption/phpoption",
@@ -4026,16 +4039,16 @@
         },
         {
             "name": "phpseclib/phpseclib",
-            "version": "3.0.39",
+            "version": "3.0.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpseclib/phpseclib.git",
-                "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485"
+                "reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/211ebc399c6e73c225a018435fe5ae209d1d1485",
-                "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db92f1b1987b12b13f248fe76c3a52cadb67bb98",
+                "reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98",
                 "shasum": ""
             },
             "require": {
@@ -4116,7 +4129,7 @@
             ],
             "support": {
                 "issues": "https://github.com/phpseclib/phpseclib/issues",
-                "source": "https://github.com/phpseclib/phpseclib/tree/3.0.39"
+                "source": "https://github.com/phpseclib/phpseclib/tree/3.0.42"
             },
             "funding": [
                 {
@@ -4132,34 +4145,34 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-24T06:27:33+00:00"
+            "time": "2024-09-16T03:06:04+00:00"
         },
         {
             "name": "phpstan/phpdoc-parser",
-            "version": "1.29.1",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpdoc-parser.git",
-                "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4"
+                "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4",
-                "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299",
+                "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.2 || ^8.0"
+                "php": "^7.4 || ^8.0"
             },
             "require-dev": {
                 "doctrine/annotations": "^2.0",
-                "nikic/php-parser": "^4.15",
+                "nikic/php-parser": "^5.3.0",
                 "php-parallel-lint/php-parallel-lint": "^1.2",
                 "phpstan/extension-installer": "^1.0",
-                "phpstan/phpstan": "^1.5",
-                "phpstan/phpstan-phpunit": "^1.1",
-                "phpstan/phpstan-strict-rules": "^1.0",
-                "phpunit/phpunit": "^9.5",
+                "phpstan/phpstan": "^2.0",
+                "phpstan/phpstan-phpunit": "^2.0",
+                "phpstan/phpstan-strict-rules": "^2.0",
+                "phpunit/phpunit": "^9.6",
                 "symfony/process": "^5.2"
             },
             "type": "library",
@@ -4177,9 +4190,9 @@
             "description": "PHPDoc parser with support for nullable, intersection and generic types",
             "support": {
                 "issues": "https://github.com/phpstan/phpdoc-parser/issues",
-                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1"
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0"
             },
-            "time": "2024-05-31T08:52:43+00:00"
+            "time": "2024-10-13T11:29:49+00:00"
         },
         {
             "name": "predis/predis",
@@ -4604,16 +4617,16 @@
         },
         {
             "name": "psr/log",
-            "version": "3.0.0",
+            "version": "3.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/log.git",
-                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+                "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
-                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+                "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
                 "shasum": ""
             },
             "require": {
@@ -4648,9 +4661,9 @@
                 "psr-3"
             ],
             "support": {
-                "source": "https://github.com/php-fig/log/tree/3.0.0"
+                "source": "https://github.com/php-fig/log/tree/3.0.2"
             },
-            "time": "2021-07-14T16:46:02+00:00"
+            "time": "2024-09-11T13:17:53+00:00"
         },
         {
             "name": "psr/simple-cache",
@@ -5079,24 +5092,24 @@
         },
         {
             "name": "sabberworm/php-css-parser",
-            "version": "v8.6.0",
+            "version": "v8.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
-                "reference": "d2fb94a9641be84d79c7548c6d39bbebba6e9a70"
+                "reference": "f414ff953002a9b18e3a116f5e462c56f21237cf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d2fb94a9641be84d79c7548c6d39bbebba6e9a70",
-                "reference": "d2fb94a9641be84d79c7548c6d39bbebba6e9a70",
+                "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/f414ff953002a9b18e3a116f5e462c56f21237cf",
+                "reference": "f414ff953002a9b18e3a116f5e462c56f21237cf",
                 "shasum": ""
             },
             "require": {
                 "ext-iconv": "*",
-                "php": ">=5.6.20"
+                "php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^5.7.27"
+                "phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.40"
             },
             "suggest": {
                 "ext-mbstring": "for parsing UTF-8 CSS"
@@ -5138,9 +5151,9 @@
             ],
             "support": {
                 "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
-                "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.6.0"
+                "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.7.0"
             },
-            "time": "2024-07-01T07:33:21+00:00"
+            "time": "2024-10-27T17:38:32+00:00"
         },
         {
             "name": "socialiteproviders/discord",
@@ -5194,16 +5207,16 @@
         },
         {
             "name": "socialiteproviders/manager",
-            "version": "v4.6.0",
+            "version": "v4.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/SocialiteProviders/Manager.git",
-                "reference": "dea5190981c31b89e52259da9ab1ca4e2b258b21"
+                "reference": "ab0691b82cec77efd90154c78f1854903455c82f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/dea5190981c31b89e52259da9ab1ca4e2b258b21",
-                "reference": "dea5190981c31b89e52259da9ab1ca4e2b258b21",
+                "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/ab0691b82cec77efd90154c78f1854903455c82f",
+                "reference": "ab0691b82cec77efd90154c78f1854903455c82f",
                 "shasum": ""
             },
             "require": {
@@ -5264,20 +5277,20 @@
                 "issues": "https://github.com/socialiteproviders/manager/issues",
                 "source": "https://github.com/socialiteproviders/manager"
             },
-            "time": "2024-05-04T07:57:39+00:00"
+            "time": "2024-11-10T01:56:18+00:00"
         },
         {
             "name": "spatie/laravel-activitylog",
-            "version": "4.8.0",
+            "version": "4.9.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-activitylog.git",
-                "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff"
+                "reference": "e0fc28178515a5396f48e107ed697719189bbe02"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/eb6f37dd40af950ce10cf5280f0acfa3e08c3bff",
-                "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff",
+                "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/e0fc28178515a5396f48e107ed697719189bbe02",
+                "reference": "e0fc28178515a5396f48e107ed697719189bbe02",
                 "shasum": ""
             },
             "require": {
@@ -5343,7 +5356,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-activitylog/issues",
-                "source": "https://github.com/spatie/laravel-activitylog/tree/4.8.0"
+                "source": "https://github.com/spatie/laravel-activitylog/tree/4.9.0"
             },
             "funding": [
                 {
@@ -5355,20 +5368,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-03-08T22:28:17+00:00"
+            "time": "2024-10-18T13:38:47+00:00"
         },
         {
             "name": "spatie/laravel-package-tools",
-            "version": "1.16.4",
+            "version": "1.16.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-package-tools.git",
-                "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53"
+                "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
-                "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
+                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/c7413972cf22ffdff97b68499c22baa04eddb6a2",
+                "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2",
                 "shasum": ""
             },
             "require": {
@@ -5407,7 +5420,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-package-tools/issues",
-                "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4"
+                "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.5"
             },
             "funding": [
                 {
@@ -5415,20 +5428,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-03-20T07:29:11+00:00"
+            "time": "2024-08-27T18:56:10+00:00"
         },
         {
             "name": "spatie/laravel-permission",
-            "version": "6.9.0",
+            "version": "6.10.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-permission.git",
-                "reference": "fe973a58b44380d0e8620107259b7bda22f70408"
+                "reference": "8bb69d6d67387f7a00d93a2f5fab98860f06e704"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/fe973a58b44380d0e8620107259b7bda22f70408",
-                "reference": "fe973a58b44380d0e8620107259b7bda22f70408",
+                "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/8bb69d6d67387f7a00d93a2f5fab98860f06e704",
+                "reference": "8bb69d6d67387f7a00d93a2f5fab98860f06e704",
                 "shasum": ""
             },
             "require": {
@@ -5439,6 +5452,7 @@
                 "php": "^8.0"
             },
             "require-dev": {
+                "larastan/larastan": "^1.0|^2.0",
                 "laravel/passport": "^11.0|^12.0",
                 "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
                 "phpunit/phpunit": "^9.4|^10.1"
@@ -5489,7 +5503,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-permission/issues",
-                "source": "https://github.com/spatie/laravel-permission/tree/6.9.0"
+                "source": "https://github.com/spatie/laravel-permission/tree/6.10.1"
             },
             "funding": [
                 {
@@ -5497,20 +5511,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-06-22T23:04:52+00:00"
+            "time": "2024-11-08T18:45:41+00:00"
         },
         {
             "name": "spatie/laravel-query-builder",
-            "version": "6.0.1",
+            "version": "6.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-query-builder.git",
-                "reference": "69a6fd38c1515e42aec0df10d8adb8465f2f1f79"
+                "reference": "64f0453f4dea6a6fabf1ce4ddbb553e14da67bb6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/69a6fd38c1515e42aec0df10d8adb8465f2f1f79",
-                "reference": "69a6fd38c1515e42aec0df10d8adb8465f2f1f79",
+                "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/64f0453f4dea6a6fabf1ce4ddbb553e14da67bb6",
+                "reference": "64f0453f4dea6a6fabf1ce4ddbb553e14da67bb6",
                 "shasum": ""
             },
             "require": {
@@ -5571,20 +5585,20 @@
                     "type": "custom"
                 }
             ],
-            "time": "2024-05-21T12:12:10+00:00"
+            "time": "2024-10-03T11:10:10+00:00"
         },
         {
             "name": "spatie/laravel-settings",
-            "version": "3.3.2",
+            "version": "3.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-settings.git",
-                "reference": "395066797823856638a0a2feb243b396a94e22e5"
+                "reference": "2da8cb5b051678725476b299ef8e13b2e5015260"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/395066797823856638a0a2feb243b396a94e22e5",
-                "reference": "395066797823856638a0a2feb243b396a94e22e5",
+                "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/2da8cb5b051678725476b299ef8e13b2e5015260",
+                "reference": "2da8cb5b051678725476b299ef8e13b2e5015260",
                 "shasum": ""
             },
             "require": {
@@ -5646,7 +5660,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/laravel-settings/issues",
-                "source": "https://github.com/spatie/laravel-settings/tree/3.3.2"
+                "source": "https://github.com/spatie/laravel-settings/tree/3.4.0"
             },
             "funding": [
                 {
@@ -5658,7 +5672,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-03-22T07:50:04+00:00"
+            "time": "2024-09-20T13:48:17+00:00"
         },
         {
             "name": "spatie/laravel-validation-rules",
@@ -5856,16 +5870,16 @@
         },
         {
             "name": "symfony/clock",
-            "version": "v7.1.1",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/clock.git",
-                "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7"
+                "reference": "97bebc53548684c17ed696bc8af016880f0f098d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/clock/zipball/3dfc8b084853586de51dd1441c6242c76a28cbe7",
-                "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7",
+                "url": "https://api.github.com/repos/symfony/clock/zipball/97bebc53548684c17ed696bc8af016880f0f098d",
+                "reference": "97bebc53548684c17ed696bc8af016880f0f098d",
                 "shasum": ""
             },
             "require": {
@@ -5910,7 +5924,7 @@
                 "time"
             ],
             "support": {
-                "source": "https://github.com/symfony/clock/tree/v7.1.1"
+                "source": "https://github.com/symfony/clock/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -5926,20 +5940,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T14:57:53+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9"
+                "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
-                "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
+                "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5",
+                "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5",
                 "shasum": ""
             },
             "require": {
@@ -6003,7 +6017,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v7.1.3"
+                "source": "https://github.com/symfony/console/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -6019,20 +6033,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T12:41:01+00:00"
+            "time": "2024-11-06T14:23:19+00:00"
         },
         {
             "name": "symfony/css-selector",
-            "version": "v7.1.1",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4"
+                "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
-                "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/4aa4f6b3d6749c14d3aa815eef8226632e7bbc66",
+                "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66",
                 "shasum": ""
             },
             "require": {
@@ -6068,7 +6082,7 @@
             "description": "Converts CSS selectors to XPath expressions",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/css-selector/tree/v7.1.1"
+                "source": "https://github.com/symfony/css-selector/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -6084,7 +6098,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T14:57:53+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -6155,16 +6169,16 @@
         },
         {
             "name": "symfony/error-handler",
-            "version": "v7.1.3",
+            "version": "v7.1.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "432bb369952795c61ca1def65e078c4a80dad13c"
+                "reference": "010e44661f4c6babaf8c4862fe68c24a53903342"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c",
-                "reference": "432bb369952795c61ca1def65e078c4a80dad13c",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/010e44661f4c6babaf8c4862fe68c24a53903342",
+                "reference": "010e44661f4c6babaf8c4862fe68c24a53903342",
                 "shasum": ""
             },
             "require": {
@@ -6210,7 +6224,7 @@
             "description": "Provides tools to manage errors and ease debugging PHP code",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/error-handler/tree/v7.1.3"
+                "source": "https://github.com/symfony/error-handler/tree/v7.1.7"
             },
             "funding": [
                 {
@@ -6226,20 +6240,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T13:02:51+00:00"
+            "time": "2024-11-05T15:34:55+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v7.1.1",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7"
+                "reference": "87254c78dd50721cfd015b62277a8281c5589702"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
-                "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87254c78dd50721cfd015b62277a8281c5589702",
+                "reference": "87254c78dd50721cfd015b62277a8281c5589702",
                 "shasum": ""
             },
             "require": {
@@ -6290,7 +6304,7 @@
             "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -6306,7 +6320,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T14:57:53+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
@@ -6386,16 +6400,16 @@
         },
         {
             "name": "symfony/finder",
-            "version": "v7.1.3",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "717c6329886f32dc65e27461f80f2a465412fdca"
+                "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca",
-                "reference": "717c6329886f32dc65e27461f80f2a465412fdca",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8",
+                "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8",
                 "shasum": ""
             },
             "require": {
@@ -6430,7 +6444,7 @@
             "description": "Finds files and directories via an intuitive fluent interface",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/finder/tree/v7.1.3"
+                "source": "https://github.com/symfony/finder/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -6446,20 +6460,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-24T07:08:44+00:00"
+            "time": "2024-10-01T08:31:23+00:00"
         },
         {
             "name": "symfony/http-client",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231"
+                "reference": "c30d91a1deac0dc3ed5e604683cf2e1dfc635b8a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/b79858aa7a051ea791b0d50269a234a0b50cb231",
-                "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/c30d91a1deac0dc3ed5e604683cf2e1dfc635b8a",
+                "reference": "c30d91a1deac0dc3ed5e604683cf2e1dfc635b8a",
                 "shasum": ""
             },
             "require": {
@@ -6524,7 +6538,7 @@
                 "http"
             ],
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v7.1.3"
+                "source": "https://github.com/symfony/http-client/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -6540,7 +6554,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-17T06:10:24+00:00"
+            "time": "2024-11-13T13:40:27+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
@@ -6622,16 +6636,16 @@
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a"
+                "reference": "f4419ec69ccfc3f725a4de7c20e4e57626d10112"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
-                "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f4419ec69ccfc3f725a4de7c20e4e57626d10112",
+                "reference": "f4419ec69ccfc3f725a4de7c20e4e57626d10112",
                 "shasum": ""
             },
             "require": {
@@ -6641,12 +6655,12 @@
             },
             "conflict": {
                 "doctrine/dbal": "<3.6",
-                "symfony/cache": "<6.4"
+                "symfony/cache": "<6.4.12|>=7.0,<7.1.5"
             },
             "require-dev": {
                 "doctrine/dbal": "^3.6|^4",
                 "predis/predis": "^1.1|^2.0",
-                "symfony/cache": "^6.4|^7.0",
+                "symfony/cache": "^6.4.12|^7.1.5",
                 "symfony/dependency-injection": "^6.4|^7.0",
                 "symfony/expression-language": "^6.4|^7.0",
                 "symfony/http-kernel": "^6.4|^7.0",
@@ -6679,7 +6693,7 @@
             "description": "Defines an object-oriented layer for the HTTP specification",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-foundation/tree/v7.1.3"
+                "source": "https://github.com/symfony/http-foundation/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -6695,20 +6709,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T12:41:01+00:00"
+            "time": "2024-11-09T09:16:45+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186"
+                "reference": "33fef24e3dc79d6d30bf4936531f2f4bd2ca189e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186",
-                "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/33fef24e3dc79d6d30bf4936531f2f4bd2ca189e",
+                "reference": "33fef24e3dc79d6d30bf4936531f2f4bd2ca189e",
                 "shasum": ""
             },
             "require": {
@@ -6793,7 +6807,7 @@
             "description": "Provides a structured process for converting a Request into a Response",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-kernel/tree/v7.1.3"
+                "source": "https://github.com/symfony/http-kernel/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -6809,20 +6823,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T14:58:15+00:00"
+            "time": "2024-11-13T14:25:32+00:00"
         },
         {
             "name": "symfony/intl",
-            "version": "v7.1.1",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/intl.git",
-                "reference": "66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c"
+                "reference": "e56b243fc0afa5a12bd11dace4002ada5a7d99f8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/intl/zipball/66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c",
-                "reference": "66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c",
+                "url": "https://api.github.com/repos/symfony/intl/zipball/e56b243fc0afa5a12bd11dace4002ada5a7d99f8",
+                "reference": "e56b243fc0afa5a12bd11dace4002ada5a7d99f8",
                 "shasum": ""
             },
             "require": {
@@ -6879,7 +6893,7 @@
                 "localization"
             ],
             "support": {
-                "source": "https://github.com/symfony/intl/tree/v7.1.1"
+                "source": "https://github.com/symfony/intl/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -6895,20 +6909,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T14:57:53+00:00"
+            "time": "2024-11-08T15:46:42+00:00"
         },
         {
             "name": "symfony/mailer",
-            "version": "v7.1.2",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mailer.git",
-                "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee"
+                "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mailer/zipball/8fcff0af9043c8f8a8e229437cea363e282f9aee",
-                "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee",
+                "url": "https://api.github.com/repos/symfony/mailer/zipball/69c9948451fb3a6a4d47dc8261d1794734e76cdd",
+                "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd",
                 "shasum": ""
             },
             "require": {
@@ -6959,7 +6973,7 @@
             "description": "Helps sending emails",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/mailer/tree/v7.1.2"
+                "source": "https://github.com/symfony/mailer/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -6975,20 +6989,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-28T08:00:31+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "symfony/mailgun-mailer",
-            "version": "v7.1.3",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mailgun-mailer.git",
-                "reference": "dac02fe68e9306849703025511c56f10701696a8"
+                "reference": "b0117bf42b6dd8dfcfcab2a7e18508b594520b5a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8",
-                "reference": "dac02fe68e9306849703025511c56f10701696a8",
+                "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/b0117bf42b6dd8dfcfcab2a7e18508b594520b5a",
+                "reference": "b0117bf42b6dd8dfcfcab2a7e18508b594520b5a",
                 "shasum": ""
             },
             "require": {
@@ -7028,7 +7042,7 @@
             "description": "Symfony Mailgun Mailer Bridge",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3"
+                "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -7044,20 +7058,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-04T11:20:59+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "symfony/mime",
-            "version": "v7.1.2",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mime.git",
-                "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc"
+                "reference": "caa1e521edb2650b8470918dfe51708c237f0598"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
-                "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
+                "url": "https://api.github.com/repos/symfony/mime/zipball/caa1e521edb2650b8470918dfe51708c237f0598",
+                "reference": "caa1e521edb2650b8470918dfe51708c237f0598",
                 "shasum": ""
             },
             "require": {
@@ -7112,7 +7126,7 @@
                 "mime-type"
             ],
             "support": {
-                "source": "https://github.com/symfony/mime/tree/v7.1.2"
+                "source": "https://github.com/symfony/mime/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -7128,24 +7142,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-28T10:03:55+00:00"
+            "time": "2024-10-25T15:11:02+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "0424dff1c58f028c451efff2045f5d92410bd540"
+                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
-                "reference": "0424dff1c58f028c451efff2045f5d92410bd540",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
+                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "provide": {
                 "ext-ctype": "*"
@@ -7191,7 +7205,7 @@
                 "portable"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7207,24 +7221,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T15:07:36+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-intl-grapheme",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
-                "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a"
+                "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a",
-                "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
+                "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "suggest": {
                 "ext-intl": "For best performance"
@@ -7269,7 +7283,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7285,26 +7299,25 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T15:07:36+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-intl-idn",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-idn.git",
-                "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c"
+                "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
-                "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773",
+                "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1",
-                "symfony/polyfill-intl-normalizer": "^1.10",
-                "symfony/polyfill-php72": "^1.10"
+                "php": ">=7.2",
+                "symfony/polyfill-intl-normalizer": "^1.10"
             },
             "suggest": {
                 "ext-intl": "For best performance"
@@ -7353,7 +7366,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7369,24 +7382,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T15:07:36+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-intl-normalizer",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
-                "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
+                "reference": "3833d7255cc303546435cb650316bff708a1c75c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
-                "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
+                "reference": "3833d7255cc303546435cb650316bff708a1c75c",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "suggest": {
                 "ext-intl": "For best performance"
@@ -7434,7 +7447,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7450,24 +7463,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T15:07:36+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
+                "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
-                "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
+                "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "provide": {
                 "ext-mbstring": "*"
@@ -7514,7 +7527,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7530,97 +7543,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-19T12:30:46+00:00"
-        },
-        {
-            "name": "symfony/polyfill-php72",
-            "version": "v1.30.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-php72.git",
-                "reference": "10112722600777e02d2745716b70c5db4ca70442"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442",
-                "reference": "10112722600777e02d2745716b70c5db4ca70442",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=7.1"
-            },
-            "type": "library",
-            "extra": {
-                "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.30.0"
-            },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2024-06-19T12:30:46+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-php80",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php80.git",
-                "reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
+                "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
-                "reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
+                "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "type": "library",
             "extra": {
@@ -7667,7 +7607,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7683,24 +7623,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T15:07:36+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-php83",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php83.git",
-                "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9"
+                "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
-                "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
+                "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491",
+                "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "type": "library",
             "extra": {
@@ -7743,7 +7683,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7759,24 +7699,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-19T12:35:24+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/polyfill-uuid",
-            "version": "v1.30.0",
+            "version": "v1.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-uuid.git",
-                "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9"
+                "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2ba1f33797470debcda07fe9dce20a0003df18e9",
-                "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9",
+                "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2",
+                "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "provide": {
                 "ext-uuid": "*"
@@ -7822,7 +7762,7 @@
                 "uuid"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-uuid/tree/v1.30.0"
+                "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0"
             },
             "funding": [
                 {
@@ -7838,20 +7778,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T15:07:36+00:00"
+            "time": "2024-09-09T11:45:10+00:00"
         },
         {
             "name": "symfony/process",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca"
+                "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca",
-                "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca",
+                "url": "https://api.github.com/repos/symfony/process/zipball/42783370fda6e538771f7c7a36e9fa2ee3a84892",
+                "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892",
                 "shasum": ""
             },
             "require": {
@@ -7883,7 +7823,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v7.1.3"
+                "source": "https://github.com/symfony/process/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -7899,20 +7839,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T12:44:47+00:00"
+            "time": "2024-11-06T14:23:19+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v7.1.3",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0"
+                "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
-                "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/66a2c469f6c22d08603235c46a20007c0701ea0a",
+                "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a",
                 "shasum": ""
             },
             "require": {
@@ -7964,7 +7904,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v7.1.3"
+                "source": "https://github.com/symfony/routing/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -7980,7 +7920,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-17T06:10:24+00:00"
+            "time": "2024-10-01T08:31:23+00:00"
         },
         {
             "name": "symfony/service-contracts",
@@ -8067,16 +8007,16 @@
         },
         {
             "name": "symfony/string",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "ea272a882be7f20cad58d5d78c215001617b7f07"
+                "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07",
-                "reference": "ea272a882be7f20cad58d5d78c215001617b7f07",
+                "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281",
+                "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281",
                 "shasum": ""
             },
             "require": {
@@ -8134,7 +8074,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v7.1.3"
+                "source": "https://github.com/symfony/string/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -8150,20 +8090,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-22T10:25:37+00:00"
+            "time": "2024-11-13T13:31:21+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v7.1.3",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1"
+                "reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1",
-                "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/b9f72ab14efdb6b772f85041fa12f820dee8d55f",
+                "reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f",
                 "shasum": ""
             },
             "require": {
@@ -8228,7 +8168,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v7.1.3"
+                "source": "https://github.com/symfony/translation/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -8244,7 +8184,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T12:41:01+00:00"
+            "time": "2024-09-28T12:35:13+00:00"
         },
         {
             "name": "symfony/translation-contracts",
@@ -8326,16 +8266,16 @@
         },
         {
             "name": "symfony/uid",
-            "version": "v7.1.1",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/uid.git",
-                "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277"
+                "reference": "65befb3bb2d503bbffbd08c815aa38b472999917"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277",
-                "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277",
+                "url": "https://api.github.com/repos/symfony/uid/zipball/65befb3bb2d503bbffbd08c815aa38b472999917",
+                "reference": "65befb3bb2d503bbffbd08c815aa38b472999917",
                 "shasum": ""
             },
             "require": {
@@ -8380,7 +8320,7 @@
                 "uuid"
             ],
             "support": {
-                "source": "https://github.com/symfony/uid/tree/v7.1.1"
+                "source": "https://github.com/symfony/uid/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -8396,20 +8336,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T14:57:53+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v7.1.3",
+            "version": "v7.1.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f"
+                "reference": "7bb01a47b1b00428d32b5e7b4d3b2d1aa58d3db8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f",
-                "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7bb01a47b1b00428d32b5e7b4d3b2d1aa58d3db8",
+                "reference": "7bb01a47b1b00428d32b5e7b4d3b2d1aa58d3db8",
                 "shasum": ""
             },
             "require": {
@@ -8463,7 +8403,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v7.1.3"
+                "source": "https://github.com/symfony/var-dumper/tree/v7.1.8"
             },
             "funding": [
                 {
@@ -8479,7 +8419,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-26T12:41:01+00:00"
+            "time": "2024-11-08T15:46:42+00:00"
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
@@ -8752,16 +8692,16 @@
         },
         {
             "name": "yajra/laravel-datatables-oracle",
-            "version": "v11.1.3",
+            "version": "v11.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/yajra/laravel-datatables.git",
-                "reference": "78ecbc43025a24b92c307664c0cf395fea56c215"
+                "reference": "158f2e9cf76d500c707a0ebd6cd2079cd87b8d4a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/78ecbc43025a24b92c307664c0cf395fea56c215",
-                "reference": "78ecbc43025a24b92c307664c0cf395fea56c215",
+                "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/158f2e9cf76d500c707a0ebd6cd2079cd87b8d4a",
+                "reference": "158f2e9cf76d500c707a0ebd6cd2079cd87b8d4a",
                 "shasum": ""
             },
             "require": {
@@ -8829,7 +8769,7 @@
             ],
             "support": {
                 "issues": "https://github.com/yajra/laravel-datatables/issues",
-                "source": "https://github.com/yajra/laravel-datatables/tree/v11.1.3"
+                "source": "https://github.com/yajra/laravel-datatables/tree/v11.1.5"
             },
             "funding": [
                 {
@@ -8837,29 +8777,29 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-07-15T04:47:52+00:00"
+            "time": "2024-08-26T01:43:52+00:00"
         }
     ],
     "packages-dev": [
         {
             "name": "barryvdh/laravel-debugbar",
-            "version": "v3.13.5",
+            "version": "v3.14.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-debugbar.git",
-                "reference": "92d86be45ee54edff735e46856f64f14b6a8bb07"
+                "reference": "f484b8c9124de0b163da39958331098ffcd4a65e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/92d86be45ee54edff735e46856f64f14b6a8bb07",
-                "reference": "92d86be45ee54edff735e46856f64f14b6a8bb07",
+                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/f484b8c9124de0b163da39958331098ffcd4a65e",
+                "reference": "f484b8c9124de0b163da39958331098ffcd4a65e",
                 "shasum": ""
             },
             "require": {
                 "illuminate/routing": "^9|^10|^11",
                 "illuminate/session": "^9|^10|^11",
                 "illuminate/support": "^9|^10|^11",
-                "maximebf/debugbar": "~1.22.0",
+                "maximebf/debugbar": "~1.23.0",
                 "php": "^8.0",
                 "symfony/finder": "^6|^7"
             },
@@ -8872,7 +8812,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.13-dev"
+                    "dev-master": "3.14-dev"
                 },
                 "laravel": {
                     "providers": [
@@ -8911,7 +8851,7 @@
             ],
             "support": {
                 "issues": "https://github.com/barryvdh/laravel-debugbar/issues",
-                "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.13.5"
+                "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.14.7"
             },
             "funding": [
                 {
@@ -8923,20 +8863,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-04-12T11:20:37+00:00"
+            "time": "2024-11-14T09:12:35+00:00"
         },
         {
             "name": "fakerphp/faker",
-            "version": "v1.23.1",
+            "version": "v1.24.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FakerPHP/Faker.git",
-                "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b"
+                "reference": "a136842a532bac9ecd8a1c723852b09915d7db50"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b",
-                "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b",
+                "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/a136842a532bac9ecd8a1c723852b09915d7db50",
+                "reference": "a136842a532bac9ecd8a1c723852b09915d7db50",
                 "shasum": ""
             },
             "require": {
@@ -8984,32 +8924,32 @@
             ],
             "support": {
                 "issues": "https://github.com/FakerPHP/Faker/issues",
-                "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1"
+                "source": "https://github.com/FakerPHP/Faker/tree/v1.24.0"
             },
-            "time": "2024-01-02T13:46:09+00:00"
+            "time": "2024-11-07T15:11:20+00:00"
         },
         {
             "name": "filp/whoops",
-            "version": "2.15.4",
+            "version": "2.16.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filp/whoops.git",
-                "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
+                "reference": "befcdc0e5dce67252aa6322d82424be928214fa2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
-                "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
+                "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2",
+                "reference": "befcdc0e5dce67252aa6322d82424be928214fa2",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9 || ^7.0 || ^8.0",
+                "php": "^7.1 || ^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"
+                "mockery/mockery": "^1.0",
+                "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
+                "symfony/var-dumper": "^4.0 || ^5.0"
             },
             "suggest": {
                 "symfony/var-dumper": "Pretty print complex values better with var-dumper available",
@@ -9049,7 +8989,7 @@
             ],
             "support": {
                 "issues": "https://github.com/filp/whoops/issues",
-                "source": "https://github.com/filp/whoops/tree/2.15.4"
+                "source": "https://github.com/filp/whoops/tree/2.16.0"
             },
             "funding": [
                 {
@@ -9057,7 +8997,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-11-03T12:00:00+00:00"
+            "time": "2024-09-25T12:00:00+00:00"
         },
         {
             "name": "hamcrest/hamcrest-php",
@@ -9112,16 +9052,16 @@
         },
         {
             "name": "laravel/sail",
-            "version": "v1.31.0",
+            "version": "v1.38.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/sail.git",
-                "reference": "48d89608a3bb5be763c9bb87121d31e7da27c1cb"
+                "reference": "d17abae06661dd6c46d13627b1683a2924259145"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/sail/zipball/48d89608a3bb5be763c9bb87121d31e7da27c1cb",
-                "reference": "48d89608a3bb5be763c9bb87121d31e7da27c1cb",
+                "url": "https://api.github.com/repos/laravel/sail/zipball/d17abae06661dd6c46d13627b1683a2924259145",
+                "reference": "d17abae06661dd6c46d13627b1683a2924259145",
                 "shasum": ""
             },
             "require": {
@@ -9171,20 +9111,20 @@
                 "issues": "https://github.com/laravel/sail/issues",
                 "source": "https://github.com/laravel/sail"
             },
-            "time": "2024-07-22T14:36:50+00:00"
+            "time": "2024-11-11T20:16:51+00:00"
         },
         {
             "name": "maximebf/debugbar",
-            "version": "v1.22.3",
+            "version": "v1.23.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/maximebf/php-debugbar.git",
-                "reference": "7aa9a27a0b1158ed5ad4e7175e8d3aee9a818b96"
+                "reference": "687400043d77943ef95e8417cb44e1673ee57844"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/7aa9a27a0b1158ed5ad4e7175e8d3aee9a818b96",
-                "reference": "7aa9a27a0b1158ed5ad4e7175e8d3aee9a818b96",
+                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/687400043d77943ef95e8417cb44e1673ee57844",
+                "reference": "687400043d77943ef95e8417cb44e1673ee57844",
                 "shasum": ""
             },
             "require": {
@@ -9206,7 +9146,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.22-dev"
+                    "dev-master": "1.23-dev"
                 }
             },
             "autoload": {
@@ -9237,9 +9177,9 @@
             ],
             "support": {
                 "issues": "https://github.com/maximebf/php-debugbar/issues",
-                "source": "https://github.com/maximebf/php-debugbar/tree/v1.22.3"
+                "source": "https://github.com/maximebf/php-debugbar/tree/v1.23.3"
             },
-            "time": "2024-04-03T19:39:26+00:00"
+            "time": "2024-10-29T12:24:25+00:00"
         },
         {
             "name": "mockery/mockery",
@@ -9326,16 +9266,16 @@
         },
         {
             "name": "myclabs/deep-copy",
-            "version": "1.12.0",
+            "version": "1.12.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/myclabs/DeepCopy.git",
-                "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c"
+                "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
-                "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
+                "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
                 "shasum": ""
             },
             "require": {
@@ -9374,7 +9314,7 @@
             ],
             "support": {
                 "issues": "https://github.com/myclabs/DeepCopy/issues",
-                "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0"
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
             },
             "funding": [
                 {
@@ -9382,27 +9322,27 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-06-12T14:39:25+00:00"
+            "time": "2024-11-08T17:47:46+00:00"
         },
         {
             "name": "nunomaduro/collision",
-            "version": "v8.3.0",
+            "version": "v8.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nunomaduro/collision.git",
-                "reference": "b49f5b2891ce52726adfd162841c69d4e4c84229"
+                "reference": "f5c101b929c958e849a633283adff296ed5f38f5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nunomaduro/collision/zipball/b49f5b2891ce52726adfd162841c69d4e4c84229",
-                "reference": "b49f5b2891ce52726adfd162841c69d4e4c84229",
+                "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5",
+                "reference": "f5c101b929c958e849a633283adff296ed5f38f5",
                 "shasum": ""
             },
             "require": {
-                "filp/whoops": "^2.15.4",
-                "nunomaduro/termwind": "^2.0.1",
+                "filp/whoops": "^2.16.0",
+                "nunomaduro/termwind": "^2.1.0",
                 "php": "^8.2.0",
-                "symfony/console": "^7.1.2"
+                "symfony/console": "^7.1.5"
             },
             "conflict": {
                 "laravel/framework": "<11.0.0 || >=12.0.0",
@@ -9410,14 +9350,14 @@
             },
             "require-dev": {
                 "larastan/larastan": "^2.9.8",
-                "laravel/framework": "^11.16.0",
-                "laravel/pint": "^1.16.2",
-                "laravel/sail": "^1.30.2",
-                "laravel/sanctum": "^4.0.2",
-                "laravel/tinker": "^2.9.0",
-                "orchestra/testbench-core": "^9.2.1",
-                "pestphp/pest": "^2.34.9 || ^3.0.0",
-                "sebastian/environment": "^6.1.0 || ^7.0.0"
+                "laravel/framework": "^11.28.0",
+                "laravel/pint": "^1.18.1",
+                "laravel/sail": "^1.36.0",
+                "laravel/sanctum": "^4.0.3",
+                "laravel/tinker": "^2.10.0",
+                "orchestra/testbench-core": "^9.5.3",
+                "pestphp/pest": "^2.36.0 || ^3.4.0",
+                "sebastian/environment": "^6.1.0 || ^7.2.0"
             },
             "type": "library",
             "extra": {
@@ -9479,7 +9419,7 @@
                     "type": "patreon"
                 }
             ],
-            "time": "2024-07-16T22:41:01+00:00"
+            "time": "2024-10-15T16:06:32+00:00"
         },
         {
             "name": "phar-io/manifest",
@@ -9601,35 +9541,35 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "11.0.5",
+            "version": "11.0.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861"
+                "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/19b6365ab8b59a64438c0c3f4241feeb480c9861",
-                "reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca",
+                "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-libxml": "*",
                 "ext-xmlwriter": "*",
-                "nikic/php-parser": "^5.0",
+                "nikic/php-parser": "^5.3.1",
                 "php": ">=8.2",
-                "phpunit/php-file-iterator": "^5.0",
-                "phpunit/php-text-template": "^4.0",
-                "sebastian/code-unit-reverse-lookup": "^4.0",
-                "sebastian/complexity": "^4.0",
-                "sebastian/environment": "^7.0",
-                "sebastian/lines-of-code": "^3.0",
-                "sebastian/version": "^5.0",
-                "theseer/tokenizer": "^1.2.0"
+                "phpunit/php-file-iterator": "^5.1.0",
+                "phpunit/php-text-template": "^4.0.1",
+                "sebastian/code-unit-reverse-lookup": "^4.0.1",
+                "sebastian/complexity": "^4.0.1",
+                "sebastian/environment": "^7.2.0",
+                "sebastian/lines-of-code": "^3.0.1",
+                "sebastian/version": "^5.0.2",
+                "theseer/tokenizer": "^1.2.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "^11.0"
+                "phpunit/phpunit": "^11.4.1"
             },
             "suggest": {
                 "ext-pcov": "PHP extension that provides line coverage",
@@ -9638,7 +9578,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "11.0-dev"
+                    "dev-main": "11.0.x-dev"
                 }
             },
             "autoload": {
@@ -9667,7 +9607,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
                 "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.5"
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.7"
             },
             "funding": [
                 {
@@ -9675,20 +9615,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-07-03T05:05:37+00:00"
+            "time": "2024-10-09T06:21:38+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "5.0.1",
+            "version": "5.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26"
+                "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6ed896bf50bbbfe4d504a33ed5886278c78e4a26",
-                "reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6",
+                "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6",
                 "shasum": ""
             },
             "require": {
@@ -9728,7 +9668,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
                 "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
-                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.1"
+                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0"
             },
             "funding": [
                 {
@@ -9736,7 +9676,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-07-03T05:06:37+00:00"
+            "time": "2024-08-27T05:02:59+00:00"
         },
         {
             "name": "phpunit/php-invoker",
@@ -9924,16 +9864,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "11.2.8",
+            "version": "11.4.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39"
+                "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a7a29e8d3113806f18f99d670f580a30e8ffff39",
-                "reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e8e8ed1854de5d36c088ec1833beae40d2dedd76",
+                "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76",
                 "shasum": ""
             },
             "require": {
@@ -9947,21 +9887,21 @@
                 "phar-io/manifest": "^2.0.4",
                 "phar-io/version": "^3.2.1",
                 "php": ">=8.2",
-                "phpunit/php-code-coverage": "^11.0.5",
-                "phpunit/php-file-iterator": "^5.0.1",
+                "phpunit/php-code-coverage": "^11.0.7",
+                "phpunit/php-file-iterator": "^5.1.0",
                 "phpunit/php-invoker": "^5.0.1",
                 "phpunit/php-text-template": "^4.0.1",
                 "phpunit/php-timer": "^7.0.1",
                 "sebastian/cli-parser": "^3.0.2",
                 "sebastian/code-unit": "^3.0.1",
-                "sebastian/comparator": "^6.0.1",
+                "sebastian/comparator": "^6.1.1",
                 "sebastian/diff": "^6.0.2",
                 "sebastian/environment": "^7.2.0",
                 "sebastian/exporter": "^6.1.3",
                 "sebastian/global-state": "^7.0.2",
                 "sebastian/object-enumerator": "^6.0.1",
-                "sebastian/type": "^5.0.1",
-                "sebastian/version": "^5.0.1"
+                "sebastian/type": "^5.1.0",
+                "sebastian/version": "^5.0.2"
             },
             "suggest": {
                 "ext-soap": "To be able to generate mocks based on WSDL files"
@@ -9972,7 +9912,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "11.2-dev"
+                    "dev-main": "11.4-dev"
                 }
             },
             "autoload": {
@@ -10004,7 +9944,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.8"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.3"
             },
             "funding": [
                 {
@@ -10020,7 +9960,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-07-18T14:56:37+00:00"
+            "time": "2024-10-28T13:07:50+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -10194,16 +10134,16 @@
         },
         {
             "name": "sebastian/comparator",
-            "version": "6.0.1",
+            "version": "6.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/comparator.git",
-                "reference": "131942b86d3587291067a94f295498ab6ac79c20"
+                "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/131942b86d3587291067a94f295498ab6ac79c20",
-                "reference": "131942b86d3587291067a94f295498ab6ac79c20",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739",
+                "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739",
                 "shasum": ""
             },
             "require": {
@@ -10214,12 +10154,12 @@
                 "sebastian/exporter": "^6.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^11.0"
+                "phpunit/phpunit": "^11.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "6.0-dev"
+                    "dev-main": "6.2-dev"
                 }
             },
             "autoload": {
@@ -10259,7 +10199,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/comparator/issues",
                 "security": "https://github.com/sebastianbergmann/comparator/security/policy",
-                "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.1"
+                "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1"
             },
             "funding": [
                 {
@@ -10267,7 +10207,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-07-03T04:48:07+00:00"
+            "time": "2024-10-31T05:30:08+00:00"
         },
         {
             "name": "sebastian/complexity",
@@ -10836,28 +10776,28 @@
         },
         {
             "name": "sebastian/type",
-            "version": "5.0.1",
+            "version": "5.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/type.git",
-                "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa"
+                "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa",
-                "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac",
+                "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "^11.0"
+                "phpunit/phpunit": "^11.3"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "5.0-dev"
+                    "dev-main": "5.1-dev"
                 }
             },
             "autoload": {
@@ -10881,7 +10821,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/type/issues",
                 "security": "https://github.com/sebastianbergmann/type/security/policy",
-                "source": "https://github.com/sebastianbergmann/type/tree/5.0.1"
+                "source": "https://github.com/sebastianbergmann/type/tree/5.1.0"
             },
             "funding": [
                 {
@@ -10889,20 +10829,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-07-03T05:11:49+00:00"
+            "time": "2024-09-17T13:12:04+00:00"
         },
         {
             "name": "sebastian/version",
-            "version": "5.0.1",
+            "version": "5.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4"
+                "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/45c9debb7d039ce9b97de2f749c2cf5832a06ac4",
-                "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874",
+                "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874",
                 "shasum": ""
             },
             "require": {
@@ -10935,7 +10875,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/version/issues",
                 "security": "https://github.com/sebastianbergmann/version/security/policy",
-                "source": "https://github.com/sebastianbergmann/version/tree/5.0.1"
+                "source": "https://github.com/sebastianbergmann/version/tree/5.0.2"
             },
             "funding": [
                 {
@@ -10943,7 +10883,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-07-03T05:13:08+00:00"
+            "time": "2024-10-09T05:16:32+00:00"
         },
         {
             "name": "spatie/backtrace",
@@ -11084,16 +11024,16 @@
         },
         {
             "name": "spatie/flare-client-php",
-            "version": "1.7.0",
+            "version": "1.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/flare-client-php.git",
-                "reference": "097040ff51e660e0f6fc863684ac4b02c93fa234"
+                "reference": "180f8ca4c0d0d6fc51477bd8c53ce37ab5a96122"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/097040ff51e660e0f6fc863684ac4b02c93fa234",
-                "reference": "097040ff51e660e0f6fc863684ac4b02c93fa234",
+                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/180f8ca4c0d0d6fc51477bd8c53ce37ab5a96122",
+                "reference": "180f8ca4c0d0d6fc51477bd8c53ce37ab5a96122",
                 "shasum": ""
             },
             "require": {
@@ -11111,7 +11051,7 @@
                 "phpstan/extension-installer": "^1.1",
                 "phpstan/phpstan-deprecation-rules": "^1.0",
                 "phpstan/phpstan-phpunit": "^1.0",
-                "spatie/phpunit-snapshot-assertions": "^4.0|^5.0"
+                "spatie/pest-plugin-snapshots": "^1.0|^2.0"
             },
             "type": "library",
             "extra": {
@@ -11141,7 +11081,7 @@
             ],
             "support": {
                 "issues": "https://github.com/spatie/flare-client-php/issues",
-                "source": "https://github.com/spatie/flare-client-php/tree/1.7.0"
+                "source": "https://github.com/spatie/flare-client-php/tree/1.8.0"
             },
             "funding": [
                 {
@@ -11149,7 +11089,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-06-12T14:39:14+00:00"
+            "time": "2024-08-01T08:27:26+00:00"
         },
         {
             "name": "spatie/ignition",
@@ -11327,16 +11267,16 @@
         },
         {
             "name": "symfony/yaml",
-            "version": "v7.1.1",
+            "version": "v7.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "fa34c77015aa6720469db7003567b9f772492bf2"
+                "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2",
-                "reference": "fa34c77015aa6720469db7003567b9f772492bf2",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/3ced3f29e4f0d6bce2170ff26719f1fe9aacc671",
+                "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671",
                 "shasum": ""
             },
             "require": {
@@ -11378,7 +11318,7 @@
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v7.1.1"
+                "source": "https://github.com/symfony/yaml/tree/v7.1.6"
             },
             "funding": [
                 {
@@ -11394,7 +11334,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-05-31T14:57:53+00:00"
+            "time": "2024-09-25T14:20:29+00:00"
         },
         {
             "name": "theseer/tokenizer",
@@ -11462,5 +11402,5 @@
     "platform-overrides": {
         "php": "8.2"
     },
-    "plugin-api-version": "2.6.0"
+    "plugin-api-version": "2.3.0"
 }

From 06113b30966e97f881003eb7ce05db5efa0823fd Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 19 Nov 2024 09:12:21 +0100
Subject: [PATCH 510/514] Update verification Email

---
 app/Models/User.php | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/app/Models/User.php b/app/Models/User.php
index 9577fa808..350e73bd0 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -14,6 +14,7 @@
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
 use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\RateLimiter;
 use Spatie\Activitylog\LogOptions;
 use Spatie\Activitylog\Traits\CausesActivity;
@@ -189,18 +190,23 @@ public function discordUser()
 
     public function sendEmailVerificationNotification()
     {
-        // Rate limit the email verification notification to 1 attempt per 30 minutes
-        $executed = RateLimiter::attempt(
-            key: 'verify-mail'. $this->id,
-            maxAttempts: 1,
-            callback: function() {
-                $this->notify(new QueuedVerifyEmail);
-            },
-            decaySeconds: 1800
-        );
-
-        if (! $executed) {
-            return response()->json(['message' => 'Too many requests, try again in: ' . RateLimiter::availableIn('verify-mail:'. $this->id) . ' seconds'], 429);
+        try {
+            // Rate limit the email verification notification to 5 attempt per 30 minutes
+            $executed = RateLimiter::attempt(
+                key: 'verify-mail' . $this->id,
+                maxAttempts: 5,
+                callback: function () {
+                    $this->notify(new QueuedVerifyEmail);
+                },
+                decaySeconds: 1800
+            );
+
+            if (!$executed) {
+                return redirect()->back()->with('error', 'Too many requests. Try again in ' . RateLimiter::availableIn('verify-mail:' . $this->id) . ' seconds.');
+            }
+        }catch (\Exception $exception){
+            Log::error($exception->getMessage());
+            return redirect()->back()->with('error', __("Something went wrong. Please try again later!"));
         }
     }
 

From a6055e051772082c22f4a98d0255fdd50d3b6880 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Tue, 19 Nov 2024 09:19:13 +0100
Subject: [PATCH 511/514] [Fix]} Update Serverdestroy Usercheck

---
 app/Http/Controllers/ServerController.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index 7f5919b4f..d7b1c833c 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -285,6 +285,9 @@ private function serverCreationFailed(Response $response, Server $server)
     /** Remove the specified resource from storage. */
     public function destroy(Server $server, DiscordSettings $discord_settings)
     {
+        if ($server->user_id != Auth::user()->id) {
+            return back()->with('error', __('This is not your Server!'));
+        }
         try {
             // Remove role from discord
             try {

From d8bff263ef4961ef8d80d3bdaf62b1df93c3b266 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 21 Nov 2024 18:23:11 +0100
Subject: [PATCH 512/514] [Fix] Free server Suspend

---
 app/Console/Commands/ChargeCreditsCommand.php | 101 ------------------
 app/Console/Commands/ChargeServers.php        |   2 +-
 2 files changed, 1 insertion(+), 102 deletions(-)
 delete mode 100644 app/Console/Commands/ChargeCreditsCommand.php

diff --git a/app/Console/Commands/ChargeCreditsCommand.php b/app/Console/Commands/ChargeCreditsCommand.php
deleted file mode 100644
index 145943c7e..000000000
--- a/app/Console/Commands/ChargeCreditsCommand.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-
-namespace App\Console\Commands;
-
-use App\Models\Product;
-use App\Models\Server;
-use App\Models\User;
-use App\Notifications\ServersSuspendedNotification;
-use Illuminate\Console\Command;
-
-class ChargeCreditsCommand extends Command
-{
-    /**
-     * The name and signature of the console command.
-     *
-     * @var string
-     */
-    protected $signature = 'credits:charge';
-
-    /**
-     * The console command description.
-     *
-     * @var string
-     */
-    protected $description = 'Charge all users with active servers';
-
-    /**
-     * A list of users that have to be notified
-     *
-     * @var array
-     */
-    protected $usersToNotify = [];
-
-    /**
-     * Create a new command instance.
-     *
-     * @return void
-     */
-    public function __construct()
-    {
-        parent::__construct();
-    }
-
-    /**
-     * Execute the console command.
-     *
-     * @return string
-     */
-    public function handle()
-    {
-        Server::whereNull('suspended')->chunk(10, function ($servers) {
-            /** @var Server $server */
-            foreach ($servers as $server) {
-                /** @var Product $product */
-                $product = $server->product;
-                /** @var User $user */
-                $user = $server->user;
-
-                //charge credits / suspend server
-                if ($user->credits >= $product->getHourlyPrice()) {
-                    $this->line("<fg=blue>{$user->name}</> Current credits: <fg=green>{$user->credits}</> Credits to be removed: <fg=red>{$product->getHourlyPrice()}</>");
-                    $user->decrement('credits', $product->getHourlyPrice());
-                } else {
-                    try {
-                        //suspend server
-                        $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
-                        $server->suspend();
-
-                        //add user to notify list
-                        if (!in_array($user, $this->usersToNotify)) {
-                            array_push($this->usersToNotify, $user);
-                        }
-                    } catch (\Exception $exception) {
-                        $this->error($exception->getMessage());
-                    }
-                }
-            }
-        });
-
-        return $this->notifyUsers();
-    }
-
-    /**
-     * @return bool
-     */
-    public function notifyUsers()
-    {
-        if (!empty($this->usersToNotify)) {
-            /** @var User $user */
-            foreach ($this->usersToNotify as $user) {
-                $this->line("<fg=yellow>Notified user:</> <fg=blue>{$user->name}</>");
-                $user->notify(new ServersSuspendedNotification());
-            }
-        }
-
-        //reset array
-        $this->usersToNotify = [];
-
-        return true;
-    }
-}
diff --git a/app/Console/Commands/ChargeServers.php b/app/Console/Commands/ChargeServers.php
index 8c7b9d4de..f623b8ec2 100644
--- a/app/Console/Commands/ChargeServers.php
+++ b/app/Console/Commands/ChargeServers.php
@@ -91,7 +91,7 @@ public function handle()
                 }
 
                 // check if the server is canceled or if user has enough credits to charge the server or
-                if ($server->canceled || $user->credits <= $product->price) {
+                if ($server->canceled || ($user->credits <= $product->price && $product->price != 0 )) {
                     try {
                         // suspend server
                         $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");

From 6e746fad072972c9a80a6b0d2abd987f8e9fb171 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 21 Nov 2024 18:31:55 +0100
Subject: [PATCH 513/514] Update Kernel.php

---
 app/Console/Kernel.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index a1bd37d22..a271e673d 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -14,7 +14,6 @@ class Kernel extends ConsoleKernel
      * @var array
      */
     protected $commands = [
-        Commands\ChargeCreditsCommand::class,
         Commands\ChargeServers::class,
         Commands\DeleteExpiredCoupons::class,
     ];

From 2d2e1e0cc7a457365da4e0683c1459918f9b5625 Mon Sep 17 00:00:00 2001
From: 1day2die <ownerdennis8@gmail.com>
Date: Thu, 21 Nov 2024 18:56:28 +0100
Subject: [PATCH 514/514] [TempFix] Discord ID on USertable

---
 app/Http/Controllers/Admin/UserController.php    | 3 +++
 themes/default/views/admin/users/index.blade.php | 6 +++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 3cc7709f9..cfa02b256 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -398,9 +398,12 @@ public function dataTable(Request $request)
             ->addColumn('verified', function (User $user) {
                 return $user->getVerifiedStatus();
             })
+            /*  This broke the ability to search the table. Have to revisit later
+
             ->addColumn('discordId', function (User $user) {
                 return $user->discordUser ? $user->discordUser->id : '';
             })
+            */
             ->addColumn('actions', function (User $user) {
                 $suspendColor = $user->isSuspended() ? 'btn-success' : 'btn-warning';
                 $suspendIcon = $user->isSuspended() ? 'fa-play-circle' : 'fa-pause-circle';
diff --git a/themes/default/views/admin/users/index.blade.php b/themes/default/views/admin/users/index.blade.php
index 69d9d3dc8..9accacb9a 100644
--- a/themes/default/views/admin/users/index.blade.php
+++ b/themes/default/views/admin/users/index.blade.php
@@ -84,11 +84,15 @@ function submitResult() {
                 order: [
                     [11, "desc"]
                 ],
-                columns: [{
+                columns: [
+                  /* This broke the ability to search the table. Have to revisit later
+                  {
                         data: 'discordId',
                         visible: false,
                         name: 'discordUser.id'
                     },
+                    */
+
                     {
                         data: 'pterodactyl_id',
                         visible: false