44 Commits

Author SHA1 Message Date
Ninluc cd3491c5a8 Install reverb for broadcasting
Push image to registry / build-image (push) Successful in 3m56s
2025-02-26 18:52:12 +01:00
Ninluc 9e55c98d47 Added TODO list 2025-02-26 18:28:42 +01:00
Ninluc 7abfea14e6 Reschedule 24hr after getting dailyFree
Push image to registry / build-image (push) Successful in 3m53s
2025-02-26 18:25:20 +01:00
Ninluc b177b27390 FIx ot reschedule in one hour but in one minute
Push image to registry / build-image (push) Successful in 6m42s
2025-02-26 07:19:58 +01:00
Ninluc 8d814c7658 Try to fix reschedules in seconds
Push image to registry / build-image (push) Has been cancelled
2025-02-26 07:18:32 +01:00
Ninluc 56ec14f1da Move file 2025-02-24 18:58:22 +01:00
Ninluc c7ad5810a7 fix jobModel again
Push image to registry / build-image (push) Successful in 4m31s
2025-02-22 08:53:54 +01:00
Ninluc 5b939f7d34 Fix jobModel interfering
Push image to registry / build-image (push) Failing after 53s
2025-02-22 08:46:47 +01:00
Ninluc 540c41357e cron with daemon
Push image to registry / build-image (push) Failing after 1m0s
2025-02-22 08:35:03 +01:00
Ninluc 9f7603ea18 Only start the job if active 2025-02-22 08:34:47 +01:00
Ninluc e44ea5a3b2 Fix queue wotker
Push image to registry / build-image (push) Successful in 3m46s
2025-02-21 18:34:19 +01:00
Ninluc a4d52e3f88 Logging and only one job in the queue 2025-02-21 18:34:03 +01:00
Ninluc 750bcf13b4 Fix supervisor
Push image to registry / build-image (push) Successful in 3m46s
2025-02-20 20:22:04 +01:00
Ninluc 7a03225a21 Fix supervisor
Push image to registry / build-image (push) Successful in 6m46s
2025-02-20 20:00:25 +01:00
Ninluc 51eafce03a Changed queue worker
Push image to registry / build-image (push) Failing after 7m39s
2025-02-20 19:22:38 +01:00
Ninluc f1f32c44b5 Fix daily free screenshot
Push image to registry / build-image (push) Successful in 3m53s
2025-02-19 18:50:34 +01:00
Ninluc 7b51e29060 Don't filter anything
Push image to registry / build-image (push) Successful in 3m43s
2025-02-19 17:47:18 +01:00
Ninluc 9ca6ba3018 Telescope Prune
Push image to registry / build-image (push) Successful in 3m46s
2025-02-19 17:40:57 +01:00
Ninluc a05e5e224d Fix telescope not availible on prod
Push image to registry / build-image (push) Has been cancelled
2025-02-19 17:38:42 +01:00
Ninluc 61e55f960e Fix Job
Push image to registry / build-image (push) Successful in 4m41s
2025-02-18 18:48:48 +01:00
Ninluc 313c0a6a9a Fix queue 2025-02-18 18:48:32 +01:00
Ninluc 2fdd34bc35 Added failed_jobs table 2025-02-18 18:37:05 +01:00
Ninluc e1d7a19f6c Added Telescope 2025-02-18 18:36:55 +01:00
Ninluc 77968e7619 Fix page name 2025-02-16 10:24:47 +01:00
Ninluc e535a85058 Fix favicon
Push image to registry / build-image (push) Successful in 3m47s
2025-02-16 10:21:12 +01:00
Ninluc b40764c4ad Fix crontab
Push image to registry / build-image (push) Successful in 3m47s
2025-02-16 10:04:41 +01:00
Ninluc e6776df487 Fix login button
Push image to registry / build-image (push) Successful in 6m47s
2025-02-15 13:34:37 +01:00
Ninluc 7151c6adff Fix ?
Push image to registry / build-image (push) Successful in 2m4s
2025-02-08 17:59:01 +01:00
Ninluc 22283b3b10 Fix clicking signin with steam
Push image to registry / build-image (push) Successful in 2m7s
2025-02-08 17:54:44 +01:00
Ninluc fa674c3381 Update sign in with steam button
Push image to registry / build-image (push) Successful in 2m50s
2025-02-08 17:44:55 +01:00
Ninluc 8cb0e2f88a Clening up
Push image to registry / build-image (push) Successful in 3m55s
2025-02-08 11:26:10 +01:00
Ninluc 1c3c4b1257 Cache when running
Push image to registry / build-image (push) Successful in 3m46s
2025-02-08 11:16:40 +01:00
Ninluc 77aa2e85c5 idk
Push image to registry / build-image (push) Successful in 35s
2025-02-08 11:13:42 +01:00
Ninluc 9647676c27 Fix debug
Push image to registry / build-image (push) Successful in 3m53s
2025-02-08 11:00:30 +01:00
Ninluc 71ad103a1f debug
Push image to registry / build-image (push) Successful in 3m52s
2025-02-08 10:46:20 +01:00
Ninluc 990fcb9a0d Added rescheduling
Push image to registry / build-image (push) Successful in 6m12s
2025-02-08 10:36:19 +01:00
Ninluc e54d65ef8b Refix debug 2025-02-08 10:36:12 +01:00
Ninluc d4ea33e181 Fix debug
Push image to registry / build-image (push) Failing after 1m1s
2025-02-08 10:31:51 +01:00
Ninluc ec869bffe9 Debug
Push image to registry / build-image (push) Failing after 52s
2025-02-08 10:23:34 +01:00
Ninluc 7f4ba8a8c9 Wait for CASES text to be able to know the page loaded
Push image to registry / build-image (push) Successful in 3m44s
2025-02-08 10:13:02 +01:00
Ninluc 1c71b88d15 Force https only if APP_URL statrs with https
Push image to registry / build-image (push) Has been cancelled
2025-02-08 10:11:14 +01:00
Ninluc 2142ea9cc2 Force https
Push image to registry / build-image (push) Successful in 3m50s
2025-02-08 10:04:40 +01:00
Ninluc 99f866fbef Force it
Push image to registry / build-image (push) Successful in 3m45s
2025-02-07 16:20:05 +01:00
Ninluc 2be60c003b Revert vite config 2025-02-07 16:18:05 +01:00
36 changed files with 2060 additions and 36 deletions
+13
View File
@@ -68,3 +68,16 @@ VITE_APP_URL="${APP_URL}"
DUSK_DRIVER_URL="http://undetected-chromedriver:4444" DUSK_DRIVER_URL="http://undetected-chromedriver:4444"
DUSK_START_MAXIMIZED=true DUSK_START_MAXIMIZED=true
# Reverb (broadcasting)
REVERB_APP_ID=943562
REVERB_APP_KEY=jzysqfijn8wdgugrilbb
REVERB_APP_SECRET=gyotb3asui2zbrltd3ob
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
+13
View File
@@ -68,3 +68,16 @@ VITE_APP_URL="${APP_URL}"
DUSK_DRIVER_URL="http://127.0.0.1:4444" DUSK_DRIVER_URL="http://127.0.0.1:4444"
DUSK_START_MAXIMIZED=true DUSK_START_MAXIMIZED=true
# Reverb (broadcasting)
REVERB_APP_ID=943562
REVERB_APP_KEY=jzysqfijn8wdgugrilbb
REVERB_APP_SECRET=gyotb3asui2zbrltd3ob
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
+14 -8
View File
@@ -38,6 +38,8 @@ RUN mkdir -p public/build/ && npm i && npm run build
# RUN # RUN
FROM php:8.2-alpine AS final FROM php:8.2-alpine AS final
ARG APP_ENV_FILE=.env.docker
# Install system dependencies # Install system dependencies
RUN apk update && apk add --no-cache \ RUN apk update && apk add --no-cache \
git \ git \
@@ -50,7 +52,9 @@ RUN apk update && apk add --no-cache \
supervisor \ supervisor \
nginx \ nginx \
openssl \ openssl \
linux-headers linux-headers \
supervisor \
&& rm -rf /tmp/* /var/cache/apk/*
RUN docker-php-ext-configure zip && docker-php-ext-install zip RUN docker-php-ext-configure zip && docker-php-ext-install zip
RUN docker-php-ext-install gd pdo pdo_mysql zip RUN docker-php-ext-install gd pdo pdo_mysql zip
@@ -59,11 +63,12 @@ RUN docker-php-ext-install gd pdo pdo_mysql zip
# Get latest Composer # Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www ARG wd=/var/www
WORKDIR ${wd}
COPY . . COPY . .
COPY --from=build-vue /usr/app/public/build ./public/build COPY --from=build-vue /usr/app/public/build ./public/build
RUN mv .env.docker .env RUN mv ${APP_ENV_FILE} .env
# DUSK # DUSK
# RUN php artisan dusk:install && php artisan dusk:chrome-driver && mv ./undetectedChromedriver/chromedriver-linux ./vendor/laravel/dusk/bin/chromedriver-linux # RUN php artisan dusk:install && php artisan dusk:chrome-driver && mv ./undetectedChromedriver/chromedriver-linux ./vendor/laravel/dusk/bin/chromedriver-linux
@@ -72,16 +77,17 @@ RUN mv .env.docker .env
RUN composer install --no-interaction --prefer-dist RUN composer install --no-interaction --prefer-dist
# Supervisor
COPY ./docker/datbrowserQueueWorker.conf /etc/supervisor/conf.d/datbrowserQueueWorker.conf
COPY ./docker/supervisord.conf /etc/supervisord.conf
# RUN supervisorctl reread && supervisorctl update
# CRON # CRON
RUN echo "* * * * * cd /usr/app && php artisan schedule:run >> /dev/null 2>&1" > /etc/crontabs/root RUN echo "* * * * * cd ${wd} && php artisan schedule:run >> /dev/null 2>&1" > /etc/crontabs/root
# Link the storage directory to the public directory. # Link the storage directory to the public directory.
RUN php artisan storage:link RUN php artisan storage:link
# Laravel optimization commands
# RUN php artisan cache:clear
RUN php artisan config:cache && php artisan route:cache
RUN chmod +x ./dockerEntryPoint.sh RUN chmod +x ./dockerEntryPoint.sh
EXPOSE 80 EXPOSE 80
+10 -2
View File
@@ -2,6 +2,7 @@
namespace App\Browser; namespace App\Browser;
use App\Models\Job;
use App\Models\JobArtifact; use App\Models\JobArtifact;
use App\Models\JobRun; use App\Models\JobRun;
use Closure; use Closure;
@@ -28,6 +29,8 @@ abstract class BrowserJob implements ShouldQueue
public int $jobId; public int $jobId;
public $timeout = 500;
public function __construct(int $jobId) public function __construct(int $jobId)
{ {
$this->jobId = $jobId; $this->jobId = $jobId;
@@ -214,7 +217,13 @@ abstract class BrowserJob implements ShouldQueue
*/ */
public function handle(): void public function handle(): void
{ {
$this->execute(); if (Job::find($this->jobId)->is_active) {
$this->execute();
}
}
public function reschedule($minutes) {
$this::dispatch()->delay(now()->addMinutes($minutes));
} }
@@ -268,7 +277,6 @@ abstract class BrowserJob implements ShouldQueue
protected function findElementContainingElementWithText(Browser $browser, string $elementXpath, string $text, bool $ignoreCase = true): RemoteWebElement|null { protected function findElementContainingElementWithText(Browser $browser, string $elementXpath, string $text, bool $ignoreCase = true): RemoteWebElement|null {
try { try {
if ($ignoreCase) { if ($ignoreCase) {
dump("{$elementXpath}[.//*[{$this->xpathContainsIgnoreCase($text)}]]");
return $browser->driver->findElement(WebDriverBy::xpath("{$elementXpath}[.//*[{$this->xpathContainsIgnoreCase($text)}]]")); return $browser->driver->findElement(WebDriverBy::xpath("{$elementXpath}[.//*[{$this->xpathContainsIgnoreCase($text)}]]"));
} else { } else {
return $browser->driver->findElement(WebDriverBy::xpath("{$elementXpath}[.//*[contains(text(), \"{$text}\")]]")); return $browser->driver->findElement(WebDriverBy::xpath("{$elementXpath}[.//*[contains(text(), \"{$text}\")]]"));
+6 -2
View File
@@ -37,7 +37,11 @@ class MainNav extends BaseComponent
} }
public function goToHome(Browser $browser) { public function goToHome(Browser $browser) {
$browser->scrollIntoView('@logo'); try {
$browser->click('@logo'); $browser->scrollIntoView('@logo');
$browser->click('@logo');
} catch (\Exception $e) {
$browser->visit('https://hellcase.com/');
}
} }
} }
+54 -17
View File
@@ -4,33 +4,35 @@ namespace App\Browser\Jobs\Hellcase;
use App\Browser\BrowserJob; use App\Browser\BrowserJob;
use App\Browser\Components\Hellcase\MainNav; use App\Browser\Components\Hellcase\MainNav;
use App\Models\JobArtifact;
use App\Browser\JobArtifacts\JobRunArtifact;
use App\Browser\Jobs\Hellcase\HellcaseLoginQrCode; use App\Browser\Jobs\Hellcase\HellcaseLoginQrCode;
use App\Models\JobArtifact;
use App\Models\JobRun; use App\Models\JobRun;
use App\Notification\NotificationBody\Hellcase\HellcaseNotificationDailyFreeBody; use App\Notification\NotificationBody\Hellcase\HellcaseNotificationDailyFreeBody;
use App\Notification\NotificationBody\Hellcase\HellcaseNotificationLoginBody; use App\Notification\NotificationBody\Hellcase\HellcaseNotificationLoginBody;
use App\Notification\Notifications\Hellcase\HellcaseNotificationDailyFree; use App\Notification\Notifications\Hellcase\HellcaseNotificationDailyFree;
use App\Notification\Notifications\Hellcase\HellcaseNotificationLogin; use App\Notification\Notifications\Hellcase\HellcaseNotificationLogin;
use App\Notification\Providers\AllNotification; use App\Notification\Providers\AllNotification;
use Dom\XPath;
use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\WebDriverBy;
use Illuminate\Support\Facades\Schedule; use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
use Illuminate\Support\Facades\Log;
use Laravel\Dusk\Browser; use Laravel\Dusk\Browser;
class HellcaseJob extends BrowserJob class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
{ {
private const STEAM_LOGIN_THRESHOLD = 5 * 60; // 5 minutes private const STEAM_LOGIN_THRESHOLD = 5 * 60; // 5 minutes
private const APPROXIMATIVE_RUNNING_MINUTES = 2;
private JobRun $jobRun; private JobRun $jobRun;
public function __construct() public function __construct()
{ {
Log::info("Constructing HellcaseJob");
parent::__construct(2); parent::__construct(2);
} }
public function run(Browser $browser): ?JobRun public function run(Browser $browser): ?JobRun
{ {
Log::info("Running HellcaseJob");
$this->jobRun = new JobRun([ $this->jobRun = new JobRun([
"job_id" => $this->jobId, "job_id" => $this->jobId,
"success" => false, "success" => false,
@@ -48,6 +50,8 @@ class HellcaseJob extends BrowserJob
$this->jobRun->success = true; $this->jobRun->success = true;
$this->jobRun->save(); $this->jobRun->save();
Log::info("HellcaseJob run ended");
return $this->jobRun; return $this->jobRun;
} }
@@ -58,7 +62,7 @@ class HellcaseJob extends BrowserJob
{ {
try { try {
$browser->visit('https://hellcase.com'); $browser->visit('https://hellcase.com');
$browser->waitForText("REFILL", 30, true); $browser->waitForText("CASES", 30, true);
$this->removePopups($browser); $this->removePopups($browser);
sleep(2); sleep(2);
$this->signin($browser); $this->signin($browser);
@@ -84,8 +88,10 @@ class HellcaseJob extends BrowserJob
return; return;
} }
sleep(5);
$browser->waitForText("Sign in with Steam", 30, true);
sleep(3); sleep(3);
$browser->clickAtXPath('//button[.//span[contains(text(), "Sign in through Steam")]]'); $browser->driver->findElement(WebDriverBy::xpath('//button[@class = "_base_1uydq_1 _accent-1_1uydq_105 _m_1uydq_52 _full_1uydq_94 _primary_1uydq_100"]'))->click();
sleep(5); sleep(5);
// QR CODE SCANNING // QR CODE SCANNING
@@ -123,10 +129,10 @@ class HellcaseJob extends BrowserJob
} }
if ($isBackOnHellcase) { if ($isBackOnHellcase) {
// Click a button tjat says "sign in" // Click a button that says "sign in"
$browser->waitForText("By signing into steam.loginhell.com through Steam", 30, true); $browser->waitForText("By signing into steam.loginhell.com through Steam", 30, true);
$browser->clickAtXPath('//input[@id = "imageLogin"]'); $browser->clickAtXPath('//input[@id = "imageLogin"]');
sleep(30); sleep(20);
} }
} }
@@ -158,6 +164,21 @@ class HellcaseJob extends BrowserJob
{ {
$joinButton = $browser->driver->findElement(WebDriverBy::xpath('//button[span[contains(text(), "Join for free")]]')); $joinButton = $browser->driver->findElement(WebDriverBy::xpath('//button[span[contains(text(), "Join for free")]]'));
$joinButton->click(); $joinButton->click();
sleep(3);
// JobRun
// Get the elements text containing class starting with giveaway-entity-prize__
$prizeElement = $browser->driver->findElements(WebDriverBy::xpath('//div[starts-with(@class, "giveaway-entity-prize__")]'));
// Join their text
$prize = "";
foreach ($prizeElement as $element) {
$prize .= $element->getText() . "\n";
}
$this->jobRun->addArtifact(new JobArtifact([
"name" => "Rejoint le concours",
"content" => "Pour tenter de gagner le prix : \n" . $prize
]));
} }
private function getDailyFree(Browser $browser) private function getDailyFree(Browser $browser)
@@ -174,25 +195,37 @@ class HellcaseJob extends BrowserJob
$availibleInButton = $browser->driver->findElement(WebDriverBy::xpath('//button[contains(@class, "daily-free-banner__button")]')); $availibleInButton = $browser->driver->findElement(WebDriverBy::xpath('//button[contains(@class, "daily-free-banner__button")]'));
if ($availibleInButton->getAttribute("disabled") == "true") { if ($availibleInButton->getAttribute("disabled") == "true") {
$hours = $availibleInButton->getText(); $hours = $availibleInButton->getText();
// If the text is like "in 26 sec." we need to put one minute
if (str_contains($hours, "sec")) {
$this->reschedule(1);
return;
}
$hours = explode(" ", $hours); $hours = explode(" ", $hours);
$minutes = $hours[4]; $minutes = $hours[4];
$hours = $hours[2]; $hours = $hours[2];
// $this->reschedule($hours);
$this->jobRun->addArtifact(new JobArtifact([ $this->jobRun->addArtifact(new JobArtifact([
"name" => "Cadeau gratuit pas encore disponible", "name" => "Cadeau gratuit pas encore disponible",
"content" => "Le cadeau gratuit journalier sera disponible dans {$hours} heures et {$minutes} minutes.\nDatboi se fera un plaisir d'aller le chercher pour vous." "content" => "Le cadeau gratuit journalier sera disponible dans {$hours} heures et {$minutes} minutes."
])); ]));
$this->reschedule($hours * 60 + $minutes + 1);
return; return;
} }
// Click the dailyfree button // Click the dailyfree button
$availibleInButton->click(); $availibleInButton->click();
sleep(15);
$browser->waitForText("Your drop", 30, true);
$lootElement = $browser->driver->findElement(WebDriverBy::xpath('//div[contains(@class, "daily-free-win-bonus")]')); $lootElement = $browser->driver->findElement(WebDriverBy::xpath('//div[contains(@class, "daily-free-win-bonus")]'));
$lootElement->takeElementScreenshot(HellcaseDailyFreeScreenshot::getImgFileAbsolutePath()); $lootElement->takeElementScreenshot(HellcaseDailyFreeScreenshot::getImgFileAbsolutePath());
$this->reschedule((24 * 60) - ($this::APPROXIMATIVE_RUNNING_MINUTES / 2)); // Reschedule in 24hr -1min
AllNotification::send( AllNotification::send(
new HellcaseNotificationDailyFree($this->jobId, new HellcaseNotificationDailyFreeBody()) new HellcaseNotificationDailyFree($this->jobId, new HellcaseNotificationDailyFreeBody())
); );
@@ -204,11 +237,12 @@ class HellcaseJob extends BrowserJob
* @throws \Exception * @throws \Exception
* @return void * @return void
*/ */
private function fillDailyFreeConditions(Browser $browser) { private function fillDailyFreeConditions(Browser $browser)
{
// 1. See what conditions we need to fullfill // 1. See what conditions we need to fullfill
$conditions = []; $conditions = [];
$conditionsDivs = $browser->driver->findElements(WebDriverBy::xpath('//*[@class = "daily-free-requirement__heading-left"]')); $conditionsDivs = $browser->driver->findElements(WebDriverBy::xpath('//*[@class = "daily-free-requirement__heading-left"]'));
for($i = 0; $i < sizeof($conditionsDivs); $i++) { for ($i = 0; $i < sizeof($conditionsDivs); $i++) {
$conditionDiv = $conditionsDivs[$i]; $conditionDiv = $conditionsDivs[$i];
// See if the element has the completed class // See if the element has the completed class
$conditions[$i] = [ $conditions[$i] = [
@@ -235,13 +269,14 @@ class HellcaseJob extends BrowserJob
* @param \Laravel\Dusk\Browser $browser * @param \Laravel\Dusk\Browser $browser
* @return void * @return void
*/ */
private function changeSteamProfilePicture(Browser $browser) { private function changeSteamProfilePicture(Browser $browser)
{
// Get all of the availible image link // Get all of the availible image link
$images = $browser->driver->findElements(WebDriverBy::xpath('//a[@class = "daily-free-user-requirement-avatar-item"]')); $images = $browser->driver->findElements(WebDriverBy::xpath('//a[@class = "daily-free-user-requirement-avatar-item"]'));
// Download the image from the second link in a special folder // Download the image from the second link in a special folder
$imageLink = $images[1]->getAttribute("href"); $imageLink = $images[1]->getAttribute("href");
// Download the image in app/Browser/downloads/ // Download the image in app/Browser/downloads/
$imagePath = base_path("app/Browser/downloads/Hellcase/pp.jpg"); $imagePath = base_path("app/Browser/downloads/Hellcase/pp.png");
file_put_contents($imagePath, file_get_contents($imageLink)); file_put_contents($imagePath, file_get_contents($imageLink));
$this->goToSteamProfileSettings($browser); $this->goToSteamProfileSettings($browser);
@@ -274,7 +309,8 @@ class HellcaseJob extends BrowserJob
} }
} }
private function changeSteamProfileToPublic(Browser $browser) { private function changeSteamProfileToPublic(Browser $browser)
{
$this->goToSteamProfileSettings($browser); $this->goToSteamProfileSettings($browser);
// Wait for and click "Privacy Settings" // Wait for and click "Privacy Settings"
@@ -298,7 +334,8 @@ class HellcaseJob extends BrowserJob
* @param \Laravel\Dusk\Browser $browser * @param \Laravel\Dusk\Browser $browser
* @return void * @return void
*/ */
private function goToSteamProfileSettings(Browser $browser) { private function goToSteamProfileSettings(Browser $browser)
{
// Get the link that has text "Steam profile" // Get the link that has text "Steam profile"
$steamProfileLink = $browser->driver->findElement(WebDriverBy::xpath('//a[contains(text(), "Steam profile")]')); $steamProfileLink = $browser->driver->findElement(WebDriverBy::xpath('//a[contains(text(), "Steam profile")]'));
$browser->visit($steamProfileLink->getAttribute("href")); $browser->visit($steamProfileLink->getAttribute("href"));
+6 -1
View File
@@ -3,6 +3,7 @@
namespace App\Providers; namespace App\Providers;
use App\Browser\BrowserJob; use App\Browser\BrowserJob;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\Facades\Vite; use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@@ -19,8 +20,12 @@ class AppServiceProvider extends ServiceProvider
/** /**
* Bootstrap any application services. * Bootstrap any application services.
*/ */
public function boot(): void public function boot(UrlGenerator $url): void
{ {
Vite::prefetch(concurrency: 3); Vite::prefetch(concurrency: 3);
if (str_starts_with(config('app.url'), "https://")) {
$url->forceScheme('https');
}
} }
} }
@@ -0,0 +1,67 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Telescope;
use Laravel\Telescope\TelescopeApplicationServiceProvider;
class TelescopeServiceProvider extends TelescopeApplicationServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
Telescope::night();
$this->hideSensitiveRequestDetails();
$isLocal = $this->app->environment('local');
Telescope::filter(function (IncomingEntry $entry) use ($isLocal) {
return true;
/* $isLocal ||
$entry->isReportableException() ||
$entry->isFailedRequest() ||
$entry->isFailedJob() ||
$entry->isScheduledTask() ||
$entry->isCache() ||
$entry->isDump() ||
$entry->isQuery() ||
$entry->isSlowQuery() ||
$entry->hasMonitoredTag(); */
});
}
/**
* Prevent sensitive request details from being logged by Telescope.
*/
protected function hideSensitiveRequestDetails(): void
{
if ($this->app->environment('local')) {
return;
}
Telescope::hideRequestParameters(['_token']);
Telescope::hideRequestHeaders([
'cookie',
'x-csrf-token',
'x-xsrf-token',
]);
}
/**
* Register the Telescope gate.
*
* This gate determines who can access Telescope in non-local environments.
*/
protected function gate(): void
{
Gate::define('viewTelescope', function ($user) {
return true;
});
}
}
+1
View File
@@ -9,6 +9,7 @@ return Application::configure(basePath: dirname(__DIR__))
web: __DIR__.'/../routes/web.php', web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php', api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php', commands: __DIR__.'/../routes/console.php',
channels: __DIR__.'/../routes/channels.php',
health: '/up', health: '/up',
) )
->withMiddleware(function (Middleware $middleware) { ->withMiddleware(function (Middleware $middleware) {
+1
View File
@@ -3,4 +3,5 @@
return [ return [
App\Providers\AppServiceProvider::class, App\Providers\AppServiceProvider::class,
App\Providers\BrowserJobsServiceProvider::class, App\Providers\BrowserJobsServiceProvider::class,
App\Providers\TelescopeServiceProvider::class,
]; ];
-2
View File
@@ -4,8 +4,6 @@ services:
restart: unless-stopped restart: unless-stopped
ports: ports:
- 80:80 - 80:80
environment:
APP_URL: datbrowser.matthiasg.dev
volumes: volumes:
- browserDownloads:/app/Browser/downloads - browserDownloads:/app/Browser/downloads
- browserScreenshots:/app/Browser/screenshots - browserScreenshots:/app/Browser/screenshots
+2
View File
@@ -14,7 +14,9 @@
"inertiajs/inertia-laravel": "^2.0", "inertiajs/inertia-laravel": "^2.0",
"laravel/dusk": "^8.2", "laravel/dusk": "^8.2",
"laravel/framework": "^11.31", "laravel/framework": "^11.31",
"laravel/reverb": "^1.0",
"laravel/sanctum": "^4.0", "laravel/sanctum": "^4.0",
"laravel/telescope": "^5.5",
"laravel/tinker": "^2.9", "laravel/tinker": "^2.9",
"tightenco/ziggy": "^2.0" "tightenco/ziggy": "^2.0"
}, },
Generated
+1068 -1
View File
File diff suppressed because it is too large Load Diff
+82
View File
@@ -0,0 +1,82 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "reverb", "pusher", "ably", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_CONNECTION', 'reverb'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over WebSockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'reverb' => [
'driver' => 'reverb',
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT', 443),
'scheme' => env('REVERB_SCHEME', 'https'),
'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
+92
View File
@@ -0,0 +1,92 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Reverb Server
|--------------------------------------------------------------------------
|
| This option controls the default server used by Reverb to handle
| incoming messages as well as broadcasting message to all your
| connected clients. At this time only "reverb" is supported.
|
*/
'default' => env('REVERB_SERVER', 'reverb'),
/*
|--------------------------------------------------------------------------
| Reverb Servers
|--------------------------------------------------------------------------
|
| Here you may define details for each of the supported Reverb servers.
| Each server has its own configuration options that are defined in
| the array below. You should ensure all the options are present.
|
*/
'servers' => [
'reverb' => [
'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
'port' => env('REVERB_SERVER_PORT', 8080),
'hostname' => env('REVERB_HOST'),
'options' => [
'tls' => [],
],
'max_request_size' => env('REVERB_MAX_REQUEST_SIZE', 10_000),
'scaling' => [
'enabled' => env('REVERB_SCALING_ENABLED', false),
'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
'server' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'database' => env('REDIS_DB', '0'),
],
],
'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
'telescope_ingest_interval' => env('REVERB_TELESCOPE_INGEST_INTERVAL', 15),
],
],
/*
|--------------------------------------------------------------------------
| Reverb Applications
|--------------------------------------------------------------------------
|
| Here you may define how Reverb applications are managed. If you choose
| to use the "config" provider, you may define an array of apps which
| your server will support, including their connection credentials.
|
*/
'apps' => [
'provider' => 'config',
'apps' => [
[
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT', 443),
'scheme' => env('REVERB_SCHEME', 'https'),
'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
],
'allowed_origins' => ['*'],
'ping_interval' => env('REVERB_APP_PING_INTERVAL', 60),
'activity_timeout' => env('REVERB_APP_ACTIVITY_TIMEOUT', 30),
'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10_000),
],
],
],
];
+206
View File
@@ -0,0 +1,206 @@
<?php
use Laravel\Telescope\Http\Middleware\Authorize;
use Laravel\Telescope\Watchers;
return [
/*
|--------------------------------------------------------------------------
| Telescope Master Switch
|--------------------------------------------------------------------------
|
| This option may be used to disable all Telescope watchers regardless
| of their individual configuration, which simply provides a single
| and convenient way to enable or disable Telescope data storage.
|
*/
'enabled' => env('TELESCOPE_ENABLED', true),
/*
|--------------------------------------------------------------------------
| Telescope Domain
|--------------------------------------------------------------------------
|
| This is the subdomain where Telescope will be accessible from. If the
| setting is null, Telescope will reside under the same domain as the
| application. Otherwise, this value will be used as the subdomain.
|
*/
'domain' => env('TELESCOPE_DOMAIN'),
/*
|--------------------------------------------------------------------------
| Telescope Path
|--------------------------------------------------------------------------
|
| This is the URI path where Telescope will be accessible from. Feel free
| to change this path to anything you like. Note that the URI will not
| affect the paths of its internal API that aren't exposed to users.
|
*/
'path' => env('TELESCOPE_PATH', 'telescope'),
/*
|--------------------------------------------------------------------------
| Telescope Storage Driver
|--------------------------------------------------------------------------
|
| This configuration options determines the storage driver that will
| be used to store Telescope's data. In addition, you may set any
| custom options as needed by the particular driver you choose.
|
*/
'driver' => env('TELESCOPE_DRIVER', 'database'),
'storage' => [
'database' => [
'connection' => env('DB_CONNECTION', 'mysql'),
'chunk' => 1000,
],
],
/*
|--------------------------------------------------------------------------
| Telescope Queue
|--------------------------------------------------------------------------
|
| This configuration options determines the queue connection and queue
| which will be used to process ProcessPendingUpdate jobs. This can
| be changed if you would prefer to use a non-default connection.
|
*/
'queue' => [
'connection' => env('TELESCOPE_QUEUE_CONNECTION', null),
'queue' => env('TELESCOPE_QUEUE', null),
'delay' => env('TELESCOPE_QUEUE_DELAY', 10),
],
/*
|--------------------------------------------------------------------------
| Telescope Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will be assigned to every Telescope route, giving you
| the chance to add your own middleware to this list or change any of
| the existing middleware. Or, you can simply stick with this list.
|
*/
'middleware' => [
'web',
// Authorize::class,
],
/*
|--------------------------------------------------------------------------
| Allowed / Ignored Paths & Commands
|--------------------------------------------------------------------------
|
| The following array lists the URI paths and Artisan commands that will
| not be watched by Telescope. In addition to this list, some Laravel
| commands, like migrations and queue commands, are always ignored.
|
*/
'only_paths' => [
// 'api/*'
],
'ignore_paths' => [
'livewire*',
'nova-api*',
'pulse*',
],
'ignore_commands' => [
//
],
/*
|--------------------------------------------------------------------------
| Telescope Watchers
|--------------------------------------------------------------------------
|
| The following array lists the "watchers" that will be registered with
| Telescope. The watchers gather the application's profile data when
| a request or task is executed. Feel free to customize this list.
|
*/
'watchers' => [
Watchers\BatchWatcher::class => env('TELESCOPE_BATCH_WATCHER', true),
Watchers\CacheWatcher::class => [
'enabled' => env('TELESCOPE_CACHE_WATCHER', true),
'hidden' => [],
],
Watchers\ClientRequestWatcher::class => env('TELESCOPE_CLIENT_REQUEST_WATCHER', true),
Watchers\CommandWatcher::class => [
'enabled' => env('TELESCOPE_COMMAND_WATCHER', true),
'ignore' => [],
],
Watchers\DumpWatcher::class => [
'enabled' => env('TELESCOPE_DUMP_WATCHER', true),
'always' => env('TELESCOPE_DUMP_WATCHER_ALWAYS', false),
],
Watchers\EventWatcher::class => [
'enabled' => env('TELESCOPE_EVENT_WATCHER', true),
'ignore' => [],
],
Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true),
Watchers\GateWatcher::class => [
'enabled' => env('TELESCOPE_GATE_WATCHER', true),
'ignore_abilities' => [],
'ignore_packages' => true,
'ignore_paths' => [],
],
Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true),
Watchers\LogWatcher::class => [
'enabled' => env('TELESCOPE_LOG_WATCHER', true),
'level' => 'error',
],
Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true),
Watchers\ModelWatcher::class => [
'enabled' => env('TELESCOPE_MODEL_WATCHER', true),
'events' => ['eloquent.*'],
'hydrations' => true,
],
Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true),
Watchers\QueryWatcher::class => [
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
'ignore_packages' => true,
'ignore_paths' => [],
'slow' => 100,
],
Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true),
Watchers\RequestWatcher::class => [
'enabled' => env('TELESCOPE_REQUEST_WATCHER', true),
'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64),
'ignore_http_methods' => [],
'ignore_status_codes' => [],
],
Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true),
Watchers\ViewWatcher::class => env('TELESCOPE_VIEW_WATCHER', true),
],
];
@@ -0,0 +1,70 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Get the migration connection name.
*/
public function getConnection(): ?string
{
return config('telescope.storage.database.connection');
}
/**
* Run the migrations.
*/
public function up(): void
{
$schema = Schema::connection($this->getConnection());
$schema->create('telescope_entries', function (Blueprint $table) {
$table->bigIncrements('sequence');
$table->uuid('uuid');
$table->uuid('batch_id');
$table->string('family_hash')->nullable();
$table->boolean('should_display_on_index')->default(true);
$table->string('type', 20);
$table->longText('content');
$table->dateTime('created_at')->nullable();
$table->unique('uuid');
$table->index('batch_id');
$table->index('family_hash');
$table->index('created_at');
$table->index(['type', 'should_display_on_index']);
});
$schema->create('telescope_entries_tags', function (Blueprint $table) {
$table->uuid('entry_uuid');
$table->string('tag');
$table->primary(['entry_uuid', 'tag']);
$table->index('tag');
$table->foreign('entry_uuid')
->references('uuid')
->on('telescope_entries')
->onDelete('cascade');
});
$schema->create('telescope_monitoring', function (Blueprint $table) {
$table->string('tag')->primary();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$schema = Schema::connection($this->getConnection());
$schema->dropIfExists('telescope_entries_tags');
$schema->dropIfExists('telescope_entries');
$schema->dropIfExists('telescope_monitoring');
}
};
@@ -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::create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('failed_jobs');
}
};
+12
View File
@@ -0,0 +1,12 @@
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work --queue=high,default --tries=3 --timeout=300 --sleep=3 --no-interaction --max-time=3600 --max-jobs=1
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/worker.log
stopwaitsecs=3600
+7
View File
@@ -0,0 +1,7 @@
[supervisord]
nodaemon=true
user=root
[include]
files = /etc/supervisor/conf.d/*.conf
+7 -1
View File
@@ -3,9 +3,15 @@
# Migrate the database # Migrate the database
php ./artisan migrate --force php ./artisan migrate --force
# Cache
php ./artisan optimize:clear && php ./artisan optimize
# Scheduler
crond -b -L /dev/stdout
# Queue worker # Queue worker
php ./artisan queue:work --queue=high,default --tries=3 --timeout=90 --sleep=3 --daemon --no-interaction & supervisord --nodaemon --configuration /etc/supervisord.conf &
supervisorctl start "laravel-worker:*"
# Start all of the server sumulataneously # Start all of the server sumulataneously
php ./artisan serve --no-interaction -vvv --port=80 --host=0.0.0.0 php ./artisan serve --no-interaction -vvv --port=80 --host=0.0.0.0
+2
View File
@@ -12,8 +12,10 @@
"autoprefixer": "^10.4.12", "autoprefixer": "^10.4.12",
"axios": "^1.7.4", "axios": "^1.7.4",
"concurrently": "^9.0.1", "concurrently": "^9.0.1",
"laravel-echo": "^2.0.2",
"laravel-vite-plugin": "^1.2.0", "laravel-vite-plugin": "^1.2.0",
"postcss": "^8.4.31", "postcss": "^8.4.31",
"pusher-js": "^8.4.0",
"sass-embedded": "^1.83.4", "sass-embedded": "^1.83.4",
"tailwindcss": "^3.2.1", "tailwindcss": "^3.2.1",
"typescript": "^5.6.3", "typescript": "^5.6.3",
+231
View File
@@ -8,6 +8,9 @@ importers:
.: .:
dependencies: dependencies:
'@vueuse/core':
specifier: ^12.5.0
version: 12.7.0(typescript@5.7.3)
class-variance-authority: class-variance-authority:
specifier: ^0.7.1 specifier: ^0.7.1
version: 0.7.1 version: 0.7.1
@@ -17,6 +20,12 @@ importers:
lucide-react: lucide-react:
specifier: ^0.474.0 specifier: ^0.474.0
version: 0.474.0(react@19.0.0) version: 0.474.0(react@19.0.0)
lucide-vue-next:
specifier: ^0.474.0
version: 0.474.0(vue@3.5.13(typescript@5.7.3))
radix-vue:
specifier: ^1.9.13
version: 1.9.16(vue@3.5.13(typescript@5.7.3))
tailwind-merge: tailwind-merge:
specifier: ^2.6.0 specifier: ^2.6.0
version: 2.6.0 version: 2.6.0
@@ -42,12 +51,18 @@ importers:
concurrently: concurrently:
specifier: ^9.0.1 specifier: ^9.0.1
version: 9.1.2 version: 9.1.2
laravel-echo:
specifier: ^2.0.2
version: 2.0.2
laravel-vite-plugin: laravel-vite-plugin:
specifier: ^1.2.0 specifier: ^1.2.0
version: 1.2.0(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0)) version: 1.2.0(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0))
postcss: postcss:
specifier: ^8.4.31 specifier: ^8.4.31
version: 8.5.1 version: 8.5.1
pusher-js:
specifier: ^8.4.0
version: 8.4.0
sass-embedded: sass-embedded:
specifier: ^1.83.4 specifier: ^1.83.4
version: 1.83.4 version: 1.83.4
@@ -243,6 +258,18 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@floating-ui/core@1.6.9':
resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
'@floating-ui/dom@1.6.13':
resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==}
'@floating-ui/utils@0.2.9':
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
'@floating-ui/vue@1.1.6':
resolution: {integrity: sha512-XFlUzGHGv12zbgHNk5FN2mUB7ROul3oG2ENdTpWdE+qMFxyNxWSRmsoyhiEnpmabNm6WnUvR1OvJfUfN4ojC1A==}
'@inertiajs/core@2.0.3': '@inertiajs/core@2.0.3':
resolution: {integrity: sha512-JvXzqc2XAt3WgEDMyxCyXO6bDLMCsBjFsYREU1/+3wtNTib7QKwK71+aF+MrhILpz+kRTi29TsLqnbkPHBAZjw==} resolution: {integrity: sha512-JvXzqc2XAt3WgEDMyxCyXO6bDLMCsBjFsYREU1/+3wtNTib7QKwK71+aF+MrhILpz+kRTi29TsLqnbkPHBAZjw==}
@@ -251,6 +278,12 @@ packages:
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
'@internationalized/date@3.7.0':
resolution: {integrity: sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==}
'@internationalized/number@3.6.0':
resolution: {integrity: sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==}
'@isaacs/cliui@8.0.2': '@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'} engines: {node: '>=12'}
@@ -384,14 +417,28 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
'@tailwindcss/forms@0.5.10': '@tailwindcss/forms@0.5.10':
resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==} resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==}
peerDependencies: peerDependencies:
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
'@tanstack/virtual-core@3.13.2':
resolution: {integrity: sha512-Qzz4EgzMbO5gKrmqUondCjiHcuu4B1ftHb0pjCut661lXZdGoHeze9f/M8iwsK1t5LGR6aNuNGU7mxkowaW6RQ==}
'@tanstack/vue-virtual@3.13.2':
resolution: {integrity: sha512-z4swzjdhzCh95n9dw9lTvw+t3iwSkYRlVkYkra3C9mul/m5fTzHR7KmtkwH4qXMTXGJUbngtC/bz2cHQIHkO8g==}
peerDependencies:
vue: ^2.7.0 || ^3.0.0
'@types/estree@1.0.6': '@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
'@vitejs/plugin-vue@5.2.1': '@vitejs/plugin-vue@5.2.1':
resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
@@ -448,6 +495,24 @@ packages:
'@vue/shared@3.5.13': '@vue/shared@3.5.13':
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
'@vueuse/core@10.11.1':
resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
'@vueuse/core@12.7.0':
resolution: {integrity: sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA==}
'@vueuse/metadata@10.11.1':
resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
'@vueuse/metadata@12.7.0':
resolution: {integrity: sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g==}
'@vueuse/shared@10.11.1':
resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
'@vueuse/shared@12.7.0':
resolution: {integrity: sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw==}
alien-signals@0.4.14: alien-signals@0.4.14:
resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==}
@@ -477,6 +542,10 @@ packages:
arg@5.0.2: arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
aria-hidden@1.2.4:
resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
engines: {node: '>=10'}
asynckit@0.4.0: asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
@@ -588,6 +657,9 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
delayed-stream@1.0.0: delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
@@ -642,6 +714,9 @@ packages:
estree-walker@2.0.2: estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-glob@3.3.3: fast-glob@3.3.3:
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
engines: {node: '>=8.6.0'} engines: {node: '>=8.6.0'}
@@ -762,6 +837,10 @@ packages:
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
hasBin: true hasBin: true
laravel-echo@2.0.2:
resolution: {integrity: sha512-Ciai6hA7r35MFqNRb8G034cvm9WiveSTFQQKRGJhWtZGbng7C8BBa5QvqDxk/Mw5GeJ+q19jrEwQhf7r1b1lcg==}
engines: {node: '>=20'}
laravel-vite-plugin@1.2.0: laravel-vite-plugin@1.2.0:
resolution: {integrity: sha512-R0pJ+IcTVeqEMoKz/B2Ij57QVq3sFTABiFmb06gAwFdivbOgsUtuhX6N2MGLEArajrS3U5JbberzwOe7uXHMHQ==} resolution: {integrity: sha512-R0pJ+IcTVeqEMoKz/B2Ij57QVq3sFTABiFmb06gAwFdivbOgsUtuhX6N2MGLEArajrS3U5JbberzwOe7uXHMHQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -794,6 +873,11 @@ packages:
peerDependencies: peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
lucide-vue-next@0.474.0:
resolution: {integrity: sha512-bQaSBjfJ33xiPQCxCf4JD3rcUgZFgWZzxSY8SScNa4Mcq2vWGlbvQx6icTL1UXRqsxzfoT13RXawePSmgg4iWw==}
peerDependencies:
vue: '>=3.0.1'
magic-string@0.30.17: magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
@@ -840,6 +924,11 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
nanoid@5.1.2:
resolution: {integrity: sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==}
engines: {node: ^18 || >=20}
hasBin: true
node-releases@2.0.19: node-releases@2.0.19:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
@@ -939,6 +1028,9 @@ packages:
proxy-from-env@1.1.0: proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
pusher-js@8.4.0:
resolution: {integrity: sha512-wp3HqIIUc1GRyu1XrP6m2dgyE9MoCsXVsWNlohj0rjSkLf+a0jLvEyVubdg58oMk7bhjBWnFClgp8jfAa6Ak4Q==}
qs@6.14.0: qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'} engines: {node: '>=0.6'}
@@ -946,6 +1038,11 @@ packages:
queue-microtask@1.2.3: queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
radix-vue@1.9.16:
resolution: {integrity: sha512-xwkTfQ7Ub/0XmT40JDc3g03xuYqKIJzVKGazcIkk8mUksj/tbw1pcCVRP0e3hKvPHKeQ0cktI1MvRnlUwCRvoQ==}
peerDependencies:
vue: '>= 3.2.0'
react@19.0.0: react@19.0.0:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@@ -1217,6 +1314,9 @@ packages:
tslib@2.8.1: tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tweetnacl@1.0.3:
resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==}
typescript@5.7.3: typescript@5.7.3:
resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
@@ -1280,6 +1380,17 @@ packages:
vscode-uri@3.0.8: vscode-uri@3.0.8:
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
hasBin: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue-tsc@2.2.0: vue-tsc@2.2.0:
resolution: {integrity: sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==} resolution: {integrity: sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==}
hasBin: true hasBin: true
@@ -1418,6 +1529,26 @@ snapshots:
'@esbuild/win32-x64@0.24.2': '@esbuild/win32-x64@0.24.2':
optional: true optional: true
'@floating-ui/core@1.6.9':
dependencies:
'@floating-ui/utils': 0.2.9
'@floating-ui/dom@1.6.13':
dependencies:
'@floating-ui/core': 1.6.9
'@floating-ui/utils': 0.2.9
'@floating-ui/utils@0.2.9': {}
'@floating-ui/vue@1.1.6(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@floating-ui/dom': 1.6.13
'@floating-ui/utils': 0.2.9
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@inertiajs/core@2.0.3': '@inertiajs/core@2.0.3':
dependencies: dependencies:
axios: 1.7.9 axios: 1.7.9
@@ -1435,6 +1566,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
'@internationalized/date@3.7.0':
dependencies:
'@swc/helpers': 0.5.15
'@internationalized/number@3.6.0':
dependencies:
'@swc/helpers': 0.5.15
'@isaacs/cliui@8.0.2': '@isaacs/cliui@8.0.2':
dependencies: dependencies:
string-width: 5.1.2 string-width: 5.1.2
@@ -1533,13 +1672,26 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.32.1': '@rollup/rollup-win32-x64-msvc@4.32.1':
optional: true optional: true
'@swc/helpers@0.5.15':
dependencies:
tslib: 2.8.1
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)': '@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)':
dependencies: dependencies:
mini-svg-data-uri: 1.4.4 mini-svg-data-uri: 1.4.4
tailwindcss: 3.4.17 tailwindcss: 3.4.17
'@tanstack/virtual-core@3.13.2': {}
'@tanstack/vue-virtual@3.13.2(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@tanstack/virtual-core': 3.13.2
vue: 3.5.13(typescript@5.7.3)
'@types/estree@1.0.6': {} '@types/estree@1.0.6': {}
'@types/web-bluetooth@0.0.20': {}
'@vitejs/plugin-vue@5.2.1(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))': '@vitejs/plugin-vue@5.2.1(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))':
dependencies: dependencies:
vite: 6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0) vite: 6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0)
@@ -1629,6 +1781,42 @@ snapshots:
'@vue/shared@3.5.13': {} '@vue/shared@3.5.13': {}
'@vueuse/core@10.11.1(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 10.11.1
'@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.7.3))
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@vueuse/core@12.7.0(typescript@5.7.3)':
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 12.7.0
'@vueuse/shared': 12.7.0(typescript@5.7.3)
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- typescript
'@vueuse/metadata@10.11.1': {}
'@vueuse/metadata@12.7.0': {}
'@vueuse/shared@10.11.1(vue@3.5.13(typescript@5.7.3))':
dependencies:
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@vueuse/shared@12.7.0(typescript@5.7.3)':
dependencies:
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- typescript
alien-signals@0.4.14: {} alien-signals@0.4.14: {}
ansi-regex@5.0.1: {} ansi-regex@5.0.1: {}
@@ -1650,6 +1838,10 @@ snapshots:
arg@5.0.2: {} arg@5.0.2: {}
aria-hidden@1.2.4:
dependencies:
tslib: 2.8.1
asynckit@0.4.0: {} asynckit@0.4.0: {}
autoprefixer@10.4.20(postcss@8.5.1): autoprefixer@10.4.20(postcss@8.5.1):
@@ -1772,6 +1964,8 @@ snapshots:
deepmerge@4.3.1: {} deepmerge@4.3.1: {}
defu@6.1.4: {}
delayed-stream@1.0.0: {} delayed-stream@1.0.0: {}
didyoumean@1.2.2: {} didyoumean@1.2.2: {}
@@ -1834,6 +2028,8 @@ snapshots:
estree-walker@2.0.2: {} estree-walker@2.0.2: {}
fast-deep-equal@3.1.3: {}
fast-glob@3.3.3: fast-glob@3.3.3:
dependencies: dependencies:
'@nodelib/fs.stat': 2.0.5 '@nodelib/fs.stat': 2.0.5
@@ -1949,6 +2145,8 @@ snapshots:
jiti@1.21.7: {} jiti@1.21.7: {}
laravel-echo@2.0.2: {}
laravel-vite-plugin@1.2.0(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0)): laravel-vite-plugin@1.2.0(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0)):
dependencies: dependencies:
picocolors: 1.1.1 picocolors: 1.1.1
@@ -1971,6 +2169,10 @@ snapshots:
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
lucide-vue-next@0.474.0(vue@3.5.13(typescript@5.7.3)):
dependencies:
vue: 3.5.13(typescript@5.7.3)
magic-string@0.30.17: magic-string@0.30.17:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/sourcemap-codec': 1.5.0
@@ -2008,6 +2210,8 @@ snapshots:
nanoid@3.3.8: {} nanoid@3.3.8: {}
nanoid@5.1.2: {}
node-releases@2.0.19: {} node-releases@2.0.19: {}
normalize-path@3.0.0: {} normalize-path@3.0.0: {}
@@ -2080,12 +2284,33 @@ snapshots:
proxy-from-env@1.1.0: {} proxy-from-env@1.1.0: {}
pusher-js@8.4.0:
dependencies:
tweetnacl: 1.0.3
qs@6.14.0: qs@6.14.0:
dependencies: dependencies:
side-channel: 1.1.0 side-channel: 1.1.0
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
radix-vue@1.9.16(vue@3.5.13(typescript@5.7.3)):
dependencies:
'@floating-ui/dom': 1.6.13
'@floating-ui/vue': 1.1.6(vue@3.5.13(typescript@5.7.3))
'@internationalized/date': 3.7.0
'@internationalized/number': 3.6.0
'@tanstack/vue-virtual': 3.13.2(vue@3.5.13(typescript@5.7.3))
'@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.7.3))
'@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.7.3))
aria-hidden: 1.2.4
defu: 6.1.4
fast-deep-equal: 3.1.3
nanoid: 5.1.2
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- '@vue/composition-api'
react@19.0.0: {} react@19.0.0: {}
read-cache@1.0.0: read-cache@1.0.0:
@@ -2368,6 +2593,8 @@ snapshots:
tslib@2.8.1: {} tslib@2.8.1: {}
tweetnacl@1.0.3: {}
typescript@5.7.3: {} typescript@5.7.3: {}
update-browserslist-db@1.1.2(browserslist@4.24.4): update-browserslist-db@1.1.2(browserslist@4.24.4):
@@ -2398,6 +2625,10 @@ snapshots:
vscode-uri@3.0.8: {} vscode-uri@3.0.8: {}
vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)):
dependencies:
vue: 3.5.13(typescript@5.7.3)
vue-tsc@2.2.0(typescript@5.7.3): vue-tsc@2.2.0(typescript@5.7.3):
dependencies: dependencies:
'@volar/typescript': 2.4.11 '@volar/typescript': 2.4.11
Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+5
View File
@@ -0,0 +1,5 @@
{
"/app.js": "/app.js?id=a04a99f77a55ffcecde23cd7304b481b",
"/app-dark.css": "/app-dark.css?id=1ea407db56c5163ae29311f1f38eb7b9",
"/app.css": "/app.css?id=de4c978567bfd90b38d186937dee5ccf"
}
+1 -1
View File
@@ -11,7 +11,7 @@ defineProps<{
</script> </script>
<template> <template>
<Head title="Welcome" /> <Head :title="job.name" />
<JobCard :job="job" /> <JobCard :job="job" />
+14
View File
@@ -0,0 +1,14 @@
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
+4
View File
@@ -0,0 +1,4 @@
<?php
use Illuminate\Support\Facades\Broadcast;
+4
View File
@@ -10,5 +10,9 @@ Artisan::command('inspire', function () {
$this->comment(Inspiring::quote()); $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote'); })->purpose('Display an inspiring quote');
// Telescope
Schedule::command('telescope:prune')->monthly();
// Jobs
Schedule::job(new HellcaseJob)->daily()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job'); Schedule::job(new HellcaseJob)->daily()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
// Schedule::job(new HellcaseJob)->everyMinute()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job'); // Schedule::job(new HellcaseJob)->everyMinute()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
+19
View File
@@ -0,0 +1,19 @@
# TODO
- Voir si le scheduler fonctionne au démmarage
- Mettre un timeout pour pas overwhelm le pc au démmarage
- Image pour le join de giveaway
- → Notification
- Ou ajouter des images base64 dans les jobRun
- Risque de devenir volumineux
- Sauf avec le jobqui enlève les vieilles jobRun
- Notification live websocket
- Serveur php plus propre (nginx, apache, n'importe)
- Job qui supprime les vieilles JobRun
- Epic games
## Pour deploy Lama
- Version Lama du compose
- Tuto installation
-1
View File
@@ -3,7 +3,6 @@ import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
export default defineConfig({ export default defineConfig({
base: process.env.ASSET_URL || '/',
plugins: [ plugins: [
laravel({ laravel({
input: 'resources/js/app.ts', input: 'resources/js/app.ts',