@ -60,7 +60,7 @@ public static function decodeOutput(?Activity $activity = null): string
|
||||
$decoded = json_decode(
|
||||
data_get($activity, 'description'),
|
||||
associative: true,
|
||||
flags: JSON_THROW_ON_ERROR
|
||||
flags: JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE
|
||||
);
|
||||
} catch (\JsonException $exception) {
|
||||
return '';
|
||||
@ -164,7 +164,7 @@ protected function elapsedTime(): int
|
||||
|
||||
public function encodeOutput($type, $output)
|
||||
{
|
||||
$outputStack = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR);
|
||||
$outputStack = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$outputStack[] = [
|
||||
'type' => $type,
|
||||
@ -174,12 +174,12 @@ public function encodeOutput($type, $output)
|
||||
'order' => $this->getLatestCounter(),
|
||||
];
|
||||
|
||||
return json_encode($outputStack, flags: JSON_THROW_ON_ERROR);
|
||||
return json_encode($outputStack, flags: JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
protected function getLatestCounter(): int
|
||||
{
|
||||
$description = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR);
|
||||
$description = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
|
||||
if ($description === null || count($description) === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -221,7 +221,19 @@ private function sentinel()
|
||||
}
|
||||
$name = data_get($exitedService, 'name');
|
||||
$fqdn = data_get($exitedService, 'fqdn');
|
||||
$containerName = $name ? "$name, available at $fqdn" : $fqdn;
|
||||
if ($name) {
|
||||
if ($fqdn) {
|
||||
$containerName = "$name, available at $fqdn";
|
||||
} else {
|
||||
$containerName = $name;
|
||||
}
|
||||
} else {
|
||||
if ($fqdn) {
|
||||
$containerName = $fqdn;
|
||||
} else {
|
||||
$containerName = null;
|
||||
}
|
||||
}
|
||||
$projectUuid = data_get($service, 'environment.project.uuid');
|
||||
$serviceUuid = data_get($service, 'uuid');
|
||||
$environmentName = data_get($service, 'environment.name');
|
||||
@ -231,7 +243,7 @@ private function sentinel()
|
||||
} else {
|
||||
$url = null;
|
||||
}
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
$exitedService->update(['status' => 'exited']);
|
||||
}
|
||||
|
||||
@ -258,7 +270,7 @@ private function sentinel()
|
||||
$url = null;
|
||||
}
|
||||
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
}
|
||||
$notRunningApplicationPreviews = $previews->pluck('id')->diff($foundApplicationPreviews);
|
||||
foreach ($notRunningApplicationPreviews as $previewId) {
|
||||
@ -283,7 +295,7 @@ private function sentinel()
|
||||
$url = null;
|
||||
}
|
||||
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
}
|
||||
$notRunningDatabases = $databases->pluck('id')->diff($foundDatabases);
|
||||
foreach ($notRunningDatabases as $database) {
|
||||
@ -307,7 +319,7 @@ private function sentinel()
|
||||
} else {
|
||||
$url = null;
|
||||
}
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
}
|
||||
|
||||
// Check if proxy is running
|
||||
@ -539,7 +551,19 @@ private function old_way()
|
||||
}
|
||||
$name = data_get($exitedService, 'name');
|
||||
$fqdn = data_get($exitedService, 'fqdn');
|
||||
$containerName = $name ? "$name, available at $fqdn" : $fqdn;
|
||||
if ($name) {
|
||||
if ($fqdn) {
|
||||
$containerName = "$name, available at $fqdn";
|
||||
} else {
|
||||
$containerName = $name;
|
||||
}
|
||||
} else {
|
||||
if ($fqdn) {
|
||||
$containerName = $fqdn;
|
||||
} else {
|
||||
$containerName = null;
|
||||
}
|
||||
}
|
||||
$projectUuid = data_get($service, 'environment.project.uuid');
|
||||
$serviceUuid = data_get($service, 'uuid');
|
||||
$environmentName = data_get($service, 'environment.name');
|
||||
@ -549,7 +573,7 @@ private function old_way()
|
||||
} else {
|
||||
$url = null;
|
||||
}
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
$exitedService->update(['status' => 'exited']);
|
||||
}
|
||||
|
||||
@ -576,7 +600,7 @@ private function old_way()
|
||||
$url = null;
|
||||
}
|
||||
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
}
|
||||
$notRunningApplicationPreviews = $previews->pluck('id')->diff($foundApplicationPreviews);
|
||||
foreach ($notRunningApplicationPreviews as $previewId) {
|
||||
@ -601,7 +625,7 @@ private function old_way()
|
||||
$url = null;
|
||||
}
|
||||
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
}
|
||||
$notRunningDatabases = $databases->pluck('id')->diff($foundDatabases);
|
||||
foreach ($notRunningDatabases as $database) {
|
||||
@ -625,7 +649,7 @@ private function old_way()
|
||||
} else {
|
||||
$url = null;
|
||||
}
|
||||
$this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
// $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
|
||||
}
|
||||
|
||||
// Check if proxy is running
|
||||
|
@ -10,7 +10,18 @@ class CheckProxy
|
||||
use AsAction;
|
||||
public function handle(Server $server, $fromUI = false)
|
||||
{
|
||||
if ($server->proxyType() === 'NONE') {
|
||||
if (!$server->isFunctional()) {
|
||||
return false;
|
||||
}
|
||||
if ($server->isBuildServer()) {
|
||||
if ($server->proxy) {
|
||||
$server->proxy = null;
|
||||
$server->save();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$proxyType = $server->proxyType();
|
||||
if (is_null($proxyType) || $proxyType === 'NONE' || $server->proxy->force_stop) {
|
||||
return false;
|
||||
}
|
||||
['uptime' => $uptime, 'error' => $error] = $server->validateConnection();
|
||||
|
@ -15,7 +15,7 @@ public function handle(Server $server, bool $async = true): string|Activity
|
||||
{
|
||||
try {
|
||||
$proxyType = $server->proxyType();
|
||||
if (is_null($proxyType) || $proxyType === 'NONE') {
|
||||
if (is_null($proxyType) || $proxyType === 'NONE' || $server->proxy->force_stop || $server->isBuildServer()) {
|
||||
return 'OK';
|
||||
}
|
||||
$commands = collect([]);
|
||||
|
@ -40,7 +40,7 @@ public function handle()
|
||||
$serviceTemplatesJson[$name] = $parsed;
|
||||
}
|
||||
}
|
||||
$serviceTemplatesJson = json_encode($serviceTemplatesJson, JSON_PRETTY_PRINT);
|
||||
$serviceTemplatesJson = json_encode($serviceTemplatesJson);
|
||||
file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Jobs\PullHelperImageJob;
|
||||
use App\Jobs\PullSentinelImageJob;
|
||||
use App\Jobs\PullTemplatesAndVersions;
|
||||
use App\Jobs\ServerStatusJob;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
@ -29,6 +30,7 @@ protected function schedule(Schedule $schedule): void
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyMinute();
|
||||
$schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
|
||||
$schedule->job(new PullTemplatesAndVersions)->everyTenMinutes()->onOneServer();
|
||||
// $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer();
|
||||
// Server Jobs
|
||||
$this->check_scheduled_backups($schedule);
|
||||
@ -41,7 +43,7 @@ protected function schedule(Schedule $schedule): void
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyFiveMinutes();
|
||||
$schedule->command('cleanup:unreachable-servers')->daily();
|
||||
|
||||
$schedule->job(new PullTemplatesAndVersions)->everyTenMinutes()->onOneServer();
|
||||
$schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer();
|
||||
// $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer();
|
||||
|
||||
|
@ -82,7 +82,7 @@ public function manual(Request $request)
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'Invalid token.',
|
||||
'message' => 'Invalid signature.',
|
||||
]);
|
||||
ray('Invalid signature');
|
||||
continue;
|
||||
|
222
app/Http/Controllers/Webhook/Gitea.php
Normal file
@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Webhook;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationPreview;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class Gitea extends Controller
|
||||
{
|
||||
public function manual(Request $request)
|
||||
{
|
||||
try {
|
||||
$return_payloads = collect([]);
|
||||
$x_gitea_delivery = request()->header('X-Gitea-Delivery');
|
||||
if (app()->isDownForMaintenance()) {
|
||||
ray('Maintenance mode is on');
|
||||
$epoch = now()->valueOf();
|
||||
$files = Storage::disk('webhooks-during-maintenance')->files();
|
||||
$gitea_delivery_found = collect($files)->filter(function ($file) use ($x_gitea_delivery) {
|
||||
return Str::contains($file, $x_gitea_delivery);
|
||||
})->first();
|
||||
if ($gitea_delivery_found) {
|
||||
ray('Webhook already found');
|
||||
return;
|
||||
}
|
||||
$data = [
|
||||
'attributes' => $request->attributes->all(),
|
||||
'request' => $request->request->all(),
|
||||
'query' => $request->query->all(),
|
||||
'server' => $request->server->all(),
|
||||
'files' => $request->files->all(),
|
||||
'cookies' => $request->cookies->all(),
|
||||
'headers' => $request->headers->all(),
|
||||
'content' => $request->getContent(),
|
||||
];
|
||||
$json = json_encode($data);
|
||||
Storage::disk('webhooks-during-maintenance')->put("{$epoch}_Gitea::manual_{$x_gitea_delivery}", $json);
|
||||
return;
|
||||
}
|
||||
$x_gitea_event = Str::lower($request->header('X-Gitea-Event'));
|
||||
$x_hub_signature_256 = Str::after($request->header('X-Hub-Signature-256'), 'sha256=');
|
||||
$content_type = $request->header('Content-Type');
|
||||
$payload = $request->collect();
|
||||
if ($x_gitea_event === 'ping') {
|
||||
// Just pong
|
||||
return response('pong');
|
||||
}
|
||||
|
||||
if ($content_type !== 'application/json') {
|
||||
$payload = json_decode(data_get($payload, 'payload'), true);
|
||||
}
|
||||
if ($x_gitea_event === 'push') {
|
||||
$branch = data_get($payload, 'ref');
|
||||
$full_name = data_get($payload, 'repository.full_name');
|
||||
if (Str::isMatch('/refs\/heads\/*/', $branch)) {
|
||||
$branch = Str::after($branch, 'refs/heads/');
|
||||
}
|
||||
$added_files = data_get($payload, 'commits.*.added');
|
||||
$removed_files = data_get($payload, 'commits.*.removed');
|
||||
$modified_files = data_get($payload, 'commits.*.modified');
|
||||
$changed_files = collect($added_files)->concat($removed_files)->concat($modified_files)->unique()->flatten();
|
||||
ray($changed_files);
|
||||
ray('Manual Webhook Gitea Push Event with branch: ' . $branch);
|
||||
}
|
||||
if ($x_gitea_event === 'pull_request') {
|
||||
$action = data_get($payload, 'action');
|
||||
$full_name = data_get($payload, 'repository.full_name');
|
||||
$pull_request_id = data_get($payload, 'number');
|
||||
$pull_request_html_url = data_get($payload, 'pull_request.html_url');
|
||||
$branch = data_get($payload, 'pull_request.head.ref');
|
||||
$base_branch = data_get($payload, 'pull_request.base.ref');
|
||||
ray('Webhook Gitea Pull Request Event with branch: ' . $branch . ' and base branch: ' . $base_branch . ' and pull request id: ' . $pull_request_id);
|
||||
}
|
||||
if (!$branch) {
|
||||
return response('Nothing to do. No branch found in the request.');
|
||||
}
|
||||
$applications = Application::where('git_repository', 'like', "%$full_name%");
|
||||
if ($x_gitea_event === 'push') {
|
||||
$applications = $applications->where('git_branch', $branch)->get();
|
||||
if ($applications->isEmpty()) {
|
||||
return response("Nothing to do. No applications found with deploy key set, branch is '$branch' and Git Repository name has $full_name.");
|
||||
}
|
||||
}
|
||||
if ($x_gitea_event === 'pull_request') {
|
||||
$applications = $applications->where('git_branch', $base_branch)->get();
|
||||
if ($applications->isEmpty()) {
|
||||
return response("Nothing to do. No applications found with branch '$base_branch'.");
|
||||
}
|
||||
}
|
||||
foreach ($applications as $application) {
|
||||
$webhook_secret = data_get($application, 'manual_webhook_secret_gitea');
|
||||
$hmac = hash_hmac('sha256', $request->getContent(), $webhook_secret);
|
||||
if (!hash_equals($x_hub_signature_256, $hmac) && !isDev()) {
|
||||
ray('Invalid signature');
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'Invalid signature.',
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
$isFunctional = $application->destination->server->isFunctional();
|
||||
if (!$isFunctional) {
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'Server is not functional.',
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
if ($x_gitea_event === 'push') {
|
||||
if ($application->isDeployable()) {
|
||||
$is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files);
|
||||
if ($is_watch_path_triggered || is_null($application->watch_paths)) {
|
||||
ray('Deploying ' . $application->name . ' with branch ' . $branch);
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
queue_application_deployment(
|
||||
application: $application,
|
||||
deployment_uuid: $deployment_uuid,
|
||||
force_rebuild: false,
|
||||
commit: data_get($payload, 'after', 'HEAD'),
|
||||
is_webhook: true,
|
||||
);
|
||||
$return_payloads->push([
|
||||
'status' => 'success',
|
||||
'message' => 'Deployment queued.',
|
||||
'application_uuid' => $application->uuid,
|
||||
'application_name' => $application->name,
|
||||
]);
|
||||
} else {
|
||||
$paths = str($application->watch_paths)->explode("\n");
|
||||
$return_payloads->push([
|
||||
'status' => 'failed',
|
||||
'message' => 'Changed files do not match watch paths. Ignoring deployment.',
|
||||
'application_uuid' => $application->uuid,
|
||||
'application_name' => $application->name,
|
||||
'details' => [
|
||||
'changed_files' => $changed_files,
|
||||
'watch_paths' => $paths,
|
||||
],
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$return_payloads->push([
|
||||
'status' => 'failed',
|
||||
'message' => 'Deployments disabled.',
|
||||
'application_uuid' => $application->uuid,
|
||||
'application_name' => $application->name,
|
||||
]);
|
||||
}
|
||||
}
|
||||
if ($x_gitea_event === 'pull_request') {
|
||||
if ($action === 'opened' || $action === 'synchronize' || $action === 'reopened') {
|
||||
if ($application->isPRDeployable()) {
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if (!$found) {
|
||||
ApplicationPreview::create([
|
||||
'git_type' => 'gitea',
|
||||
'application_id' => $application->id,
|
||||
'pull_request_id' => $pull_request_id,
|
||||
'pull_request_html_url' => $pull_request_html_url,
|
||||
]);
|
||||
}
|
||||
queue_application_deployment(
|
||||
application: $application,
|
||||
pull_request_id: $pull_request_id,
|
||||
deployment_uuid: $deployment_uuid,
|
||||
force_rebuild: false,
|
||||
commit: data_get($payload, 'head.sha', 'HEAD'),
|
||||
is_webhook: true,
|
||||
git_type: 'gitea'
|
||||
);
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'success',
|
||||
'message' => 'Preview deployment queued.',
|
||||
]);
|
||||
} else {
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'Preview deployments disabled.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
if ($action === 'closed') {
|
||||
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if ($found) {
|
||||
$found->delete();
|
||||
$container_name = generateApplicationContainerName($application, $pull_request_id);
|
||||
// ray('Stopping container: ' . $container_name);
|
||||
instant_remote_process(["docker rm -f $container_name"], $application->destination->server);
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'success',
|
||||
'message' => 'Preview deployment closed.',
|
||||
]);
|
||||
} else {
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'No preview deployment found.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ray($return_payloads);
|
||||
return response($return_payloads);
|
||||
} catch (Exception $e) {
|
||||
ray($e->getMessage());
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
}
|
@ -106,7 +106,7 @@ public function manual(Request $request)
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'Invalid token.',
|
||||
'message' => 'Invalid signature.',
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ public function manual(Request $request)
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'failed',
|
||||
'message' => 'Invalid token.',
|
||||
'message' => 'Invalid signature.',
|
||||
]);
|
||||
ray('Invalid signature');
|
||||
continue;
|
||||
|
@ -184,6 +184,9 @@ public function __construct(int $application_deployment_queue_id)
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$this->application_deployment_queue->update([
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
if (!$this->server->isFunctional()) {
|
||||
$this->application_deployment_queue->addLogEntry("Server is not functional.");
|
||||
$this->fail("Server is not functional.");
|
||||
@ -422,7 +425,7 @@ private function deploy_docker_compose_buildpack()
|
||||
// TODO
|
||||
} else {
|
||||
$this->execute_remote_command([
|
||||
"docker network create --attachable '{$networkId}' >/dev/null || true", "hidden" => true, "ignore_errors" => true
|
||||
"docker network inspect '{$networkId}' >/dev/null 2>&1 || docker network create --attachable '{$networkId}' >/dev/null || true", "hidden" => true, "ignore_errors" => true
|
||||
], [
|
||||
"docker network connect {$networkId} coolify-proxy || true", "hidden" => true, "ignore_errors" => true
|
||||
]);
|
||||
@ -988,6 +991,7 @@ private function health_check()
|
||||
}
|
||||
if (Str::of($this->saved_outputs->get('health_check'))->replace('"', '')->value() === 'unhealthy') {
|
||||
$this->newVersionIsHealthy = false;
|
||||
$this->query_logs();
|
||||
break;
|
||||
}
|
||||
$counter++;
|
||||
@ -997,9 +1001,25 @@ private function health_check()
|
||||
$sleeptime++;
|
||||
}
|
||||
}
|
||||
if (Str::of($this->saved_outputs->get('health_check'))->replace('"', '')->value() === 'starting') {
|
||||
$this->query_logs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private function query_logs()
|
||||
{
|
||||
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
||||
$this->application_deployment_queue->addLogEntry("Container logs:");
|
||||
$this->execute_remote_command(
|
||||
[
|
||||
"command" => "docker logs -n 100 {$this->container_name}",
|
||||
"type" => "stderr",
|
||||
"ignore_errors" => true,
|
||||
],
|
||||
);
|
||||
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
||||
}
|
||||
private function deploy_pull_request()
|
||||
{
|
||||
if ($this->application->build_pack === 'dockercompose') {
|
||||
@ -1257,8 +1277,21 @@ private function generate_nixpacks_confs()
|
||||
// Do any modifications here
|
||||
$this->generate_env_variables();
|
||||
$merged_envs = $this->env_args->merge(collect(data_get($parsed, 'variables', [])));
|
||||
$aptPkgs = data_get($parsed, 'phases.setup.aptPkgs', []);
|
||||
if (count($aptPkgs) === 0) {
|
||||
data_set($parsed, 'phases.setup.aptPkgs', ['curl', 'wget']);
|
||||
} else {
|
||||
if (!in_array('curl', $aptPkgs)) {
|
||||
$aptPkgs[] = 'curl';
|
||||
}
|
||||
if (!in_array('wget', $aptPkgs)) {
|
||||
$aptPkgs[] = 'wget';
|
||||
}
|
||||
data_set($parsed, 'phases.setup.aptPkgs', $aptPkgs);
|
||||
}
|
||||
data_set($parsed, 'variables', $merged_envs->toArray());
|
||||
$this->nixpacks_plan = json_encode($parsed, JSON_PRETTY_PRINT);
|
||||
$this->application_deployment_queue->addLogEntry("Final Nixpacks plan: {$this->nixpacks_plan}", hidden: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1935,16 +1968,16 @@ private function run_pre_deployment_command()
|
||||
if ($containers->count() == 0) {
|
||||
return;
|
||||
}
|
||||
$this->application_deployment_queue->addLogEntry("Executing pre-deployment command (see debug log for output): {$this->application->pre_deployment_command}");
|
||||
$this->application_deployment_queue->addLogEntry("Executing pre-deployment command (see debug log for output).");
|
||||
|
||||
foreach ($containers as $container) {
|
||||
$containerName = data_get($container, 'Names');
|
||||
if ($containers->count() == 1 || str_starts_with($containerName, $this->application->pre_deployment_command_container . '-' . $this->application->uuid)) {
|
||||
$cmd = 'sh -c "' . str_replace('"', '\"', $this->application->pre_deployment_command) . '"';
|
||||
$cmd = "sh -c '" . str_replace("'", "'\''", $this->application->pre_deployment_command) . "'";
|
||||
$exec = "docker exec {$containerName} {$cmd}";
|
||||
$this->execute_remote_command(
|
||||
[
|
||||
executeInDocker($this->deployment_uuid, $exec), 'hidden' => true
|
||||
'command' => $exec, 'hidden' => true
|
||||
],
|
||||
);
|
||||
return;
|
||||
@ -1958,17 +1991,17 @@ private function run_post_deployment_command()
|
||||
if (empty($this->application->post_deployment_command)) {
|
||||
return;
|
||||
}
|
||||
$this->application_deployment_queue->addLogEntry("Executing post-deployment command (see debug log for output): {$this->application->post_deployment_command}");
|
||||
$this->application_deployment_queue->addLogEntry("Executing post-deployment command (see debug log for output).");
|
||||
|
||||
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
||||
foreach ($containers as $container) {
|
||||
$containerName = data_get($container, 'Names');
|
||||
if ($containers->count() == 1 || str_starts_with($containerName, $this->application->post_deployment_command_container . '-' . $this->application->uuid)) {
|
||||
$cmd = 'sh -c "' . str_replace('"', '\"', $this->application->post_deployment_command) . '"';
|
||||
$cmd = "sh -c '" . str_replace("'", "'\''", $this->application->post_deployment_command) . "'";
|
||||
$exec = "docker exec {$containerName} {$cmd}";
|
||||
$this->execute_remote_command(
|
||||
[
|
||||
executeInDocker($this->deployment_uuid, $exec), 'hidden' => true
|
||||
'command' => $exec, 'hidden' => true
|
||||
],
|
||||
);
|
||||
return;
|
||||
|
@ -70,7 +70,7 @@ public function handle(): void
|
||||
}
|
||||
if (!$this->server->log_drain_notification_sent) {
|
||||
ray('Log drain container still unhealthy. Sending notification...');
|
||||
$this->server->team?->notify(new ContainerStopped('Coolify Log Drainer', $this->server, null));
|
||||
// $this->server->team?->notify(new ContainerStopped('Coolify Log Drainer', $this->server, null));
|
||||
$this->server->update(['log_drain_notification_sent' => true]);
|
||||
}
|
||||
} else {
|
||||
|
57
app/Jobs/PullTemplatesAndVersions.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class PullTemplatesAndVersions implements ShouldQueue, ShouldBeEncrypted
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $timeout = 10;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
if (!isDev() && !isCloud()) {
|
||||
ray('PullTemplatesAndVersions versions.json');
|
||||
$response = Http::retry(3, 1000)->get('https://cdn.coollabs.io/coolify/versions.json');
|
||||
if ($response->successful()) {
|
||||
$versions = $response->json();
|
||||
File::put(base_path('versions.json'), json_encode($versions, JSON_PRETTY_PRINT));
|
||||
} else {
|
||||
send_internal_notification('PullTemplatesAndVersions failed with: ' . $response->status() . ' ' . $response->body());
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
send_internal_notification('PullTemplatesAndVersions failed with: ' . $e->getMessage());
|
||||
ray($e->getMessage());
|
||||
}
|
||||
try {
|
||||
if (!isDev()) {
|
||||
ray('PullTemplatesAndVersions service-templates');
|
||||
$response = Http::retry(3, 1000)->get(config('constants.services.official'));
|
||||
if ($response->successful()) {
|
||||
$services = $response->json();
|
||||
File::put(base_path('templates/service-templates.json'), json_encode($services));
|
||||
} else {
|
||||
send_internal_notification('PullTemplatesAndVersions failed with: ' . $response->status() . ' ' . $response->body());
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
send_internal_notification('PullTemplatesAndVersions failed with: ' . $e->getMessage());
|
||||
ray($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -43,10 +43,11 @@ public function handle()
|
||||
try {
|
||||
if ($this->server->isFunctional()) {
|
||||
$this->cleanup(notify: false);
|
||||
$this->removeCoolifyYaml();
|
||||
$this->remove_unnecessary_coolify_yaml();
|
||||
if (config('coolify.is_sentinel_enabled')) {
|
||||
$this->server->checkSentinel();
|
||||
}
|
||||
$this->check_docker_engine();
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage());
|
||||
@ -54,7 +55,38 @@ public function handle()
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
private function removeCoolifyYaml()
|
||||
private function check_docker_engine()
|
||||
{
|
||||
$version = instant_remote_process([
|
||||
"docker info",
|
||||
], $this->server, false);
|
||||
if (is_null($version)) {
|
||||
$os = instant_remote_process([
|
||||
"cat /etc/os-release | grep ^ID=",
|
||||
], $this->server, false);
|
||||
$os = str($os)->after('ID=')->trim();
|
||||
if ($os === 'ubuntu') {
|
||||
try {
|
||||
instant_remote_process([
|
||||
"systemctl start docker",
|
||||
], $this->server);
|
||||
} catch (\Throwable $e) {
|
||||
ray($e->getMessage());
|
||||
return handleError($e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
instant_remote_process([
|
||||
"service docker start",
|
||||
], $this->server);
|
||||
} catch (\Throwable $e) {
|
||||
ray($e->getMessage());
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private function remove_unnecessary_coolify_yaml()
|
||||
{
|
||||
// This will remote the coolify.yaml file from the server as it is not needed on cloud servers
|
||||
if (isCloud() && $this->server->id !== 0) {
|
||||
|
@ -17,5 +17,7 @@ public function handle(ProxyStarted $event): void
|
||||
$this->server = data_get($event, 'data');
|
||||
$this->server->setupDefault404Redirect();
|
||||
$this->server->setupDynamicProxyConfiguration();
|
||||
$this->server->proxy->force_stop = false;
|
||||
$this->server->save();
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class Compose extends Component
|
||||
public string $base64 = '';
|
||||
public $services;
|
||||
public function mount() {
|
||||
$this->services = getServiceTemplates();
|
||||
$this->services = get_service_templates();
|
||||
}
|
||||
public function setService(string $selected) {
|
||||
$this->base64 = data_get($this->services, $selected . '.compose');
|
||||
|
@ -24,7 +24,7 @@ public function mount()
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.force-password-reset');
|
||||
return view('livewire.force-password-reset')->layout('layouts.simple');
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
namespace App\Livewire\Project\Database\Backup;
|
||||
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
use Livewire\Component;
|
||||
|
||||
class Execution extends Component
|
||||
{
|
||||
public $database;
|
||||
public $backup;
|
||||
public ?ScheduledDatabaseBackup $backup;
|
||||
public $executions;
|
||||
public $s3s;
|
||||
public function mount()
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
namespace App\Livewire\Project\Database;
|
||||
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
use Livewire\Component;
|
||||
use Spatie\Url\Url;
|
||||
|
||||
class BackupEdit extends Component
|
||||
{
|
||||
public $backup;
|
||||
public ?ScheduledDatabaseBackup $backup;
|
||||
public $s3s;
|
||||
public ?string $status = null;
|
||||
public array $parameters;
|
||||
@ -36,7 +37,7 @@ public function mount()
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
if (is_null(data_get($this->backup, 's3_storage_id'))) {
|
||||
$this->backup->s3_storage_id = 'default';
|
||||
data_set($this->backup, 's3_storage_id', 'default');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,12 @@
|
||||
|
||||
namespace App\Livewire\Project\Database;
|
||||
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
use Livewire\Component;
|
||||
|
||||
class BackupExecutions extends Component
|
||||
{
|
||||
public $backup;
|
||||
public ?ScheduledDatabaseBackup $backup = null;
|
||||
public $executions = [];
|
||||
public $setDeletableBackup;
|
||||
public function getListeners()
|
||||
@ -20,8 +21,11 @@ public function getListeners()
|
||||
|
||||
public function cleanupFailed()
|
||||
{
|
||||
$this->backup?->executions()->where('status', 'failed')->delete();
|
||||
$this->refreshBackupExecutions();
|
||||
if ($this->backup) {
|
||||
$this->backup->executions()->where('status', 'failed')->delete();
|
||||
$this->refreshBackupExecutions();
|
||||
$this->dispatch('success', 'Failed backups cleaned up.');
|
||||
}
|
||||
}
|
||||
public function deleteBackup($exeuctionId)
|
||||
{
|
||||
@ -45,6 +49,8 @@ public function download_file($exeuctionId)
|
||||
}
|
||||
public function refreshBackupExecutions(): void
|
||||
{
|
||||
$this->executions = $this->backup->executions()->get()->sortByDesc('created_at');
|
||||
if ($this->backup) {
|
||||
$this->executions = $this->backup->executions()->get()->sortByDesc('created_at');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Livewire\Project\Database;
|
||||
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Component;
|
||||
|
||||
class CreateScheduledBackup extends Component
|
||||
@ -12,7 +13,7 @@ class CreateScheduledBackup extends Component
|
||||
public bool $enabled = true;
|
||||
public bool $save_s3 = false;
|
||||
public $s3_storage_id;
|
||||
public $s3s;
|
||||
public Collection $s3s;
|
||||
|
||||
protected $rules = [
|
||||
'frequency' => 'required|string',
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Livewire\Project\Database;
|
||||
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
use Livewire\Component;
|
||||
|
||||
class ScheduledBackups extends Component
|
||||
@ -9,7 +10,7 @@ class ScheduledBackups extends Component
|
||||
public $database;
|
||||
public $parameters;
|
||||
public $type;
|
||||
public $selectedBackup;
|
||||
public ?ScheduledDatabaseBackup $selectedBackup;
|
||||
public $selectedBackupId;
|
||||
public $s3s;
|
||||
protected $listeners = ['refreshScheduledBackups'];
|
||||
|
@ -15,10 +15,10 @@ class Select extends Component
|
||||
public string $type;
|
||||
public string $server_id;
|
||||
public string $destination_uuid;
|
||||
public Countable|array|Server $allServers = [];
|
||||
public Countable|array|Server $servers = [];
|
||||
public Collection|array $standaloneDockers = [];
|
||||
public Collection|array $swarmDockers = [];
|
||||
public Collection|null|Server $allServers;
|
||||
public Collection|null|Server $servers;
|
||||
public ?Collection $standaloneDockers;
|
||||
public ?Collection $swarmDockers;
|
||||
public array $parameters;
|
||||
public Collection|array $services = [];
|
||||
public Collection|array $allServices = [];
|
||||
@ -91,7 +91,7 @@ public function loadServices(bool $force = false)
|
||||
});
|
||||
} else {
|
||||
$this->search = null;
|
||||
$this->allServices = getServiceTemplates();
|
||||
$this->allServices = get_service_templates();
|
||||
$this->services = $this->allServices->filter(function ($service, $key) {
|
||||
return str_contains(strtolower($key), strtolower($this->search));
|
||||
});
|
||||
@ -107,7 +107,11 @@ public function instantSave()
|
||||
if ($this->includeSwarm) {
|
||||
$this->servers = $this->allServers;
|
||||
} else {
|
||||
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false)->where('settings.is_build_server', false);
|
||||
if ($this->allServers instanceof Collection) {
|
||||
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false)->where('settings.is_build_server', false);
|
||||
} else {
|
||||
$this->servers = $this->allServers;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function setType(string $type)
|
||||
@ -126,13 +130,21 @@ public function setType(string $type)
|
||||
case 'mongodb':
|
||||
$this->isDatabase = true;
|
||||
$this->includeSwarm = false;
|
||||
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false)->where('settings.is_build_server', false);
|
||||
if ($this->allServers instanceof Collection) {
|
||||
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false)->where('settings.is_build_server', false);
|
||||
} else {
|
||||
$this->servers = $this->allServers;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (str($type)->startsWith('one-click-service') || str($type)->startsWith('docker-compose-empty')) {
|
||||
$this->isDatabase = true;
|
||||
$this->includeSwarm = false;
|
||||
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false)->where('settings.is_build_server', false);
|
||||
if ($this->allServers instanceof Collection) {
|
||||
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false)->where('settings.is_build_server', false);
|
||||
} else {
|
||||
$this->servers = $this->allServers;
|
||||
}
|
||||
}
|
||||
if ($type === "existing-postgresql") {
|
||||
$this->current_step = $type;
|
||||
|
@ -25,7 +25,7 @@ public function mount()
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
if (isset($type) && isset($destination_uuid) && isset($server_id)) {
|
||||
$services = getServiceTemplates();
|
||||
$services = get_service_templates();
|
||||
|
||||
if (in_array($type, DATABASE_TYPES)) {
|
||||
if ($type->value() === "postgresql") {
|
||||
|
@ -67,7 +67,6 @@ public function check_status()
|
||||
GetContainersStatus::run($this->service->server);
|
||||
// dispatch_sync(new ContainerStatusJob($this->service->server));
|
||||
$this->dispatch('refresh')->self();
|
||||
$this->dispatch('updateStatus');
|
||||
} catch (\Exception $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ public function getListeners()
|
||||
$userId = auth()->user()->id;
|
||||
return [
|
||||
"echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted',
|
||||
"updateStatus"=> '$refresh',
|
||||
];
|
||||
}
|
||||
public function serviceStarted()
|
||||
|
@ -24,6 +24,7 @@ public function mount()
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
// $this->authorize('delete', $this->resource);
|
||||
$this->resource->delete();
|
||||
DeleteResourceJob::dispatch($this->resource, $this->delete_configurations);
|
||||
return redirect()->route('project.resource.index', [
|
||||
|
@ -11,10 +11,12 @@ class Webhooks extends Component
|
||||
public ?string $githubManualWebhook = null;
|
||||
public ?string $gitlabManualWebhook = null;
|
||||
public ?string $bitbucketManualWebhook = null;
|
||||
public ?string $giteaManualWebhook = null;
|
||||
protected $rules = [
|
||||
'resource.manual_webhook_secret_github' => 'nullable|string',
|
||||
'resource.manual_webhook_secret_gitlab' => 'nullable|string',
|
||||
'resource.manual_webhook_secret_bitbucket' => 'nullable|string',
|
||||
'resource.manual_webhook_secret_gitea' => 'nullable|string',
|
||||
];
|
||||
public function saveSecret()
|
||||
{
|
||||
@ -32,6 +34,7 @@ public function mount()
|
||||
$this->githubManualWebhook = generateGitManualWebhook($this->resource, 'github');
|
||||
$this->gitlabManualWebhook = generateGitManualWebhook($this->resource, 'gitlab');
|
||||
$this->bitbucketManualWebhook = generateGitManualWebhook($this->resource, 'bitbucket');
|
||||
$this->giteaManualWebhook = generateGitManualWebhook($this->resource, 'gitea');
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
|
@ -58,6 +58,12 @@ public function serverInstalled()
|
||||
$this->server->refresh();
|
||||
$this->server->settings->refresh();
|
||||
}
|
||||
public function updatedServerSettingsIsBuildServer()
|
||||
{
|
||||
$this->dispatch('serverInstalled');
|
||||
$this->dispatch('serverRefresh');
|
||||
$this->dispatch('proxyStatusUpdated');
|
||||
}
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
|
@ -97,6 +97,9 @@ public function submit()
|
||||
if ($this->is_swarm_worker) {
|
||||
$payload['swarm_cluster'] = $this->selected_swarm_cluster;
|
||||
}
|
||||
if ($this->is_build_server) {
|
||||
data_forget($payload, 'proxy');
|
||||
}
|
||||
$server = Server::create($payload);
|
||||
if ($this->is_build_server) {
|
||||
$this->is_swarm_manager = false;
|
||||
|
@ -72,6 +72,8 @@ public function checkProxy()
|
||||
public function startProxy()
|
||||
{
|
||||
try {
|
||||
$this->server->proxy->force_stop = false;
|
||||
$this->server->save();
|
||||
$activity = StartProxy::run($this->server);
|
||||
$this->dispatch('activityMonitor', $activity->id, ProxyStatusChanged::class);
|
||||
} catch (\Throwable $e) {
|
||||
@ -86,17 +88,15 @@ public function stop()
|
||||
instant_remote_process([
|
||||
"docker service rm coolify-proxy_traefik",
|
||||
], $this->server);
|
||||
$this->server->proxy->status = 'exited';
|
||||
$this->server->save();
|
||||
$this->dispatch('proxyStatusUpdated');
|
||||
} else {
|
||||
instant_remote_process([
|
||||
"docker rm -f coolify-proxy",
|
||||
], $this->server);
|
||||
$this->server->proxy->status = 'exited';
|
||||
$this->server->save();
|
||||
$this->dispatch('proxyStatusUpdated');
|
||||
}
|
||||
$this->server->proxy->status = 'exited';
|
||||
$this->server->proxy->force_stop = true;
|
||||
$this->server->save();
|
||||
$this->dispatch('proxyStatusUpdated');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
@ -129,6 +129,9 @@ public function validateDockerVersion()
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->server->isBuildServer()) {
|
||||
return;
|
||||
}
|
||||
$this->dispatch('startProxy');
|
||||
}
|
||||
public function render()
|
||||
|
@ -36,7 +36,7 @@ class Backup extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->backup = $this->database?->scheduledBackups->first() ?? [];
|
||||
$this->backup = $this->database?->scheduledBackups->first() ?? null;
|
||||
$this->executions = $this->backup?->executions ?? [];
|
||||
}
|
||||
public function add_coolify_database()
|
||||
|
@ -10,6 +10,8 @@ class AdminView extends Component
|
||||
{
|
||||
public $users;
|
||||
public ?string $search = "";
|
||||
public bool $lots_of_users = false;
|
||||
private $number_of_users_to_show = 20;
|
||||
public function mount()
|
||||
{
|
||||
if (!isInstanceAdmin()) {
|
||||
@ -32,8 +34,14 @@ public function submitSearch()
|
||||
}
|
||||
public function getUsers()
|
||||
{
|
||||
$this->users = User::where('id', '!=', auth()->id())->get();
|
||||
// $this->users = User::all();
|
||||
$users = User::where('id', '!=', auth()->id())->get();
|
||||
if ($users->count() > $this->number_of_users_to_show) {
|
||||
$this->lots_of_users = true;
|
||||
$this->users = $users->take($this->number_of_users_to_show);
|
||||
} else {
|
||||
$this->lots_of_users = false;
|
||||
$this->users = $users;
|
||||
}
|
||||
}
|
||||
private function finalizeDeletion(User $user, Team $team)
|
||||
{
|
||||
@ -59,6 +67,9 @@ private function finalizeDeletion(User $user, Team $team)
|
||||
}
|
||||
public function delete($id)
|
||||
{
|
||||
if (!auth()->user()->isInstanceAdmin()) {
|
||||
return $this->dispatch('error', 'You are not authorized to delete users');
|
||||
}
|
||||
$user = User::find($id);
|
||||
$teams = $user->teams;
|
||||
foreach ($teams as $team) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
use Illuminate\Support\Str;
|
||||
use RuntimeException;
|
||||
use Spatie\Url\Url;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
@ -213,6 +214,13 @@ public function gitCommitLink($link): string
|
||||
$git_repository = str_replace(['git@', ':', '.git'], ['', '/', ''], $this->git_repository);
|
||||
return "https://{$git_repository}/commit/{$link}";
|
||||
}
|
||||
if (str($this->git_repository)->contains('bitbucket')) {
|
||||
$git_repository = str_replace('.git', '', $this->git_repository);
|
||||
$url = Url::fromString($git_repository);
|
||||
$url = $url->withUserInfo('');
|
||||
$url = $url->withPath($url->getPath() . '/commits/' . $link);
|
||||
return $url->__toString();
|
||||
}
|
||||
return $this->git_repository;
|
||||
}
|
||||
public function dockerfileLocation(): Attribute
|
||||
|
@ -525,7 +525,7 @@ public function isServerReady(int $tries = 3)
|
||||
// Reached max number of retries
|
||||
if ($this->unreachable_notification_sent === false) {
|
||||
ray('Server unreachable, sending notification...');
|
||||
$this->team?->notify(new Unreachable($this));
|
||||
// $this->team?->notify(new Unreachable($this));
|
||||
$this->update(['unreachable_notification_sent' => true]);
|
||||
}
|
||||
if ($this->settings->is_reachable === true) {
|
||||
@ -825,7 +825,7 @@ public function validateConnection()
|
||||
'unreachable_count' => 0,
|
||||
]);
|
||||
if (data_get($server, 'unreachable_notification_sent') === true) {
|
||||
$server->team?->notify(new Revived($server));
|
||||
// $server->team?->notify(new Revived($server));
|
||||
$server->update(['unreachable_notification_sent' => false]);
|
||||
}
|
||||
return ['uptime' => true, 'error' => null];
|
||||
@ -927,4 +927,7 @@ public function isNonRoot()
|
||||
}
|
||||
return $this->user !== 'root';
|
||||
}
|
||||
public function isBuildServer() {
|
||||
return $this->settings->is_build_server;
|
||||
}
|
||||
}
|
||||
|
@ -659,7 +659,7 @@ public function failedTaskLink($task_uuid)
|
||||
return route('project.service.scheduled-tasks', [
|
||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||
'environment_name' => data_get($this, 'environment.name'),
|
||||
'application_uuid' => data_get($this, 'uuid'),
|
||||
'service_uuid' => data_get($this, 'uuid'),
|
||||
'task_uuid' => $task_uuid
|
||||
]);
|
||||
}
|
||||
@ -667,7 +667,7 @@ public function failedTaskLink($task_uuid)
|
||||
}
|
||||
public function documentation()
|
||||
{
|
||||
$services = getServiceTemplates();
|
||||
$services = get_service_templates();
|
||||
$service = data_get($services, str($this->name)->beforeLast('-')->value, []);
|
||||
return data_get($service, 'documentation', config('constants.docs.base_url'));
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ public function type()
|
||||
{
|
||||
return 'service';
|
||||
}
|
||||
public function workdir() {
|
||||
return service_configuration_dir() . "/{$this->service->uuid}";
|
||||
}
|
||||
public function serviceType()
|
||||
{
|
||||
$found = str(collect(SPECIFIC_SERVICES)->filter(function ($service) {
|
||||
|
@ -59,6 +59,9 @@ public function getServiceDatabaseUrl()
|
||||
}
|
||||
return "{$realIp}:{$port}";
|
||||
}
|
||||
public function workdir() {
|
||||
return service_configuration_dir() . "/{$this->service->uuid}";
|
||||
}
|
||||
public function service()
|
||||
{
|
||||
return $this->belongsTo(Service::class);
|
||||
|
69
app/Policies/ApplicationPolicy.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class ApplicationPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Application $application): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Application $application): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Application $application): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Application $application): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Application $application): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
79
app/Policies/ServicePolicy.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Service;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class ServicePolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Service $service): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Service $service): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Service $service): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Service $service): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Service $service): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function stop(User $user, Service $service): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -43,16 +43,10 @@ function queue_application_deployment(Application $application, string $deployme
|
||||
]);
|
||||
|
||||
if ($no_questions_asked) {
|
||||
$deployment->update([
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
));
|
||||
} else if (next_queuable($server_id, $application_id)) {
|
||||
$deployment->update([
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
));
|
||||
|
@ -173,14 +173,14 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
|
||||
function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
{
|
||||
if ($resource->getMorphClass() === 'App\Models\ServiceApplication') {
|
||||
$uuid = $resource->uuid;
|
||||
$server = $resource->service->server;
|
||||
$environment_variables = $resource->service->environment_variables;
|
||||
$uuid = data_get($resource, 'uuid');
|
||||
$server = data_get($resource, 'service.server');
|
||||
$environment_variables = data_get($resource, 'service.environment_variables');
|
||||
$type = $resource->serviceType();
|
||||
} else if ($resource->getMorphClass() === 'App\Models\Application') {
|
||||
$uuid = $resource->uuid;
|
||||
$server = $resource->destination->server;
|
||||
$environment_variables = $resource->environment_variables;
|
||||
$uuid = data_get($resource, 'uuid');
|
||||
$server = data_get($resource, 'destination.server');
|
||||
$environment_variables = data_get($resource, 'environment_variables');
|
||||
$type = $resource->serviceType();
|
||||
}
|
||||
if (is_null($server) || is_null($type)) {
|
||||
@ -234,7 +234,7 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
}
|
||||
return $payload;
|
||||
}
|
||||
function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true, ?bool $is_stripprefix_enabled = true, ?string $service_name = null)
|
||||
function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true, ?bool $is_stripprefix_enabled = true, ?string $service_name = null, ?string $image = null)
|
||||
{
|
||||
$labels = collect([]);
|
||||
if ($serviceLabels) {
|
||||
@ -247,7 +247,6 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains,
|
||||
$url = Url::fromString($domain);
|
||||
$host = $url->getHost();
|
||||
$path = $url->getPath();
|
||||
// $stripped_path = str($path)->replaceEnd('/', '');
|
||||
|
||||
$schema = $url->getScheme();
|
||||
$port = $url->getPort();
|
||||
@ -273,7 +272,7 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains,
|
||||
}
|
||||
return $labels->sort();
|
||||
}
|
||||
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true, ?bool $is_stripprefix_enabled = true, ?string $service_name = null, bool $generate_unique_uuid = false)
|
||||
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true, ?bool $is_stripprefix_enabled = true, ?string $service_name = null, bool $generate_unique_uuid = false, ?string $image = null)
|
||||
{
|
||||
$labels = collect([]);
|
||||
$labels->push('traefik.enable=true');
|
||||
@ -331,7 +330,10 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$http_label = "http-{$loop}-{$uuid}-{$service_name}";
|
||||
$https_label = "https-{$loop}-{$uuid}-{$service_name}";
|
||||
}
|
||||
|
||||
if (str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.redir-ghost.redirectregex.regex=^{$path}/(.*)");
|
||||
$labels->push("traefik.http.middlewares.redir-ghost.redirectregex.replacement=/$1");
|
||||
}
|
||||
if ($schema === 'https') {
|
||||
// Set labels for https
|
||||
$labels->push("traefik.http.routers.{$https_label}.rule=Host(`{$host}`) && PathPrefix(`{$path}`)");
|
||||
@ -341,9 +343,10 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels->push("traefik.http.services.{$https_label}.loadbalancer.server.port=$port");
|
||||
}
|
||||
if ($path !== '/') {
|
||||
if ($is_stripprefix_enabled) {
|
||||
$middlewares = collect([]);
|
||||
if ($is_stripprefix_enabled && !str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||
$middlewares = collect(["{$https_label}-stripprefix"]);
|
||||
$middlewares->push("{$https_label}-stripprefix");
|
||||
}
|
||||
if ($is_gzip_enabled) {
|
||||
$middlewares->push('gzip');
|
||||
@ -354,6 +357,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
||||
@ -369,6 +375,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
||||
@ -396,9 +405,10 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels->push("traefik.http.routers.{$http_label}.service={$http_label}");
|
||||
}
|
||||
if ($path !== '/') {
|
||||
if ($is_stripprefix_enabled) {
|
||||
$middlewares = collect([]);
|
||||
if ($is_stripprefix_enabled && !str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||
$middlewares = collect(["{$http_label}-stripprefix"]);
|
||||
$middlewares->push("{$https_label}-stripprefix");
|
||||
}
|
||||
if ($is_gzip_enabled) {
|
||||
$middlewares->push('gzip');
|
||||
@ -409,6 +419,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
||||
@ -424,6 +437,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
||||
|
@ -110,16 +110,18 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($resourceFqdns);
|
||||
$port = $fqdn->getPort();
|
||||
$path = $fqdn->getPath();
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn;
|
||||
$generatedEnv->value = $fqdn . $path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
if ($port) {
|
||||
$variableName = $variableName . "_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
// ray($generatedEnv);
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn . ':' . $port;
|
||||
$generatedEnv->value = $fqdn . ':' . $port . $path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
@ -127,17 +129,18 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($fqdn);
|
||||
$port = $url->getPort();
|
||||
$path = $url->getPath();
|
||||
$url = $url->getHost();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($fqdn)->after('://');
|
||||
$generatedEnv->value = $url;
|
||||
$generatedEnv->value = $url . $path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
if ($port) {
|
||||
$variableName = $variableName . "_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $url . ':' . $port;
|
||||
$generatedEnv->value = $url . ':' . $port . $path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
@ -146,6 +149,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$host = Url::fromString($fqdn);
|
||||
$port = $host->getPort();
|
||||
$url = $host->getHost();
|
||||
$path = $host->getPath();
|
||||
$host = $host->getScheme() . '://' . $host->getHost();
|
||||
if ($port) {
|
||||
$port_envs = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_FQDN_%_$port")->get();
|
||||
@ -153,10 +157,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$service_fqdn = str($port_env->key)->beforeLast('_')->after('SERVICE_FQDN_');
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_FQDN_' . $service_fqdn)->first();
|
||||
if ($env) {
|
||||
$env->value = $host;
|
||||
$env->value = $host . $path;
|
||||
$env->save();
|
||||
}
|
||||
$port_env->value = $host . ':' . $port;
|
||||
$port_env->value = $host . ':' . $port . $path;
|
||||
$port_env->save();
|
||||
}
|
||||
$port_envs_url = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_URL_%_$port")->get();
|
||||
@ -164,17 +168,17 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$service_url = str($port_env_url->key)->beforeLast('_')->after('SERVICE_URL_');
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_URL_' . $service_url)->first();
|
||||
if ($env) {
|
||||
$env->value = $url;
|
||||
$env->value = $url . $path;
|
||||
$env->save();
|
||||
}
|
||||
$port_env_url->value = $url . ':' . $port;
|
||||
$port_env_url->value = $url . ':' . $port . $path;
|
||||
$port_env_url->save();
|
||||
}
|
||||
} else {
|
||||
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($fqdn);
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost();
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost() . $fqdn->getPath();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn;
|
||||
$generatedEnv->save();
|
||||
@ -182,7 +186,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($fqdn);
|
||||
$url = $url->getHost();
|
||||
$url = $url->getHost() . $url->getPath();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($fqdn)->after('://');
|
||||
$generatedEnv->value = $url;
|
||||
|
@ -165,9 +165,12 @@ function get_latest_sentinel_version(): string
|
||||
function get_latest_version_of_coolify(): string
|
||||
{
|
||||
try {
|
||||
$response = Http::get('https://cdn.coollabs.io/coolify/versions.json');
|
||||
$versions = $response->json();
|
||||
$versions = File::get(base_path('versions.json'));
|
||||
$versions = json_decode($versions, true);
|
||||
return data_get($versions, 'coolify.v4.version');
|
||||
// $response = Http::get('https://cdn.coollabs.io/coolify/versions.json');
|
||||
// $versions = $response->json();
|
||||
// return data_get($versions, 'coolify.v4.version');
|
||||
} catch (\Throwable $e) {
|
||||
//throw $e;
|
||||
ray($e->getMessage());
|
||||
@ -462,24 +465,25 @@ function sslip(Server $server)
|
||||
return "http://{$server->ip}.sslip.io";
|
||||
}
|
||||
|
||||
function getServiceTemplates()
|
||||
function get_service_templates()
|
||||
{
|
||||
if (isDev()) {
|
||||
$services = File::get(base_path('templates/service-templates.json'));
|
||||
$services = collect(json_decode($services))->sortKeys();
|
||||
} else {
|
||||
try {
|
||||
$response = Http::retry(3, 50)->get(config('constants.services.official'));
|
||||
if ($response->failed()) {
|
||||
return collect([]);
|
||||
}
|
||||
$services = $response->json();
|
||||
$services = collect($services)->sortKeys();
|
||||
} catch (\Throwable $e) {
|
||||
$services = collect([]);
|
||||
}
|
||||
}
|
||||
return $services;
|
||||
// if (isDev()) {
|
||||
// $services = File::get(base_path('templates/service-templates.json'));
|
||||
// $services = collect(json_decode($services))->sortKeys();
|
||||
// } else {
|
||||
// try {
|
||||
// $response = Http::retry(3, 50)->get(config('constants.services.official'));
|
||||
// if ($response->failed()) {
|
||||
// return collect([]);
|
||||
// }
|
||||
// $services = $response->json();
|
||||
// $services = collect($services)->sortKeys();
|
||||
// } catch (\Throwable $e) {
|
||||
// $services = collect([]);
|
||||
// }
|
||||
// }
|
||||
$services = File::get(base_path('templates/service-templates.json'));
|
||||
return collect(json_decode($services))->sortKeys();
|
||||
}
|
||||
|
||||
function getResourceByUuid(string $uuid, ?int $teamId = null)
|
||||
@ -649,7 +653,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
$allServices = getServiceTemplates();
|
||||
$allServices = get_service_templates();
|
||||
$topLevelVolumes = collect(data_get($yaml, 'volumes', []));
|
||||
$topLevelNetworks = collect(data_get($yaml, 'networks', []));
|
||||
$services = data_get($yaml, 'services');
|
||||
@ -1007,7 +1011,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
'service_id' => $resource->id,
|
||||
])->first();
|
||||
if ($env) {
|
||||
|
||||
$env_url = Url::fromString($savedService->fqdn);
|
||||
$env_port = $env_url->getPort();
|
||||
if ($env_port !== $predefinedPort) {
|
||||
@ -1049,6 +1052,17 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
}
|
||||
if ($foundEnv) {
|
||||
$fqdn = data_get($foundEnv, 'value');
|
||||
// if ($savedService->fqdn) {
|
||||
// $savedServiceFqdn = Url::fromString($savedService->fqdn);
|
||||
// $parsedFqdn = Url::fromString($fqdn);
|
||||
// $savedServicePath = $savedServiceFqdn->getPath();
|
||||
// $parsedFqdnPath = $parsedFqdn->getPath();
|
||||
// if ($savedServicePath != $parsedFqdnPath) {
|
||||
// $fqdn = $parsedFqdn->withPath($savedServicePath)->__toString();
|
||||
// $foundEnv->value = $fqdn;
|
||||
// $foundEnv->save();
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
if ($command->value() === 'URL') {
|
||||
$fqdn = Str::of($fqdn)->after('://')->value();
|
||||
@ -1153,7 +1167,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
serviceLabels: $serviceLabels,
|
||||
is_gzip_enabled: $savedService->isGzipEnabled(),
|
||||
is_stripprefix_enabled: $savedService->isStripprefixEnabled(),
|
||||
service_name: $serviceName
|
||||
service_name: $serviceName,
|
||||
image: data_get($service, 'image')
|
||||
));
|
||||
$serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy(
|
||||
network: $resource->destination->network,
|
||||
@ -1163,7 +1178,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
serviceLabels: $serviceLabels,
|
||||
is_gzip_enabled: $savedService->isGzipEnabled(),
|
||||
is_stripprefix_enabled: $savedService->isStripprefixEnabled(),
|
||||
service_name: $serviceName
|
||||
service_name: $serviceName,
|
||||
image: data_get($service, 'image')
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1189,13 +1205,14 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
if (!data_get($service, 'restart')) {
|
||||
data_set($service, 'restart', RESTART_MODE);
|
||||
}
|
||||
if (data_get($service, 'restart') === 'no') {
|
||||
if (data_get($service, 'restart') === 'no' || data_get($service, 'exclude_from_hc')) {
|
||||
$savedService->update(['exclude_from_status' => true]);
|
||||
}
|
||||
data_set($service, 'container_name', $containerName);
|
||||
data_forget($service, 'volumes.*.content');
|
||||
data_forget($service, 'volumes.*.isDirectory');
|
||||
data_forget($service, 'volumes.*.is_directory');
|
||||
data_forget($service, 'exclude_from_hc');
|
||||
|
||||
// Remove unnecessary variables from service.environment
|
||||
// $withoutServiceEnvs = collect([]);
|
||||
@ -1217,6 +1234,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
'volumes' => $topLevelVolumes->toArray(),
|
||||
'networks' => $topLevelNetworks->toArray(),
|
||||
];
|
||||
$yaml = data_forget($yaml, 'services.*.volumes.*.content');
|
||||
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
||||
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
||||
$resource->save();
|
||||
@ -1642,13 +1660,15 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
uuid: $resource->uuid,
|
||||
domains: $fqdns,
|
||||
serviceLabels: $serviceLabels,
|
||||
generate_unique_uuid: $resource->build_pack === 'dockercompose'
|
||||
generate_unique_uuid: $resource->build_pack === 'dockercompose',
|
||||
image: data_get($service, 'image')
|
||||
));
|
||||
$serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy(
|
||||
network: $resource->destination->network,
|
||||
uuid: $resource->uuid,
|
||||
domains: $fqdns,
|
||||
serviceLabels: $serviceLabels
|
||||
serviceLabels: $serviceLabels,
|
||||
image: data_get($service, 'image')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
"guzzlehttp/guzzle": "^7.5.0",
|
||||
"laravel/fortify": "^v1.16.0",
|
||||
"laravel/framework": "^v10.7.1",
|
||||
"laravel/horizon": "^5.15",
|
||||
"laravel/horizon": "^5.23.1",
|
||||
"laravel/prompts": "^0.1.6",
|
||||
"laravel/sanctum": "^v3.2.1",
|
||||
"laravel/socialite": "^5.12",
|
||||
@ -23,7 +23,7 @@
|
||||
"lcobucci/jwt": "^5.0.0",
|
||||
"league/flysystem-aws-s3-v3": "^3.0",
|
||||
"league/flysystem-sftp-v3": "^3.0",
|
||||
"livewire/livewire": "^3.0",
|
||||
"livewire/livewire": "3.4.9",
|
||||
"lorisleiva/laravel-actions": "^2.7",
|
||||
"nubs/random-name-generator": "^2.2",
|
||||
"phpseclib/phpseclib": "~3.0",
|
||||
|
@ -21,8 +21,8 @@
|
||||
],
|
||||
'services' => [
|
||||
// Temporary disabled until cache is implemented
|
||||
// 'official' => 'https://cdn.coollabs.io/coolify/service-templates.json',
|
||||
'official' => 'https://raw.githubusercontent.com/coollabsio/coolify/main/templates/service-templates.json',
|
||||
'official' => 'https://cdn.coollabs.io/coolify/service-templates.json',
|
||||
// 'official' => 'https://raw.githubusercontent.com/coollabsio/coolify/main/templates/service-templates.json',
|
||||
],
|
||||
'limits' => [
|
||||
'trial_period' => 0,
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
// The release version of your application
|
||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||
'release' => '4.0.0-beta.285',
|
||||
'release' => '4.0.0-beta.286',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.285';
|
||||
return '4.0.0-beta.286';
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?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('applications', function (Blueprint $table) {
|
||||
$table->text('post_deployment_command')->nullable()->change();
|
||||
$table->text('pre_deployment_command')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->string('post_deployment_command')->nullable()->change();
|
||||
$table->string('pre_deployment_command')->nullable()->change();
|
||||
});
|
||||
}
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
<?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('applications', function (Blueprint $table) {
|
||||
$table->string('manual_webhook_secret_gitea')->nullable();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->dropColumn('manual_webhook_secret_gitea');
|
||||
});
|
||||
}
|
||||
};
|
215
package-lock.json
generated
@ -6,22 +6,22 @@
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "0.5.7",
|
||||
"@tailwindcss/typography": "0.5.12",
|
||||
"alpinejs": "3.13.8",
|
||||
"ioredis": "5.3.2",
|
||||
"@tailwindcss/typography": "0.5.13",
|
||||
"alpinejs": "3.14.0",
|
||||
"ioredis": "5.4.1",
|
||||
"tailwindcss-scrollbar": "0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "4.5.1",
|
||||
"autoprefixer": "10.4.19",
|
||||
"axios": "1.6.8",
|
||||
"laravel-echo": "1.16.0",
|
||||
"axios": "1.7.2",
|
||||
"laravel-echo": "1.16.1",
|
||||
"laravel-vite-plugin": "0.8.1",
|
||||
"postcss": "8.4.38",
|
||||
"pusher-js": "8.4.0-rc2",
|
||||
"tailwindcss": "3.4.3",
|
||||
"vite": "4.5.3",
|
||||
"vue": "3.4.21"
|
||||
"vue": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
@ -36,9 +36,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
|
||||
"integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
|
||||
"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@ -496,9 +496,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.12.tgz",
|
||||
"integrity": "sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==",
|
||||
"version": "0.5.13",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz",
|
||||
"integrity": "sha512-ADGcJ8dX21dVVHIwTRgzrcunY6YY9uSlAHHGVKvkA+vLc5qLwEszvKts40lx7z0qc4clpjclwLeK5rVCV2P/uw==",
|
||||
"dependencies": {
|
||||
"lodash.castarray": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
@ -535,77 +535,77 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
|
||||
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
|
||||
"integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@vue/shared": "3.4.21",
|
||||
"@babel/parser": "^7.24.4",
|
||||
"@vue/shared": "3.4.27",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
"source-map-js": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
|
||||
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
|
||||
"integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.4.21",
|
||||
"@vue/shared": "3.4.21"
|
||||
"@vue/compiler-core": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-dom/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
|
||||
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
|
||||
"integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@vue/compiler-core": "3.4.21",
|
||||
"@vue/compiler-dom": "3.4.21",
|
||||
"@vue/compiler-ssr": "3.4.21",
|
||||
"@vue/shared": "3.4.21",
|
||||
"@babel/parser": "^7.24.4",
|
||||
"@vue/compiler-core": "3.4.27",
|
||||
"@vue/compiler-dom": "3.4.27",
|
||||
"@vue/compiler-ssr": "3.4.27",
|
||||
"@vue/shared": "3.4.27",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.7",
|
||||
"postcss": "^8.4.35",
|
||||
"source-map-js": "^1.0.2"
|
||||
"magic-string": "^0.30.10",
|
||||
"postcss": "^8.4.38",
|
||||
"source-map-js": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
|
||||
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
|
||||
"integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.4.21",
|
||||
"@vue/shared": "3.4.21"
|
||||
"@vue/compiler-dom": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
@ -617,64 +617,64 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
|
||||
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
|
||||
"integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.4.21",
|
||||
"@vue/shared": "3.4.21"
|
||||
"@vue/reactivity": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core/node_modules/@vue/reactivity": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
|
||||
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz",
|
||||
"integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.4.21"
|
||||
"@vue/shared": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/runtime-dom": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
|
||||
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
|
||||
"integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/runtime-core": "3.4.21",
|
||||
"@vue/shared": "3.4.21",
|
||||
"@vue/runtime-core": "3.4.27",
|
||||
"@vue/shared": "3.4.27",
|
||||
"csstype": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/server-renderer": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
|
||||
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
|
||||
"integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.4.21",
|
||||
"@vue/shared": "3.4.21"
|
||||
"@vue/compiler-ssr": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.4.21"
|
||||
"vue": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
@ -683,9 +683,9 @@
|
||||
"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA=="
|
||||
},
|
||||
"node_modules/alpinejs": {
|
||||
"version": "3.13.8",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.8.tgz",
|
||||
"integrity": "sha512-XolbBJryCndomtaHd/KHQjQeD/L72FJxy/YhLLFD4Lr7zzGcpcbg+UgXteMR2pYg1KhRUr6V4O3GfN1zJAmRWw==",
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.0.tgz",
|
||||
"integrity": "sha512-YCWF95PMJqePe9ll6KMyDt/nLhh2R7RhqBf4loEmLzIskcHque4Br/9UgAa6cw13H0Cm3FM9e1hzDwP5z5wlDA==",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "~3.1.1"
|
||||
}
|
||||
@ -756,9 +756,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
|
||||
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@ -1238,9 +1238,9 @@
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/ioredis": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz",
|
||||
"integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==",
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz",
|
||||
"integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==",
|
||||
"dependencies": {
|
||||
"@ioredis/commands": "^1.1.1",
|
||||
"cluster-key-slot": "^1.1.0",
|
||||
@ -1318,9 +1318,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/laravel-echo": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.16.0.tgz",
|
||||
"integrity": "sha512-BJGUa4tcKvYmTkzTmcBGMHiO2tq+k7Do5wPmLbRswWfzKwyfZEUR+J5iwBTPEfLLwNPZlA9Kjo6R/NV6pmyIpg==",
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.16.1.tgz",
|
||||
"integrity": "sha512-++Ylb6M3ariC9Rk5WE5gZjj6wcEV5kvLF8b+geJ5/rRIfdoOA+eG6b9qJPrarMD9rY28Apx+l3eelIrCc2skVg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@ -1381,15 +1381,12 @@
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.8",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
|
||||
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
|
||||
"version": "0.30.10",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
|
||||
"integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
@ -2085,16 +2082,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
|
||||
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz",
|
||||
"integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.4.21",
|
||||
"@vue/compiler-sfc": "3.4.21",
|
||||
"@vue/runtime-dom": "3.4.21",
|
||||
"@vue/server-renderer": "3.4.21",
|
||||
"@vue/shared": "3.4.21"
|
||||
"@vue/compiler-dom": "3.4.27",
|
||||
"@vue/compiler-sfc": "3.4.27",
|
||||
"@vue/runtime-dom": "3.4.27",
|
||||
"@vue/server-renderer": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
@ -2106,9 +2103,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/shared": {
|
||||
"version": "3.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
|
12
package.json
@ -8,20 +8,20 @@
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "4.5.1",
|
||||
"autoprefixer": "10.4.19",
|
||||
"axios": "1.6.8",
|
||||
"laravel-echo": "1.16.0",
|
||||
"axios": "1.7.2",
|
||||
"laravel-echo": "1.16.1",
|
||||
"laravel-vite-plugin": "0.8.1",
|
||||
"postcss": "8.4.38",
|
||||
"pusher-js": "8.4.0-rc2",
|
||||
"tailwindcss": "3.4.3",
|
||||
"vite": "4.5.3",
|
||||
"vue": "3.4.21"
|
||||
"vue": "3.4.27"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "0.5.7",
|
||||
"@tailwindcss/typography": "0.5.12",
|
||||
"alpinejs": "3.13.8",
|
||||
"ioredis": "5.3.2",
|
||||
"@tailwindcss/typography": "0.5.13",
|
||||
"alpinejs": "3.14.0",
|
||||
"ioredis": "5.4.1",
|
||||
"tailwindcss-scrollbar": "0.1.0"
|
||||
}
|
||||
}
|
||||
|
10
public/svgs/chatwoot.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg viewBox="0 0 550 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="on_white" fill-rule="nonzero">
|
||||
<g id="woot-log">
|
||||
<circle id="Oval" fill="#47A7F6" cx="256" cy="256" r="256"></circle>
|
||||
<path d="M362.807947,368.807947 L244.122956,368.807947 C178.699407,368.807947 125.456954,315.561812 125.456954,250.12177 C125.456954,184.703089 178.699407,131.456954 244.124143,131.456954 C309.565494,131.456954 362.807947,184.703089 362.807947,250.12177 L362.807947,368.807947 Z" id="Fill-1" stroke="#FFFFFF" stroke-width="6" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 773 B |
BIN
public/svgs/docuseal.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
public/svgs/glance.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/svgs/mediawiki.ico
Normal file
After Width: | Height: | Size: 15 KiB |
8
public/vendor/horizon/app-dark.css
vendored
8
public/vendor/horizon/app.css
vendored
2
public/vendor/horizon/app.js
vendored
BIN
public/vendor/horizon/img/favicon.png
vendored
Before Width: | Height: | Size: 648 B |
4
public/vendor/horizon/img/horizon.svg
vendored
@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="226" height="30" viewBox="0 0 226 30">
|
||||
<path fill="#405263" d="M54.132 25l-.644-4.144h-5.936V5.68h-4.788V25h11.368zm13.3 0H63.68l-.28-1.708c-1.12 1.176-2.436 1.988-4.312 1.988-2.184 0-3.724-1.316-3.724-3.808 0-3.22 2.464-4.732 7.84-5.208v-.252c0-1.204-.672-1.736-2.072-1.736-1.54 0-2.968.392-4.424 1.036l-.504-3.192c1.568-.644 3.332-1.064 5.572-1.064 3.78 0 5.656 1.26 5.656 4.76V25zm-4.228-3.78v-2.912c-2.884.448-3.668 1.4-3.668 2.604 0 .868.532 1.344 1.316 1.344.812 0 1.596-.364 2.352-1.036zm15.876-5.908L78.38 11c-2.016.14-3.164 1.428-4.004 2.996l-.448-2.716h-3.696V25h4.228v-7.616c1.036-1.12 2.576-1.932 4.62-2.072zM92.184 25h-3.752l-.28-1.708c-1.12 1.176-2.436 1.988-4.312 1.988-2.184 0-3.724-1.316-3.724-3.808 0-3.22 2.464-4.732 7.84-5.208v-.252c0-1.204-.672-1.736-2.072-1.736-1.54 0-2.968.392-4.424 1.036l-.504-3.192c1.568-.644 3.332-1.064 5.572-1.064 3.78 0 5.656 1.26 5.656 4.76V25zm-4.228-3.78v-2.912c-2.884.448-3.668 1.4-3.668 2.604 0 .868.532 1.344 1.316 1.344.812 0 1.596-.364 2.352-1.036zm19.544-9.94h-4.116l-2.492 8.484-2.548-8.68-4.536.532 4.676 13.44h4.228L107.5 11.28zm13.552 6.832c0 .42-.028.868-.084 1.092h-8.232c.224 2.156 1.512 2.996 3.36 2.996 1.512 0 2.996-.56 4.508-1.428l.42 2.968c-1.484.952-3.304 1.54-5.46 1.54-4.116 0-7.056-2.184-7.056-7.084 0-4.48 2.744-7.196 6.468-7.196 4.2 0 6.076 3.136 6.076 7.112zm-4.032-1.232c-.14-2.072-.868-3.136-2.156-3.136-1.176 0-2.016 1.036-2.156 3.136h4.312zM127.66 25V4.784l-4.256.672V25h4.256zm25.032 0V5.68h-1.932v8.344h-10.724V5.68h-1.932V25h1.932v-9.24h10.724V25h1.932zm15.876-6.608c0 4.368-2.632 6.888-6.02 6.888-3.388 0-5.936-2.52-5.936-6.888 0-4.396 2.604-6.916 5.936-6.916 3.444 0 6.02 2.52 6.02 6.916zm-1.904 0c0-3.052-1.456-5.348-4.116-5.348-2.632 0-4.06 2.212-4.06 5.348 0 3.052 1.456 5.32 4.06 5.32 2.688 0 4.116-2.184 4.116-5.32zm12.208-5.18l-.308-1.736c-2.184.056-3.724 1.512-4.704 2.996l-.42-2.716h-1.372V25h1.848v-8.316c.896-1.764 2.772-3.332 4.956-3.472zm5.264-5.964c0-.728-.588-1.344-1.316-1.344-.728 0-1.344.616-1.344 1.344 0 .728.616 1.344 1.344 1.344.728 0 1.316-.616 1.316-1.344zM183.716 25V11.756h-1.82V25h1.82zm13.748 0l-.252-1.54h-7.868l7.896-10.276v-1.428h-9.604l.252 1.54h7.224l-7.896 10.276V25h10.248zm14.476-6.608c0 4.368-2.632 6.888-6.02 6.888-3.388 0-5.936-2.52-5.936-6.888 0-4.396 2.604-6.916 5.936-6.916 3.444 0 6.02 2.52 6.02 6.916zm-1.904 0c0-3.052-1.456-5.348-4.116-5.348-2.632 0-4.06 2.212-4.06 5.348 0 3.052 1.456 5.32 4.06 5.32 2.688 0 4.116-2.184 4.116-5.32zM225.884 25v-9.464c0-2.548-1.316-4.06-3.948-4.06-1.792 0-3.304.952-4.76 2.24l-.308-1.96h-1.428V25h1.848v-9.576c1.456-1.428 2.884-2.296 4.284-2.296 1.68 0 2.464 1.036 2.464 2.744V25h1.848z"/>
|
||||
<path fill="#405263" d="M5.26176342 26.4094389C2.04147988 23.6582233 0 19.5675182 0 15c0-4.1421356 1.67893219-7.89213562 4.39339828-10.60660172C7.10786438 1.67893219 10.8578644 0 15 0c8.2842712 0 15 6.71572875 15 15 0 8.2842712-6.7157288 15-15 15-3.716753 0-7.11777662-1.3517984-9.73823658-3.5905611zM4.03811305 15.9222506C5.70084247 14.4569342 6.87195416 12.5 10 12.5c5 0 5 5 10 5 3.1280454 0 4.2991572-1.9569336 5.961887-3.4222502C25.4934253 8.43417206 20.7645408 4 15 4 8.92486775 4 4 8.92486775 4 15c0 .3105915.01287248.6181765.03811305.9222506z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.2 KiB |
806
public/vendor/horizon/img/sprite.svg
vendored
@ -1,806 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-add-outline">
|
||||
<path d="M11 9h4v2h-4v4H9v-4H5V9h4V5h2v4zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-add-solid">
|
||||
<path d="M11 9V5H9v4H5v2h4v4h2v-4h4V9h-4zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-adjust">
|
||||
<path d="M10 2v16a8 8 0 1 0 0-16zm0 18a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-airplane">
|
||||
<path d="M8.4 12H2.8L1 15H0V5h1l1.8 3h5.6L6 0h2l4.8 8H18a2 2 0 1 1 0 4h-5.2L8 20H6l2.4-8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-align-center">
|
||||
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM4 5h12v2H4V5zm0 8h12v2H4v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-align-justified">
|
||||
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM1 5h18v2H1V5zm0 8h18v2H1v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-align-left">
|
||||
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM1 5h12v2H1V5zm0 8h12v2H1v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-align-right">
|
||||
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-anchor">
|
||||
<path d="M4.34 15.66A7.97 7.97 0 0 0 9 17.94V10H5V8h4V5.83a3 3 0 1 1 2 0V8h4v2h-4v7.94a7.97 7.97 0 0 0 4.66-2.28l-1.42-1.42h5.66l-2.83 2.83a10 10 0 0 1-14.14 0L.1 14.24h5.66l-1.42 1.42zM10 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-announcement">
|
||||
<path d="M3 6c0-1.1.9-2 2-2h8l4-4h2v16h-2l-4-4H5a2 2 0 0 1-2-2H1V6h2zm8 9v5H8l-1.67-5H5v-2h8v2h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-apparel">
|
||||
<path d="M7 0H6L0 3v6l4-1v12h12V8l4 1V3l-6-3h-1a3 3 0 0 1-6 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-down">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-2-8V5h4v5h3l-5 5-5-5h3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-left">
|
||||
<path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm2 0a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm8-2h5v4h-5v3l-5-5 5-5v3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-right">
|
||||
<path d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0zm-2 0a8 8 0 1 0-16 0 8 8 0 0 0 16 0zm-8 2H5V8h5V5l5 5-5 5v-3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-up">
|
||||
<path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm2 8v5H8v-5H5l5-5 5 5h-3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-down">
|
||||
<path d="M7 10V2h6v8h5l-8 8-8-8h5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-left">
|
||||
<path d="M10 13h8V7h-8V2l-8 8 8 8v-5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-right">
|
||||
<path d="M10 7H2v6h8v5l8-8-8-8v5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-up">
|
||||
<path d="M7 10v8h6v-8h5l-8-8-8 8h5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-down">
|
||||
<path d="M9 16.172l-6.071-6.071-1.414 1.414L10 20l.707-.707 7.778-7.778-1.414-1.414L11 16.172V0H9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-left">
|
||||
<path d="M3.828 9l6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9H3.828z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-right">
|
||||
<path d="M16.172 9l-6.071-6.071 1.414-1.414L20 10l-.707.707-7.778 7.778-1.414-1.414L16.172 11H0V9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-up">
|
||||
<path d="M9 3.828L2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9V3.828z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-at-symbol">
|
||||
<path d="M13.6 13.47A4.99 4.99 0 0 1 5 10a5 5 0 0 1 8-4V5h2v6.5a1.5 1.5 0 0 0 3 0V10a8 8 0 1 0-4.42 7.16l.9 1.79A10 10 0 1 1 20 10h-.18.17v1.5a3.5 3.5 0 0 1-6.4 1.97zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-attachment">
|
||||
<path d="M15 3H7a7 7 0 1 0 0 14h8v-2H7A5 5 0 0 1 7 5h8a3 3 0 0 1 0 6H7a1 1 0 0 1 0-2h8V7H7a3 3 0 1 0 0 6h8a5 5 0 0 0 0-10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-backspace">
|
||||
<path d="M0 10l7-7h13v14H7l-7-7zm14.41 0l2.13-2.12-1.42-1.42L13 8.6l-2.12-2.13-1.42 1.42L11.6 10l-2.13 2.12 1.42 1.42L13 11.4l2.12 2.13 1.42-1.42L14.4 10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-badge">
|
||||
<path d="M10 12a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-3a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm4 2.75V20l-4-4-4 4v-8.25a6.97 6.97 0 0 0 8 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-battery-full">
|
||||
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7zm5 0h4v6H8V7zm5 0h4v6h-4V7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-battery-half">
|
||||
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7zm5 0h4v6H8V7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-battery-low">
|
||||
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-beverage">
|
||||
<path d="M9 18v-7L0 2V0h20v2l-9 9v7l5 1v1H4v-1l5-1zm2-10a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-block">
|
||||
<path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm16.32-4.9L5.09 16.31A8 8 0 0 0 16.32 5.09zm-1.41-1.42A8 8 0 0 0 3.68 14.91L14.91 3.68z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-bluetooth">
|
||||
<path d="M9.41 0l6 6-4 4 4 4-6 6H9v-7.59l-3.3 3.3-1.4-1.42L8.58 10l-4.3-4.3L5.7 4.3 9 7.58V0h.41zM11 4.41V7.6L12.59 6 11 4.41zM12.59 14L11 12.41v3.18L12.59 14z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-bolt">
|
||||
<path d="M13 8V0L8.11 5.87 3 12h4v8L17 8h-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-book-reference">
|
||||
<path d="M6 4H5a1 1 0 1 1 0-2h11V1a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V5a1 1 0 0 0-1-1h-7v8l-2-2-2 2V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-bookmark">
|
||||
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-bookmark-outline">
|
||||
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2zm2 0v15l6-3 6 3V2H4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-bookmark-outline-add">
|
||||
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2zm2 0v15l6-3 6 3V2H4zm5 5V5h2v2h2v2h-2v2H9V9H7V7h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-all">
|
||||
<path d="M11 11v6h6v-6h-6zm0-2h6V3h-6v6zm-2 2H3v6h6v-6zm0-2V3H3v6h6zm-8 9V1h18v18H1v-1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-bottom">
|
||||
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h18v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm4-8h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm4-12h2v2h-2V1zm0 8h2v2h-2V9zm4-8h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-horizontal">
|
||||
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h18v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 16h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 8h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 16h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 8h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-inner">
|
||||
<path d="M9 9V1h2v8h8v2h-8v8H9v-8H1V9h8zM1 1h2v2H1V1zm0 4h2v2H1V5zm0 8h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 16h2v2H5v-2zm8-16h2v2h-2V1zm0 16h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 8h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-left">
|
||||
<path d="M1 1h2v18H1V1zm4 0h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-none">
|
||||
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-outer">
|
||||
<path d="M2 19H1V1h18v18H2zm1-2h14V3H3v14zm10-8h2v2h-2V9zM9 9h2v2H9V9zM5 9h2v2H5V9zm4-4h2v2H9V5zm0 8h2v2H9v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-right">
|
||||
<path d="M5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zM1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM17 1h2v18h-2V1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-top">
|
||||
<path d="M1 1h18v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zm4-8h2v2H5V9zm0 8h2v2H5v-2zM9 5h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-8h2v2h-2V9zm0 8h2v2h-2v-2zm4-12h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-border-vertical">
|
||||
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v18H9V1zm4 0h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-box">
|
||||
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v2H0V2zm1 3h18v13a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5zm6 2v2h6V7H7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-brightness-down">
|
||||
<path d="M10 13a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM9 4a1 1 0 1 1 2 0 1 1 0 1 1-2 0zm4.54 1.05a1 1 0 1 1 1.41 1.41 1 1 0 1 1-1.41-1.41zM16 9a1 1 0 1 1 0 2 1 1 0 1 1 0-2zm-1.05 4.54a1 1 0 1 1-1.41 1.41 1 1 0 1 1 1.41-1.41zM11 16a1 1 0 1 1-2 0 1 1 0 1 1 2 0zm-4.54-1.05a1 1 0 1 1-1.41-1.41 1 1 0 1 1 1.41 1.41zM4 11a1 1 0 1 1 0-2 1 1 0 1 1 0 2zm1.05-4.54a1 1 0 1 1 1.41-1.41 1 1 0 1 1-1.41 1.41z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-brightness-up">
|
||||
<path d="M10 14a4 4 0 1 1 0-8 4 4 0 0 1 0 8zM9 1a1 1 0 1 1 2 0v2a1 1 0 1 1-2 0V1zm6.65 1.94a1 1 0 1 1 1.41 1.41l-1.4 1.4a1 1 0 1 1-1.41-1.41l1.4-1.4zM18.99 9a1 1 0 1 1 0 2h-1.98a1 1 0 1 1 0-2h1.98zm-1.93 6.65a1 1 0 1 1-1.41 1.41l-1.4-1.4a1 1 0 1 1 1.41-1.41l1.4 1.4zM11 18.99a1 1 0 1 1-2 0v-1.98a1 1 0 1 1 2 0v1.98zm-6.65-1.93a1 1 0 1 1-1.41-1.41l1.4-1.4a1 1 0 1 1 1.41 1.41l-1.4 1.4zM1.01 11a1 1 0 1 1 0-2h1.98a1 1 0 1 1 0 2H1.01zm1.93-6.65a1 1 0 1 1 1.41-1.41l1.4 1.4a1 1 0 1 1-1.41 1.41l-1.4-1.4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-browser-window">
|
||||
<path d="M0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm2 2v12h16V5H2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-browser-window-new">
|
||||
<path d="M9 10V8h2v2h2v2h-2v2H9v-2H7v-2h2zM0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm2 2v12h16V5H2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-browser-window-open">
|
||||
<path d="M0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm2 2v12h16V5H2zm8 3l4 5H6l4-5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-bug">
|
||||
<path d="M15.3 14.89l2.77 2.77a1 1 0 0 1 0 1.41 1 1 0 0 1-1.41 0l-2.59-2.58A5.99 5.99 0 0 1 11 18V9.04a1 1 0 0 0-2 0V18a5.98 5.98 0 0 1-3.07-1.51l-2.59 2.58a1 1 0 0 1-1.41 0 1 1 0 0 1 0-1.41l2.77-2.77A5.95 5.95 0 0 1 4.07 13H1a1 1 0 1 1 0-2h3V8.41L.93 5.34a1 1 0 0 1 0-1.41 1 1 0 0 1 1.41 0l2.1 2.1h11.12l2.1-2.1a1 1 0 0 1 1.41 0 1 1 0 0 1 0 1.41L16 8.41V11h3a1 1 0 1 1 0 2h-3.07c-.1.67-.32 1.31-.63 1.89zM15 5H5a5 5 0 1 1 10 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-buoy">
|
||||
<path d="M17.16 6.42a8.03 8.03 0 0 0-3.58-3.58l-1.34 2.69a5.02 5.02 0 0 1 2.23 2.23l2.69-1.34zm0 7.16l-2.69-1.34a5.02 5.02 0 0 1-2.23 2.23l1.34 2.69a8.03 8.03 0 0 0 3.58-3.58zM6.42 2.84a8.03 8.03 0 0 0-3.58 3.58l2.69 1.34a5.02 5.02 0 0 1 2.23-2.23L6.42 2.84zM2.84 13.58a8.03 8.03 0 0 0 3.58 3.58l1.34-2.69a5.02 5.02 0 0 1-2.23-2.23l-2.69 1.34zM10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-7a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-calculator">
|
||||
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm3 1v2h10V3H5zm0 4v2h2V7H5zm4 0v2h2V7H9zm4 0v2h2V7h-2zm-8 4v2h2v-2H5zm4 0v2h2v-2H9zm4 0v6h2v-6h-2zm-8 4v2h2v-2H5zm4 0v2h2v-2H9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-calendar">
|
||||
<path d="M1 4c0-1.1.9-2 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4zm2 2v12h14V6H3zm2-6h2v2H5V0zm8 0h2v2h-2V0zM5 9h2v2H5V9zm0 4h2v2H5v-2zm4-4h2v2H9V9zm0 4h2v2H9v-2zm4-4h2v2h-2V9zm0 4h2v2h-2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-camera">
|
||||
<path d="M0 6c0-1.1.9-2 2-2h3l2-2h6l2 2h3a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm10 10a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm0-2a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-chart">
|
||||
<path d="M4.13 12H4a2 2 0 1 0 1.8 1.11L7.86 10a2.03 2.03 0 0 0 .65-.07l1.55 1.55a2 2 0 1 0 3.72-.37L15.87 8H16a2 2 0 1 0-1.8-1.11L12.14 10a2.03 2.03 0 0 0-.65.07L9.93 8.52a2 2 0 1 0-3.72.37L4.13 12zM0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-chart-bar">
|
||||
<path d="M1 10h3v10H1V10zM6 0h3v20H6V0zm5 8h3v12h-3V8zm5-4h3v16h-3V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-chart-pie">
|
||||
<path d="M19.95 11A10 10 0 1 1 9 .05V11h10.95zm-.08-2.6H11.6V.13a10 10 0 0 1 8.27 8.27z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-chat-bubble-dots">
|
||||
<path d="M10 15l-4 4v-4H2a2 2 0 0 1-2-2V3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-8zM5 7v2h2V7H5zm4 0v2h2V7H9zm4 0v2h2V7h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-checkmark">
|
||||
<path d="M0 11l2-2 5 5L18 3l2 2L7 18z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-checkmark-outline">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM6.7 9.29L9 11.6l4.3-4.3 1.4 1.42L9 14.4l-3.7-3.7 1.4-1.42z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-down">
|
||||
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-left">
|
||||
<path d="M7.05 9.293L6.343 10 12 15.657l1.414-1.414L9.172 10l4.242-4.243L12 4.343z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-down">
|
||||
<path d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0zM10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm-.7 10.54L5.75 9l1.41-1.41L10 10.4l2.83-2.82L14.24 9 10 13.24l-.7-.7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-left">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-right">
|
||||
<path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-up">
|
||||
<path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm10 8a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm.7-10.54L14.25 11l-1.41 1.41L10 9.6l-2.83 2.8L5.76 11 10 6.76l.7.7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-right">
|
||||
<path d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-up">
|
||||
<path d="M10.707 7.05L10 6.343 4.343 12l1.414 1.414L10 9.172l4.243 4.242L15.657 12z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-clipboard">
|
||||
<path d="M7.03 2.6a3 3 0 0 1 5.94 0L15 3v1h1a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h1V3l2.03-.4zM5 6H4v12h12V6h-1v1H5V6zm5-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-close">
|
||||
<path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-close-outline">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-close-solid">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM11.4 10l2.83-2.83-1.41-1.41L10 8.59 7.17 5.76 5.76 7.17 8.59 10l-2.83 2.83 1.41 1.41L10 11.41l2.83 2.83 1.41-1.41L11.41 10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cloud">
|
||||
<path d="M16.88 9.1A4 4 0 0 1 16 17H5a5 5 0 0 1-1-9.9V7a3 3 0 0 1 4.52-2.59A4.98 4.98 0 0 1 17 8c0 .38-.04.74-.12 1.1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cloud-upload">
|
||||
<path d="M16.88 9.1A4 4 0 0 1 16 17H5a5 5 0 0 1-1-9.9V7a3 3 0 0 1 4.52-2.59A4.98 4.98 0 0 1 17 8c0 .38-.04.74-.12 1.1zM11 11h3l-4-4-4 4h3v3h2v-3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-code">
|
||||
<path d="M.7 9.3l4.8-4.8 1.4 1.42L2.84 10l4.07 4.07-1.41 1.42L0 10l.7-.7zm18.6 1.4l.7-.7-5.49-5.49-1.4 1.42L17.16 10l-4.07 4.07 1.41 1.42 4.78-4.78z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-coffee">
|
||||
<path d="M4 11H2a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h2V1h14v10a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zm0-2V5H2v4h2zm-2 8v-1h18v1l-4 2H6l-4-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-cog">
|
||||
<path d="M3.94 6.5L2.22 3.64l1.42-1.42L6.5 3.94c.52-.3 1.1-.54 1.7-.7L9 0h2l.8 3.24c.6.16 1.18.4 1.7.7l2.86-1.72 1.42 1.42-1.72 2.86c.3.52.54 1.1.7 1.7L20 9v2l-3.24.8c-.16.6-.4 1.18-.7 1.7l1.72 2.86-1.42 1.42-2.86-1.72c-.52.3-1.1.54-1.7.7L11 20H9l-.8-3.24c-.6-.16-1.18-.4-1.7-.7l-2.86 1.72-1.42-1.42 1.72-2.86c-.3-.52-.54-1.1-.7-1.7L0 11V9l3.24-.8c.16-.6.4-1.18.7-1.7zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-color-palette">
|
||||
<path d="M9 20v-1.7l.01-.24L15.07 12h2.94c1.1 0 1.99.89 1.99 2v4a2 2 0 0 1-2 2H9zm0-3.34V5.34l2.08-2.07a1.99 1.99 0 0 1 2.82 0l2.83 2.83a2 2 0 0 1 0 2.82L9 16.66zM0 1.99C0 .9.89 0 2 0h4a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zM4 17a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-compose">
|
||||
<path d="M2 4v14h14v-6l2-2v10H0V2h10L8 4H2zm10.3-.3l4 4L8 16H4v-4l8.3-8.3zm1.4-1.4L16 0l4 4-2.3 2.3-4-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-computer-desktop">
|
||||
<path d="M7 17H2a2 2 0 0 1-2-2V2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2h-5l4 2v1H3v-1l4-2zM2 2v11h16V2H2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-computer-laptop">
|
||||
<path d="M18 16h2v1a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1v-1h2V4c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12zM4 4v9h12V4H4zm4 11v1h4v-1H8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-conversation">
|
||||
<path d="M17 11v3l-3-3H8a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-1zm-3 2v2a2 2 0 0 1-2 2H6l-3 3v-3H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h2v3a4 4 0 0 0 4 4h6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-credit-card">
|
||||
<path d="M18 6V4H2v2h16zm0 4H2v6h16v-6zM0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm4 8h4v2H4v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-currency-dollar">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm1-5h1a3 3 0 0 0 0-6H7.99a1 1 0 0 1 0-2H14V5h-3V3H9v2H8a3 3 0 1 0 0 6h4a1 1 0 1 1 0 2H6v2h3v2h2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-dashboard">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm-5.6-4.29a9.95 9.95 0 0 1 11.2 0 8 8 0 1 0-11.2 0zm6.12-7.64l3.02-3.02 1.41 1.41-3.02 3.02a2 2 0 1 1-1.41-1.41z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-date-add">
|
||||
<path d="M15 2h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h2V0h2v2h6V0h2v2zM3 6v12h14V6H3zm6 5V9h2v2h2v2h-2v2H9v-2H7v-2h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-dial-pad">
|
||||
<path d="M5 4a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM5 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM5 14a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5-6a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-directions">
|
||||
<path d="M10 0l10 10-10 10L0 10 10 0zM6 10v3h2v-3h3v3l4-4-4-4v3H8a2 2 0 0 0-2 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-document">
|
||||
<path d="M4 18h12V6h-4V2H4v16zm-2 1V0h12l4 4v16H2v-1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-document-add">
|
||||
<path d="M9 10V8h2v2h2v2h-2v2H9v-2H7v-2h2zm-5 8h12V6h-4V2H4v16zm-2 1V0h12l4 4v16H2v-1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-dots-horizontal-double">
|
||||
<path d="M10 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-dots-horizontal-triple">
|
||||
<path d="M10 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0-6a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-download">
|
||||
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-duplicate">
|
||||
<path d="M6 6V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h4zm2 0h4a2 2 0 0 1 2 2v4h4V2H8v4zM2 8v10h10V8H2zm4 4v-2h2v2h2v2H8v2H6v-2H4v-2h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-edit-copy">
|
||||
<path d="M6 6V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h4zm2 0h4a2 2 0 0 1 2 2v4h4V2H8v4zM2 8v10h10V8H2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-edit-crop">
|
||||
<path d="M14 16H6a2 2 0 0 1-2-2V6H0V4h4V0h2v14h14v2h-4v4h-2v-4zm0-3V6H7V4h7a2 2 0 0 1 2 2v7h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-edit-cut">
|
||||
<path d="M9.77 11.5l5.34 3.91c.44.33 1.24.59 1.79.59H20L6.89 6.38A3.5 3.5 0 1 0 5.5 8.37L7.73 10 5.5 11.63a3.5 3.5 0 1 0 1.38 1.99l2.9-2.12zM3.5 7a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm0 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM15.1 4.59A3.53 3.53 0 0 1 16.9 4H20l-7.5 5.5L10.45 8l4.65-3.41z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-edit-pencil">
|
||||
<path d="M12.3 3.7l4 4L4 20H0v-4L12.3 3.7zm1.4-1.4L16 0l4 4-2.3 2.3-4-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-education">
|
||||
<path d="M3.33 8L10 12l10-6-10-6L0 6h10v2H3.33zM0 8v8l2-2.22V9.2L0 8zm10 12l-5-3-2-1.2v-6l7 4.2 7-4.2v6L10 20z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-envelope">
|
||||
<path d="M18 2a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h16zm-4.37 9.1L20 16v-2l-5.12-3.9L20 6V4l-10 8L0 4v2l5.12 4.1L0 14v2l6.37-4.9L10 14l3.63-2.9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-exclamation-outline">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 5h2v6H9V5zm0 8h2v2H9v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-exclamation-solid">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM9 5v6h2V5H9zm0 8v2h2v-2H9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-explore">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zM7.88 7.88l-3.54 7.78 7.78-3.54 3.54-7.78-7.78 3.54zM10 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-factory">
|
||||
<path d="M10.5 20H0V7l5 3.33V7l5 3.33V7l5 3.33V0h5v20h-9.5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-fast-forward">
|
||||
<path d="M1 5l9 5-9 5V5zm9 0l9 5-9 5V5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-fast-rewind">
|
||||
<path d="M19 5v10l-9-5 9-5zm-9 0v10l-9-5 9-5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-film">
|
||||
<path d="M0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm6 0v12h8V4H6zM2 5v2h2V5H2zm0 4v2h2V9H2zm0 4v2h2v-2H2zm14-8v2h2V5h-2zm0 4v2h2V9h-2zm0 4v2h2v-2h-2zM8 7l5 3-5 3V7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-filter">
|
||||
<path d="M12 12l8-8V0H0v4l8 8v8l4-4v-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-flag">
|
||||
<path d="M7.667 12H2v8H0V0h12l.333 2H20l-3 6 3 6H8l-.333-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-flashlight">
|
||||
<path d="M13 7v11a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V7L5 5V3h10v2l-2 2zM9 8v1a1 1 0 1 0 2 0V8a1 1 0 0 0-2 0zM5 0h10v2H5V0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-folder">
|
||||
<path d="M0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-folder-outline">
|
||||
<path d="M0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2 2v10h16V6H2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-folder-outline-add">
|
||||
<path d="M0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2 2v10h16V6H2zm7 4V8h2v2h2v2h-2v2H9v-2H7v-2h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-format-bold">
|
||||
<path d="M3 19V1h8a5 5 0 0 1 3.88 8.16A5.5 5.5 0 0 1 11.5 19H3zm7.5-8H7v5h3.5a2.5 2.5 0 1 0 0-5zM7 4v4h3a2 2 0 1 0 0-4H7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-format-italic">
|
||||
<path d="M8 1h9v2H8V1zm3 2h3L8 17H5l6-14zM2 17h9v2H2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-format-text-size">
|
||||
<path d="M16 9v8h-2V9h-4V7h10v2h-4zM8 5v12H6V5H0V3h15v2H8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-format-underline">
|
||||
<path d="M16 9A6 6 0 1 1 4 9V1h3v8a3 3 0 0 0 6 0V1h3v8zM2 17h16v2H2v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-gift">
|
||||
<path d="M14.83 4H20v6h-1v10H1V10H0V4h5.17A3 3 0 0 1 10 .76 3 3 0 0 1 14.83 4zM8 10H3v8h5v-8zm4 0v8h5v-8h-5zM8 6H2v2h6V6zm4 0v2h6V6h-6zM8 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm4 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-globe">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm2-2.25a8 8 0 0 0 4-2.46V9a2 2 0 0 1-2-2V3.07a7.95 7.95 0 0 0-3-1V3a2 2 0 0 1-2 2v1a2 2 0 0 1-2 2v2h3a2 2 0 0 1 2 2v5.75zm-4 0V15a2 2 0 0 1-2-2v-1h-.5A1.5 1.5 0 0 1 4 10.5V8H2.25A8.01 8.01 0 0 0 8 17.75z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-hand-stop">
|
||||
<path d="M17 16a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4.01V4a1 1 0 0 1 1-1 1 1 0 0 1 1 1v6h1V2a1 1 0 0 1 1-1 1 1 0 0 1 1 1v8h1V1a1 1 0 1 1 2 0v9h1V2a1 1 0 0 1 1-1 1 1 0 0 1 1 1v13h1V9a1 1 0 0 1 1-1h1v8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-hard-drive">
|
||||
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm10.4 5.6A5 5 0 1 0 15 12V5l-2.6 2.6zM10 14a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM6 3v2h4V3H6zM4 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 16a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm12 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0-16a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-headphones">
|
||||
<path d="M16 8A6 6 0 1 0 4 8v11H2a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2V8a8 8 0 1 1 16 0v3a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-2V8zm-4 2h3v10h-3V10zm-7 0h3v10H5V10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-heart">
|
||||
<path d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.78 7.77L10 18.78l8.39-8.4a5.5 5.5 0 0 0-7.78-7.77l-.61.61z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-home">
|
||||
<path d="M8 20H3V10H0L10 0l10 10h-3v10h-5v-6H8v6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-hot">
|
||||
<path d="M10 0s8 7.58 8 12a8 8 0 1 1-16 0c0-1.5.91-3.35 2.12-5.15A3 3 0 0 0 10 6V0zM8 0a3 3 0 1 0 0 6V0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-hour-glass">
|
||||
<path d="M3 18a7 7 0 0 1 4-6.33V8.33A7 7 0 0 1 3 2H1V0h18v2h-2a7 7 0 0 1-4 6.33v3.34A7 7 0 0 1 17 18h2v2H1v-2h2zM5 2a5 5 0 0 0 4 4.9V10h2V6.9A5 5 0 0 0 15 2H5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-inbox">
|
||||
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm14 12h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-inbox-check">
|
||||
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm14 12h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2zM5 9l2-2 2 2 4-4 2 2-6 6-4-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-inbox-download">
|
||||
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm14 12h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2zM9 8V5h2v3h3l-4 4-4-4h3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-inbox-full">
|
||||
<path d="M14 14h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2zM0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm4 2h12v2H4V4zm0 3h12v2H4V7zm0 3h12v2H4v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-indent-decrease">
|
||||
<path d="M1 1h18v2H1V1zm6 8h12v2H7V9zm-6 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2zM5 6v8l-4-4 4-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-indent-increase">
|
||||
<path d="M1 1h18v2H1V1zm6 8h12v2H7V9zm-6 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2zM1 6l4 4-4 4V6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-information-outline">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-information-solid">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM9 11v4h2V9H9v2zm0-6v2h2V5H9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-key">
|
||||
<path d="M12.26 11.74L10 14H8v2H6v2l-2 2H0v-4l8.26-8.26a6 6 0 1 1 4 4zm4.86-4.62A3 3 0 0 0 15 2a3 3 0 0 0-2.12.88l4.24 4.24z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-keyboard">
|
||||
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v2h2V6H2zm1 3v2h2V9H3zm-1 3v2h2v-2H2zm3 0v2h10v-2H5zm11 0v2h2v-2h-2zM6 9v2h2V9H6zm3 0v2h2V9H9zm3 0v2h2V9h-2zm3 0v2h2V9h-2zM5 6v2h2V6H5zm3 0v2h2V6H8zm3 0v2h2V6h-2zm3 0v2h4V6h-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-layers">
|
||||
<path d="M10 1l10 6-10 6L0 7l10-6zm6.67 10L20 13l-10 6-10-6 3.33-2L10 15l6.67-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-library">
|
||||
<path d="M0 6l10-6 10 6v2H0V6zm0 12h20v2H0v-2zm2-2h16v2H2v-2zm0-8h4v8H2V8zm6 0h4v8H8V8zm6 0h4v8h-4V8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-light-bulb">
|
||||
<path d="M7 13.33a7 7 0 1 1 6 0V16H7v-2.67zM7 17h6v1.5c0 .83-.67 1.5-1.5 1.5h-3A1.5 1.5 0 0 1 7 18.5V17zm2-5.1V14h2v-2.1a5 5 0 1 0-2 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-link">
|
||||
<path d="M9.26 13a2 2 0 0 1 .01-2.01A3 3 0 0 0 9 5H5a3 3 0 0 0 0 6h.08a6.06 6.06 0 0 0 0 2H5A5 5 0 0 1 5 3h4a5 5 0 0 1 .26 10zm1.48-6a2 2 0 0 1-.01 2.01A3 3 0 0 0 11 15h4a3 3 0 0 0 0-6h-.08a6.06 6.06 0 0 0 0-2H15a5 5 0 0 1 0 10h-4a5 5 0 0 1-.26-10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-list-add">
|
||||
<path d="M15 9h-3v2h3v3h2v-3h3V9h-3V6h-2v3zM0 3h10v2H0V3zm0 8h10v2H0v-2zm0-4h10v2H0V7zm0 8h10v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-list-bullet">
|
||||
<path d="M1 4h2v2H1V4zm4 0h14v2H5V4zM1 9h2v2H1V9zm4 0h14v2H5V9zm-4 5h2v2H1v-2zm4 0h14v2H5v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-load-balancer">
|
||||
<path d="M17 12h-6v4h1v4H8v-4h1v-4H3v4h1v4H0v-4h1v-4a2 2 0 0 1 2-2h6V6H7V0h6v6h-2v4h6a2 2 0 0 1 2 2v4h1v4h-4v-4h1v-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location">
|
||||
<path d="M10 20S3 10.87 3 7a7 7 0 1 1 14 0c0 3.87-7 13-7 13zm0-11a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-current">
|
||||
<path d="M0 0l20 8-8 4-2 8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-food">
|
||||
<path d="M18 11v7a2 2 0 0 1-4 0v-5h-2V3a3 3 0 0 1 3-3h3v11zM4 10a2 2 0 0 1-2-2V1a1 1 0 0 1 2 0v4h1V1a1 1 0 0 1 2 0v4h1V1a1 1 0 0 1 2 0v7a2 2 0 0 1-2 2v8a2 2 0 0 1-4 0v-8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-gas-station">
|
||||
<path d="M13 18h1v2H0v-2h1V2c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v16zM3 2v6h8V2H3zm10 8h1a2 2 0 0 1 2 2v3a1 1 0 0 0 2 0v-5l-2-2V6l-2-2 1-1 5 5v7a3 3 0 0 1-6 0v-3h-1v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-hotel">
|
||||
<path d="M2 12h18v6h-2v-2H2v2H0V2h2v10zm8-6h8a2 2 0 0 1 2 2v3H10V6zm-4 5a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-marina">
|
||||
<path d="M8 1.88V0h2v16h10l-4 4H2l-2-4h8v-2H0v-.26A24.03 24.03 0 0 0 8 1.88zM19.97 14H10v-.36A11.94 11.94 0 0 0 10 .36v-.2A16.01 16.01 0 0 1 19.97 14z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-park">
|
||||
<path d="M5.33 12.77A4 4 0 1 1 3 5.13V5a4 4 0 0 1 5.71-3.62 3.5 3.5 0 0 1 6.26 1.66 2.5 2.5 0 0 1 2 2.08 4 4 0 1 1-2.7 7.49A5.02 5.02 0 0 1 12 14.58V18l2 1v1H6v-1l2-1v-3l-2.67-2.23zM5 10l3 3v-3H5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-restroom">
|
||||
<path d="M12 16H9l2-4.5V9c0-1.1.9-2 2-2h2a2 2 0 0 1 2 2v2.5l2 4.5h-3v4h-4v-4zm-5-3h2V9a2 2 0 0 0-2-2H3a2 2 0 0 0-2 2v4h2v7h4v-7zM5 6a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm9 0a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-location-shopping">
|
||||
<path d="M16 6v2h2l2 12H0L2 8h2V6a6 6 0 1 1 12 0zm-2 0a4 4 0 1 0-8 0v2h8V6zM4 10v2h2v-2H4zm10 0v2h2v-2h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-lock-closed">
|
||||
<path d="M4 8V6a6 6 0 1 1 12 0v2h1a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2h1zm5 6.73V17h2v-2.27a2 2 0 1 0-2 0zM7 6v2h6V6a3 3 0 0 0-6 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-lock-open">
|
||||
<path d="M4 8V6a6 6 0 1 1 12 0h-3v2h4a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2h1zm5 6.73V17h2v-2.27a2 2 0 1 0-2 0zM7 6v2h6V6a3 3 0 0 0-6 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-map">
|
||||
<path d="M0 0l6 4 8-4 6 4v16l-6-4-8 4-6-4V0zm7 6v11l6-3V3L7 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-menu">
|
||||
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-mic">
|
||||
<path d="M9 18v-1.06A8 8 0 0 1 2 9h2a6 6 0 1 0 12 0h2a8 8 0 0 1-7 7.94V18h3v2H6v-2h3zM6 4a4 4 0 1 1 8 0v5a4 4 0 1 1-8 0V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-minus-outline">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm5-9v2H5V9h10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-minus-solid">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm5-11H5v2h10V9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-mobile-devices">
|
||||
<path d="M17 6V5h-2V2H3v14h5v4h3.25H11a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6zm-5.75 14H3a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v4a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5.75zM11 8v8h6V8h-6zm3 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-mood-happy">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM6.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm7 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm2.16 3a6 6 0 0 1-11.32 0h11.32z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-mood-sad">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM6.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm7 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm2.16 6H4.34a6 6 0 0 1 11.32 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-mouse">
|
||||
<path d="M4 9V6A6 6 0 0 1 9 .08V9H4zm0 2v3a6 6 0 1 0 12 0v-3H4zm12-2V6a6 6 0 0 0-5-5.92V9h5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-music-album">
|
||||
<path d="M0 0h20v20H0V0zm10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-5a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-music-artist">
|
||||
<path d="M15.75 8l-3.74-3.75a3.99 3.99 0 0 1 6.82-3.08A4 4 0 0 1 15.75 8zm-13.9 7.3l9.2-9.19 2.83 2.83-9.2 9.2-2.82-2.84zm-1.4 2.83l2.11-2.12 1.42 1.42-2.12 2.12-1.42-1.42zM10 15l2-2v7h-2v-5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-music-notes">
|
||||
<path d="M20 2.5V0L6 2v12.17A3 3 0 0 0 5 14H3a3 3 0 0 0 0 6h2a3 3 0 0 0 3-3V5.71L18 4.3v7.88a3 3 0 0 0-1-.17h-2a3 3 0 0 0 0 6h2a3 3 0 0 0 3-3V2.5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-music-playlist">
|
||||
<path d="M16 17a3 3 0 0 1-3 3h-2a3 3 0 0 1 0-6h2a3 3 0 0 1 1 .17V1l6-1v4l-4 .67V17zM0 3h12v2H0V3zm0 4h12v2H0V7zm0 4h12v2H0v-2zm0 4h6v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-navigation-more">
|
||||
<path d="M4 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm6 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm6 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-network">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm7.75-8a8.01 8.01 0 0 0 0-4h-3.82a28.81 28.81 0 0 1 0 4h3.82zm-.82 2h-3.22a14.44 14.44 0 0 1-.95 3.51A8.03 8.03 0 0 0 16.93 14zm-8.85-2h3.84a24.61 24.61 0 0 0 0-4H8.08a24.61 24.61 0 0 0 0 4zm.25 2c.41 2.4 1.13 4 1.67 4s1.26-1.6 1.67-4H8.33zm-6.08-2h3.82a28.81 28.81 0 0 1 0-4H2.25a8.01 8.01 0 0 0 0 4zm.82 2a8.03 8.03 0 0 0 4.17 3.51c-.42-.96-.74-2.16-.95-3.51H3.07zm13.86-8a8.03 8.03 0 0 0-4.17-3.51c.42.96.74 2.16.95 3.51h3.22zm-8.6 0h3.34c-.41-2.4-1.13-4-1.67-4S8.74 3.6 8.33 6zM3.07 6h3.22c.2-1.35.53-2.55.95-3.51A8.03 8.03 0 0 0 3.07 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-news-paper">
|
||||
<path d="M16 2h4v15a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V0h16v2zm0 2v13a1 1 0 0 0 1 1 1 1 0 0 0 1-1V4h-2zM2 2v15a1 1 0 0 0 1 1h11.17a2.98 2.98 0 0 1-.17-1V2H2zm2 8h8v2H4v-2zm0 4h8v2H4v-2zM4 4h8v4H4V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-notifications">
|
||||
<path d="M4 8a6 6 0 0 1 4.03-5.67 2 2 0 1 1 3.95 0A6 6 0 0 1 16 8v6l3 2v1H1v-1l3-2V8zm8 10a2 2 0 1 1-4 0h4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-notifications-outline">
|
||||
<path d="M6 8v7h8V8a4 4 0 1 0-8 0zm2.03-5.67a2 2 0 1 1 3.95 0A6 6 0 0 1 16 8v6l3 2v1H1v-1l3-2V8a6 6 0 0 1 4.03-5.67zM12 18a2 2 0 1 1-4 0h4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-paste">
|
||||
<path d="M10.5 20H2a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h1V3l2.03-.4a3 3 0 0 1 5.94 0L13 3v1h1a2 2 0 0 1 2 2v1h-2V6h-1v1H3V6H2v12h5v2h3.5zM8 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm2 4h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2zm0 2v8h8v-8h-8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-pause">
|
||||
<path d="M5 4h3v12H5V4zm7 0h3v12h-3V4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-pause-outline">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM7 6h2v8H7V6zm4 0h2v8h-2V6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-pause-solid">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM7 6v8h2V6H7zm4 0v8h2V6h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-pen-tool">
|
||||
<path d="M11 9.27V0l6 11-4 6H7l-4-6L9 0v9.27a2 2 0 1 0 2 0zM6 18h8v2H6v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-phone">
|
||||
<path d="M20 18.35V19a1 1 0 0 1-1 1h-2A17 17 0 0 1 0 3V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v4c0 .56-.31 1.31-.7 1.7L3.16 8.84c1.52 3.6 4.4 6.48 8 8l2.12-2.12c.4-.4 1.15-.71 1.7-.71H19a1 1 0 0 1 .99 1v3.35z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-photo">
|
||||
<path d="M0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm11 9l-3-3-6 6h16l-5-5-2 2zm4-4a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-php-elephant">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 12v8A10 10 0 0 1 8.17.17L10 2h5a5 5 0 0 1 5 4.99v9.02A4 4 0 0 1 16 20v-2a2 2 0 1 0 0-4h-4l-2-2zm5.5-3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-pin">
|
||||
<path d="M11 12h6v-1l-3-1V2l3-1V0H3v1l3 1v8l-3 1v1h6v7l1 1 1-1v-7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-play">
|
||||
<path d="M4 4l12 6-12 6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-play-outline">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM7 6l8 4-8 4V6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-plugin">
|
||||
<path d="M20 14v4a2 2 0 0 1-2 2h-4v-2a2 2 0 0 0-2-2 2 2 0 0 0-2 2v2H6a2 2 0 0 1-2-2v-4H2a2 2 0 0 1-2-2 2 2 0 0 1 2-2h2V6c0-1.1.9-2 2-2h4V2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h4a2 2 0 0 1 2 2v4h-2a2 2 0 0 0-2 2 2 2 0 0 0 2 2h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-portfolio">
|
||||
<path d="M9 12H1v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-8v2H9v-2zm0-1H0V5c0-1.1.9-2 2-2h4V2a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1h4a2 2 0 0 1 2 2v6h-9V9H9v2zm3-8V2H8v1h4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-printer">
|
||||
<path d="M4 16H0V6h20v10h-4v4H4v-4zm2-4v6h8v-6H6zM4 0h12v5H4V0zM2 8v2h2V8H2zm4 0v2h2V8H6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-pylon">
|
||||
<path d="M17.4 18H20v2H0v-2h2.6L8 0h4l5.4 18zm-3.2-4H5.8l-1.2 4h10.8l-1.2-4zm-2.4-8H8.2L7 10h6l-1.2-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-question">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm2-13c0 .28-.21.8-.42 1L10 9.58c-.57.58-1 1.6-1 2.42v1h2v-1c0-.29.21-.8.42-1L13 9.42c.57-.58 1-1.6 1-2.42a4 4 0 1 0-8 0h2a2 2 0 1 1 4 0zm-3 8v2h2v-2H9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-queue">
|
||||
<path d="M0 2h20v4H0V2zm0 8h20v2H0v-2zm0 6h20v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-radar">
|
||||
<path d="M12 10a2 2 0 0 1-3.41 1.41A2 2 0 0 1 10 8V0a9.97 9.97 0 0 1 10 10h-8zm7.9 1.41A10 10 0 1 1 8.59.1v2.03a8 8 0 1 0 9.29 9.29h2.02zm-4.07 0a6 6 0 1 1-7.25-7.25v2.1a3.99 3.99 0 0 0-1.4 6.57 4 4 0 0 0 6.56-1.42h2.1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-radio">
|
||||
<path d="M20 9v9a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h13.8L.74 1.97 1.26.03 20 5.06V9zm-5 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM2 8v2h16V8H2zm1.5 10a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm6.5-1a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-refresh">
|
||||
<path d="M10 3v2a5 5 0 0 0-3.54 8.54l-1.41 1.41A7 7 0 0 1 10 3zm4.95 2.05A7 7 0 0 1 10 17v-2a5 5 0 0 0 3.54-8.54l1.41-1.41zM10 20l-4-4 4-4v8zm0-12V0l4 4-4 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-reload">
|
||||
<path d="M14.66 15.66A8 8 0 1 1 17 10h-2a6 6 0 1 0-1.76 4.24l1.42 1.42zM12 10h8l-4 4-4-4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-reply">
|
||||
<path d="M15 17v-2.99A4 4 0 0 0 11 10H8v5L2 9l6-6v5h3a6 6 0 0 1 6 6v3h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-reply-all">
|
||||
<path d="M18 17v-2.99A4 4 0 0 0 14 10h-3v5L5 9l6-6v5h3a6 6 0 0 1 6 6v3h-2zM6 6V3L0 9l6 6v-3L3 9l3-3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-repost">
|
||||
<path d="M5 4a2 2 0 0 0-2 2v6H0l4 4 4-4H5V6h7l2-2H5zm10 4h-3l4-4 4 4h-3v6a2 2 0 0 1-2 2H6l2-2h7V8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-save-disk">
|
||||
<path d="M0 2C0 .9.9 0 2 0h14l4 4v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm5 0v6h10V2H5zm6 1h3v4h-3V3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-screen-full">
|
||||
<path d="M2.8 15.8L0 13v7h7l-2.8-2.8 4.34-4.32-1.42-1.42L2.8 15.8zM17.2 4.2L20 7V0h-7l2.8 2.8-4.34 4.32 1.42 1.42L17.2 4.2zm-1.4 13L13 20h7v-7l-2.8 2.8-4.32-4.34-1.42 1.42 4.33 4.33zM4.2 2.8L7 0H0v7l2.8-2.8 4.32 4.34 1.42-1.42L4.2 2.8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-search">
|
||||
<path d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-send">
|
||||
<path d="M0 0l20 10L0 20V0zm0 8v4l10-2L0 8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-servers">
|
||||
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm0 7c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V9zm0 7c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2zM12 2v2h2V2h-2zm4 0v2h2V2h-2zm-4 7v2h2V9h-2zm4 0v2h2V9h-2zm-4 7v2h2v-2h-2zm4 0v2h2v-2h-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-share">
|
||||
<path d="M4 10c0-1.1.9-2 2-2h8c1.1 0 2 .9 2 2v8c0 1.1-.9 2-2 2H6c-1.1 0-2-.9-2-2v-8zm2 0v8h8v-8h-2V8H8v2H6zm3-6.17V16h2V3.83l3.07 3.07 1.42-1.41L10 0l-.7.7-4.8 4.8 1.42 1.4L9 3.84z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-share-alt">
|
||||
<path d="M5.08 12.16A2.99 2.99 0 0 1 0 10a3 3 0 0 1 5.08-2.16l8.94-4.47a3 3 0 1 1 .9 1.79L5.98 9.63a3.03 3.03 0 0 1 0 .74l8.94 4.47A2.99 2.99 0 0 1 20 17a3 3 0 1 1-5.98-.37l-8.94-4.47z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-shield">
|
||||
<path d="M19 11a7.5 7.5 0 0 1-3.5 5.94L10 20l-5.5-3.06A7.5 7.5 0 0 1 1 11V3c3.38 0 6.5-1.12 9-3 2.5 1.89 5.62 3 9 3v8zm-9 1.08l2.92 2.04-1.03-3.41 2.84-2.15-3.56-.08L10 5.12 8.83 8.48l-3.56.08L8.1 10.7l-1.03 3.4L10 12.09z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-shopping-cart">
|
||||
<path d="M4 2h16l-3 9H4a1 1 0 1 0 0 2h13v2H4a3 3 0 0 1 0-6h.33L3 5 2 2H0V0h3a1 1 0 0 1 1 1v1zm1 18a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm10 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-show-sidebar">
|
||||
<path d="M7 3H2v14h5V3zm2 0v14h9V3H9zM0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm3 1h3v2H3V4zm0 3h3v2H3V7zm0 3h3v2H3v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-shuffle">
|
||||
<path d="M6.59 12.83L4.4 15c-.58.58-1.59 1-2.4 1H0v-2h2c.29 0 .8-.2 1-.41l2.17-2.18 1.42 1.42zM16 4V1l4 4-4 4V6h-2c-.29 0-.8.2-1 .41l-2.17 2.18L9.4 7.17 11.6 5c.58-.58 1.59-1 2.41-1h2zm0 10v-3l4 4-4 4v-3h-2c-.82 0-1.83-.42-2.41-1l-8.6-8.59C2.8 6.21 2.3 6 2 6H0V4h2c.82 0 1.83.42 2.41 1l8.6 8.59c.2.2.7.41.99.41h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-star-full">
|
||||
<path d="M10 15l-5.878 3.09 1.123-6.545L.489 6.91l6.572-.955L10 0l2.939 5.955 6.572.955-4.756 4.635 1.123 6.545z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-station">
|
||||
<path d="M9 11.73a2 2 0 1 1 2 0V20H9v-8.27zm5.24 2.51l-1.41-1.41A3.99 3.99 0 0 0 10 6a4 4 0 0 0-2.83 6.83l-1.41 1.41a6 6 0 1 1 8.49 0zm2.83 2.83l-1.41-1.41a8 8 0 1 0-11.31 0l-1.42 1.41a10 10 0 1 1 14.14 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-step-backward">
|
||||
<path d="M4 5h3v10H4V5zm12 0v10l-9-5 9-5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-step-forward">
|
||||
<path d="M13 5h3v10h-3V5zM4 5l9 5-9 5V5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-stethoscope">
|
||||
<path d="M17 10.27V4.99a1 1 0 0 0-2 0V15a5 5 0 0 1-10 0v-1.08A6 6 0 0 1 0 8V2C0 .9.9 0 2 0h1a1 1 0 0 1 1 1 1 1 0 0 1-1 1H2v6a4 4 0 1 0 8 0V2H9a1 1 0 0 1-1-1 1 1 0 0 1 1-1h1a2 2 0 0 1 2 2v6a6 6 0 0 1-5 5.92V15a3 3 0 0 0 6 0V5a3 3 0 0 1 6 0v5.27a2 2 0 1 1-2 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-store-front">
|
||||
<path d="M18 9.87V20H2V9.87a4.25 4.25 0 0 0 3-.38V14h10V9.5a4.26 4.26 0 0 0 3 .37zM3 0h4l-.67 6.03A3.43 3.43 0 0 1 3 9C1.34 9 .42 7.73.95 6.15L3 0zm5 0h4l.7 6.3c.17 1.5-.91 2.7-2.42 2.7h-.56A2.38 2.38 0 0 1 7.3 6.3L8 0zm5 0h4l2.05 6.15C19.58 7.73 18.65 9 17 9a3.42 3.42 0 0 1-3.33-2.97L13 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-stroke-width">
|
||||
<path d="M0 0h20v5H0V0zm0 7h20v4H0V7zm0 6h20v3H0v-3zm0 5h20v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-subdirectory-left">
|
||||
<path d="M18 12v1H8v5l-6-6 6-6v5h8V2h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-subdirectory-right">
|
||||
<path d="M3.5 13H12v5l6-6-6-6v5H4V2H2v11z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-swap">
|
||||
<path d="M9 6a4 4 0 1 1 8 0v8h3l-4 4-4-4h3V6a2 2 0 0 0-2-2 2 2 0 0 0-2 2v8a4 4 0 1 1-8 0V6H0l4-4 4 4H5v8a2 2 0 0 0 2 2 2 2 0 0 0 2-2V6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-tablet">
|
||||
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm2 0v14h12V2H4zm6 17a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-tag">
|
||||
<path d="M0 10V2l2-2h8l10 10-10 10L0 10zm4.5-4a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-target">
|
||||
<path d="M17.94 11H13V9h4.94A8 8 0 0 0 11 2.06V7H9V2.06A8 8 0 0 0 2.06 9H7v2H2.06A8 8 0 0 0 9 17.94V13h2v4.94A8 8 0 0 0 17.94 11zM10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-text-box">
|
||||
<path d="M0 0h6v6H0V0zm2 2v2h2V2H2zm12-2h6v6h-6V0zm2 2v2h2V2h-2zm-2 12h6v6h-6v-6zm2 2v2h2v-2h-2zM0 14h6v6H0v-6zm2 2v2h2v-2H2zM6 2h8v2H6V2zm0 14h8v2H6v-2zM16 6h2v8h-2V6zM2 6h2v8H2V6zm5 1h6v2H7V7zm2 2h2v4H9V9z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-text-decoration">
|
||||
<path d="M12 5h-2v12H8V3h8v2h-2v12h-2V5zM8 3a4 4 0 1 0 0 8V3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-thermometer">
|
||||
<path d="M9 11.17V7h2v4.17a3 3 0 1 1-2 0zm-1-.63a4 4 0 1 0 4 0V4a2 2 0 1 0-4 0v6.53zM6 9.53V4a4 4 0 0 1 8 0v5.53A5.99 5.99 0 0 1 10 20 6 6 0 0 1 6 9.53z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-thumbs-down">
|
||||
<path d="M11 20a2 2 0 0 1-2-2v-6H2a2 2 0 0 1-2-2V8l2.3-6.12A3.11 3.11 0 0 1 5 0h8a2 2 0 0 1 2 2v8l-3 7v3h-1zm6-10V0h3v10h-3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-thumbs-up">
|
||||
<path d="M11 0h1v3l3 7v8a2 2 0 0 1-2 2H5c-1.1 0-2.31-.84-2.7-1.88L0 12v-2a2 2 0 0 1 2-2h7V2a2 2 0 0 1 2-2zm6 10h3v10h-3V10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-ticket">
|
||||
<path d="M20 12v5H0v-5a2 2 0 1 0 0-4V3h20v5a2 2 0 1 0 0 4zM3 5v10h14V5H3zm7 7.08l-2.92 2.04L8.1 10.7 5.27 8.56l3.56-.08L10 5.12l1.17 3.36 3.56.08-2.84 2.15 1.03 3.4L10 12.09z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-time">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-1-7.59V4h2v5.59l3.95 3.95-1.41 1.41L9 10.41z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-timer">
|
||||
<path d="M16.32 7.1A8 8 0 1 1 9 4.06V2h2v2.06c1.46.18 2.8.76 3.9 1.62l1.46-1.46 1.42 1.42-1.46 1.45zM10 18a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM7 0h6v2H7V0zm5.12 8.46l1.42 1.42L10 13.4 8.59 12l3.53-3.54z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-translate">
|
||||
<path d="M7.41 9l2.24 2.24-.83 2L6 10.4l-3.3 3.3-1.4-1.42L4.58 9l-.88-.88c-.53-.53-1-1.3-1.3-2.12h2.2c.15.28.33.53.51.7l.89.9.88-.88C7.48 6.1 8 4.84 8 4H0V2h5V0h2v2h5v2h-2c0 1.37-.74 3.15-1.7 4.12L7.4 9zm3.84 8L10 20H8l5-12h2l5 12h-2l-1.25-3h-5.5zm.83-2h3.84L14 10.4 12.08 15z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-trash">
|
||||
<path d="M6 2l2-2h4l2 2h4v2H2V2h4zM3 6h14l-1 14H4L3 6zm5 2v10h1V8H8zm3 0v10h1V8h-1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-travel-bus">
|
||||
<path d="M13 18H7v1a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2v1a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1zM4 5v6h5V5H4zm7 0v6h5V5h-5zM5 2v1h10V2H5zm.5 14a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm9 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-travel-car">
|
||||
<path d="M2 14v-3H1a1 1 0 0 1-1-1 1 1 0 0 1 1-1h1l4-7h8l4 7h1a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-1v6a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1H5v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-3zm13.86-5L13 4H7L4.14 9h11.72zM5.5 14a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm9 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-travel-case">
|
||||
<path d="M14 5h2v14H4V5h2V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1zm3 0h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1V5zM3 5v14H2a2 2 0 0 1-2-2V7c0-1.1.9-2 2-2h1zm5-1v1h4V4H8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-travel-taxi-cab">
|
||||
<path d="M12 3h2l4 7h1a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-1v6a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1H5v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-6H1a1 1 0 0 1-1-1 1 1 0 0 1 1-1h1l4-7h2V1h4v2zm3.86 7L13 5H7l-2.86 5h11.72zM5.5 15a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm9 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-travel-train">
|
||||
<path d="M12 18H8l-2 2H3l2-2a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2l2 2h-3l-2-2zM5 5v6h10V5H5zm1.5 11a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM8 2v1h4V2H8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-travel-walk">
|
||||
<path d="M11 7l1.44 2.16c.31.47 1.01.84 1.57.84H17V8h-3l-1.44-2.16a5.94 5.94 0 0 0-1.4-1.4l-1.32-.88a1.72 1.72 0 0 0-1.7-.04L4 6v5h2V7l2-1-3 14h2l2.35-7.65L11 14v6h2v-8l-2.7-2.7L11 7zm1-3a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-trophy">
|
||||
<path d="M15 9a3 3 0 0 0 3-3h2a5 5 0 0 1-5.1 5 5 5 0 0 1-3.9 3.9V17l5 2v1H4v-1l5-2v-2.1A5 5 0 0 1 5.1 11H5a5 5 0 0 1-5-5h2a3 3 0 0 0 3 3V4H2v2H0V2h5V0h10v2h5v4h-2V4h-3v5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-tuning">
|
||||
<path d="M17 16v4h-2v-4h-2v-3h6v3h-2zM1 9h6v3H1V9zm6-4h6v3H7V5zM3 0h2v8H3V0zm12 0h2v12h-2V0zM9 0h2v4H9V0zM3 12h2v8H3v-8zm6-4h2v12H9V8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-upload">
|
||||
<path d="M13 10v6H7v-6H2l8-8 8 8h-5zM0 18h20v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-usb">
|
||||
<path d="M15 8v2h-4V4h2l-3-4-3 4h2v8H5V9.73a2 2 0 1 0-2 0V12a2 2 0 0 0 2 2h4v2.27a2 2 0 1 0 2 0V12h4a2 2 0 0 0 2-2V8h1V4h-4v4h1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-user">
|
||||
<path d="M5 5a5 5 0 0 1 10 0v2A5 5 0 0 1 5 7V5zM0 16.68A19.9 19.9 0 0 1 10 14c3.64 0 7.06.97 10 2.68V20H0v-3.32z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-user-add">
|
||||
<path d="M2 6H0v2h2v2h2V8h2V6H4V4H2v2zm7 0a3 3 0 0 1 6 0v2a3 3 0 0 1-6 0V6zm11 9.14A15.93 15.93 0 0 0 12 13c-2.91 0-5.65.78-8 2.14V18h16v-2.86z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-user-group">
|
||||
<path d="M7 8a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0 1c2.15 0 4.2.4 6.1 1.09L12 16h-1.25L10 20H4l-.75-4H2L.9 10.09A17.93 17.93 0 0 1 7 9zm8.31.17c1.32.18 2.59.48 3.8.92L18 16h-1.25L16 20h-3.96l.37-2h1.25l1.65-8.83zM13 0a4 4 0 1 1-1.33 7.76 5.96 5.96 0 0 0 0-7.52C12.1.1 12.53 0 13 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-user-solid-circle">
|
||||
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zM7 6v2a3 3 0 1 0 6 0V6a3 3 0 1 0-6 0zm-3.65 8.44a8 8 0 0 0 13.3 0 15.94 15.94 0 0 0-13.3 0z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-user-solid-square">
|
||||
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm7 4v2a3 3 0 1 0 6 0V6a3 3 0 1 0-6 0zm11 9.14A15.93 15.93 0 0 0 10 13c-2.91 0-5.65.78-8 2.14V18h16v-2.86z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-vector">
|
||||
<path d="M12 4h4.27a2 2 0 1 1 0 2h-2.14a9 9 0 0 1 4.84 7.25 2 2 0 1 1-2 .04 7 7 0 0 0-4.97-6V8H8v-.71a7 7 0 0 0-4.96 6 2 2 0 1 1-2-.04A9 9 0 0 1 5.86 6H3.73a2 2 0 1 1 0-2H8V3h4v1z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-video-camera">
|
||||
<path d="M16 7l4-4v14l-4-4v3a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v3zm-8 7a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-2a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-view-carousel">
|
||||
<path d="M16 16v2H4v-2H0V4h4V2h12v2h4v12h-4zM14 5.5V4H6v12h8V5.5zm2 .5v8h2V6h-2zM4 6H2v8h2V6z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-view-column">
|
||||
<path d="M12 4H8v12h4V4zm2 0v12h4V4h-4zM6 4H2v12h4V4zM0 2h20v16H0V2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-view-hide">
|
||||
<path d="M12.81 4.36l-1.77 1.78a4 4 0 0 0-4.9 4.9l-2.76 2.75C2.06 12.79.96 11.49.2 10a11 11 0 0 1 12.6-5.64zm3.8 1.85c1.33 1 2.43 2.3 3.2 3.79a11 11 0 0 1-12.62 5.64l1.77-1.78a4 4 0 0 0 4.9-4.9l2.76-2.75zm-.25-3.99l1.42 1.42L3.64 17.78l-1.42-1.42L16.36 2.22z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-view-list">
|
||||
<path d="M0 3h20v2H0V3zm0 4h20v2H0V7zm0 4h20v2H0v-2zm0 4h20v2H0v-2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-view-show">
|
||||
<path d="M.2 10a11 11 0 0 1 19.6 0A11 11 0 0 1 .2 10zm9.8 4a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-2a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-view-tile">
|
||||
<path d="M0 0h9v9H0V0zm2 2v5h5V2H2zm-2 9h9v9H0v-9zm2 2v5h5v-5H2zm9-13h9v9h-9V0zm2 2v5h5V2h-5zm-2 9h9v9h-9v-9zm2 2v5h5v-5h-5z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-volume-down">
|
||||
<path d="M7 7H3v6h4l5 5V2L7 7zm8.54 6.54l-1.42-1.42a3 3 0 0 0 0-4.24l1.42-1.42a4.98 4.98 0 0 1 0 7.08z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-volume-mute">
|
||||
<path d="M9 7H5v6h4l5 5V2L9 7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-volume-off">
|
||||
<path d="M15 8.59l-2.12-2.13-1.42 1.42L13.6 10l-2.13 2.12 1.42 1.42L15 11.4l2.12 2.13 1.42-1.42L16.4 10l2.13-2.12-1.42-1.42L15 8.6zM4 7H0v6h4l5 5V2L4 7z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-volume-up">
|
||||
<path d="M5 7H1v6h4l5 5V2L5 7zm11.36 9.36l-1.41-1.41a6.98 6.98 0 0 0 0-9.9l1.41-1.41a8.97 8.97 0 0 1 0 12.72zm-2.82-2.82l-1.42-1.42a3 3 0 0 0 0-4.24l1.42-1.42a4.98 4.98 0 0 1 0 7.08z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-wallet">
|
||||
<path d="M0 4c0-1.1.9-2 2-2h15a1 1 0 0 1 1 1v1H2v1h17a1 1 0 0 1 1 1v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm16.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-watch">
|
||||
<path d="M11 9h2v2H9V7h2v2zm-5.82 6.08a6.98 6.98 0 0 1 0-10.16L6 0h8l.82 4.92a6.98 6.98 0 0 1 0 10.16L14 20H6l-.82-4.92zM10 15a5 5 0 1 0 0-10 5 5 0 0 0 0 10z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-wrench">
|
||||
<path d="M6.47 9.8A5 5 0 0 1 .2 3.22l3.95 3.95 2.82-2.83L3.03.41a5 5 0 0 1 6.4 6.68l10 10-2.83 2.83L6.47 9.8z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-zoom-in">
|
||||
<path fill-rule="evenodd"
|
||||
d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zM7 7V5h2v2h2v2H9v2H7V9H5V7h2z"/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 20 20" id="zondicon-zoom-out">
|
||||
<path fill-rule="evenodd"
|
||||
d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zM5 7h6v2H5V7z"/>
|
||||
</symbol>
|
||||
</svg>
|
Before Width: | Height: | Size: 60 KiB |
8
public/vendor/horizon/mix-manifest.json
vendored
@ -1,8 +0,0 @@
|
||||
{
|
||||
"/app.js": "/app.js?id=b4f3f08e60211bd6948ec35e5e9de9a1",
|
||||
"/app-dark.css": "/app-dark.css?id=15c72df05e2b1147fa3e4b0670cfb435",
|
||||
"/app.css": "/app.css?id=4d6a1a7fe095eedc2cb2a4ce822ea8a5",
|
||||
"/img/favicon.png": "/img/favicon.png?id=1542bfe8a0010dcbee710da13cce367f",
|
||||
"/img/horizon.svg": "/img/horizon.svg?id=904d5b5185fefb09035384e15bfca765",
|
||||
"/img/sprite.svg": "/img/sprite.svg?id=afc4952b74895bdef3ab4ebe9adb746f"
|
||||
}
|
@ -307,7 +307,6 @@ class="{{ request()->is('settings*') ? 'menu-item-active menu-item' : 'menu-item
|
||||
|
||||
@if (isCloud() && isInstanceAdmin())
|
||||
<li>
|
||||
|
||||
<a title="Admin" class="menu-item" href="/admin">
|
||||
<svg class="text-pink-600 icon" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
@ -320,9 +319,11 @@ class="{{ request()->is('settings*') ? 'menu-item-active menu-item' : 'menu-item
|
||||
@endif
|
||||
<div class="flex-1"></div>
|
||||
@if (isInstanceAdmin() && !isCloud())
|
||||
<li>
|
||||
<livewire:upgrade />
|
||||
</li>
|
||||
@persist('upgrade')
|
||||
<li>
|
||||
<livewire:upgrade />
|
||||
</li>
|
||||
@endpersist
|
||||
@endif
|
||||
<li>
|
||||
<a title="Onboarding"
|
||||
|
@ -1,54 +1,57 @@
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="py-4">Executions</h3>
|
||||
<x-forms.button wire:click='cleanupFailed'>Cleanup Failed Backups</x-forms.button>
|
||||
</div>
|
||||
<div class="flex flex-col-reverse gap-2">
|
||||
@forelse($executions as $execution)
|
||||
<form wire:key="{{ data_get($execution, 'id') }}"
|
||||
class="relative flex flex-col p-4 bg-white box-without-bg dark:bg-coolgray-100"
|
||||
@class([
|
||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
||||
])>
|
||||
@if (data_get($execution, 'status') === 'running')
|
||||
<div class="absolute top-2 right-2">
|
||||
<x-loading />
|
||||
</div>
|
||||
@endif
|
||||
<div>Database: {{ data_get($execution, 'database_name', 'N/A') }}</div>
|
||||
<div>Status: {{ data_get($execution, 'status') }}</div>
|
||||
<div>Started At: {{ data_get($execution, 'created_at') }}</div>
|
||||
@if (data_get($execution, 'message'))
|
||||
<div>Message: {{ data_get($execution, 'message') }}</div>
|
||||
@endif
|
||||
<div>Size: {{ data_get($execution, 'size') }} B /
|
||||
{{ round((int) data_get($execution, 'size') / 1024, 2) }}
|
||||
kB / {{ round((int) data_get($execution, 'size') / 1024 / 1024, 3) }} MB
|
||||
</div>
|
||||
<div>Location: {{ data_get($execution, 'filename', 'N/A') }}</div>
|
||||
<div class="flex gap-2">
|
||||
<div class="flex-1"></div>
|
||||
@if (data_get($execution, 'status') === 'success')
|
||||
<x-forms.button class=" dark:hover:bg-coolgray-400"
|
||||
x-on:click="download_file('{{ data_get($execution, 'id') }}')">Download</x-forms.button>
|
||||
@isset($backup)
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="py-4">Executions</h3>
|
||||
<x-forms.button wire:click='cleanupFailed'>Cleanup Failed Backups</x-forms.button>
|
||||
</div>
|
||||
<div class="flex flex-col-reverse gap-2">
|
||||
@forelse($executions as $execution)
|
||||
<form wire:key="{{ data_get($execution, 'id') }}"
|
||||
class="relative flex flex-col p-4 bg-white box-without-bg dark:bg-coolgray-100"
|
||||
@class([
|
||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
||||
])>
|
||||
@if (data_get($execution, 'status') === 'running')
|
||||
<div class="absolute top-2 right-2">
|
||||
<x-loading />
|
||||
</div>
|
||||
@endif
|
||||
<x-modal-confirmation isErrorButton action="deleteBackup({{ data_get($execution, 'id') }})">
|
||||
<x-slot:button-title>
|
||||
Delete
|
||||
</x-slot:button-title>
|
||||
This will delete this backup. It is not reversible.<br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
</div>
|
||||
</form>
|
||||
<div>Database: {{ data_get($execution, 'database_name', 'N/A') }}</div>
|
||||
<div>Status: {{ data_get($execution, 'status') }}</div>
|
||||
<div>Started At: {{ data_get($execution, 'created_at') }}</div>
|
||||
@if (data_get($execution, 'message'))
|
||||
<div>Message: {{ data_get($execution, 'message') }}</div>
|
||||
@endif
|
||||
<div>Size: {{ data_get($execution, 'size') }} B /
|
||||
{{ round((int) data_get($execution, 'size') / 1024, 2) }}
|
||||
kB / {{ round((int) data_get($execution, 'size') / 1024 / 1024, 3) }} MB
|
||||
</div>
|
||||
<div>Location: {{ data_get($execution, 'filename', 'N/A') }}</div>
|
||||
<div class="flex gap-2">
|
||||
<div class="flex-1"></div>
|
||||
@if (data_get($execution, 'status') === 'success')
|
||||
<x-forms.button class=" dark:hover:bg-coolgray-400"
|
||||
x-on:click="download_file('{{ data_get($execution, 'id') }}')">Download</x-forms.button>
|
||||
@endif
|
||||
<x-modal-confirmation isErrorButton action="deleteBackup({{ data_get($execution, 'id') }})">
|
||||
<x-slot:button-title>
|
||||
Delete
|
||||
</x-slot:button-title>
|
||||
This will delete this backup. It is not reversible.<br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@empty
|
||||
<div>No executions found.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<script>
|
||||
function download_file(executionId) {
|
||||
window.open('/download/backup/' + executionId, '_blank');
|
||||
}
|
||||
</script>
|
||||
@endisset
|
||||
|
||||
@empty
|
||||
<div>No executions found.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<script>
|
||||
function download_file(executionId) {
|
||||
window.open('/download/backup/' + executionId, '_blank');
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
@ -151,11 +151,13 @@ class="w-4 h-4 dark:text-warning text-coollabs"
|
||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}">
|
||||
Settings
|
||||
</a>
|
||||
<x-modal-confirmation action="restartDatabase({{ $database->id }})" isErrorButton
|
||||
buttonTitle="Restart">
|
||||
This database will be unavailable during the restart. <br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
|
||||
@if (str($database->status)->contains('running'))
|
||||
<x-modal-confirmation action="restartDatabase({{ $database->id }})"
|
||||
isErrorButton buttonTitle="Restart">
|
||||
This database will be unavailable during the restart. <br>Please think
|
||||
again.
|
||||
</x-modal-confirmation>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<form wire:submit.prevent='submit' class="flex flex-col w-full gap-2">
|
||||
<div class="pb-2">Note: If a service has a defined port, do not delete it. <br>If you want to use your custom domain, you can add it with a port.</div>
|
||||
<x-forms.input required placeholder="https://app.coolify.io" label="Domains" id="application.fqdn"
|
||||
<x-forms.input placeholder="https://app.coolify.io" label="Domains" id="application.fqdn"
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "></x-forms.input>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
</form>
|
||||
|
@ -40,6 +40,13 @@
|
||||
label="Bitbucket Webhook Secret"
|
||||
id="resource.manual_webhook_secret_bitbucket"></x-forms.input>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input readonly label="Gitea" id="giteaManualWebhook"></x-forms.input>
|
||||
<x-forms.input type="password"
|
||||
helper="Need to set a secret to be able to use this webhook. It should match with the secret in Gitea."
|
||||
label="Gitea Webhook Secret"
|
||||
id="resource.manual_webhook_secret_gitea"></x-forms.input>
|
||||
</div>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
</form>
|
||||
@else
|
||||
|
@ -72,7 +72,7 @@ class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-1
|
||||
<div class="w-64">
|
||||
@if ($server->isFunctional())
|
||||
@if (!$server->isLocalhost())
|
||||
<x-forms.checkbox instantSave disabled id="server.settings.is_build_server"
|
||||
<x-forms.checkbox instantSave id="server.settings.is_build_server"
|
||||
label="Use it as a build server?" />
|
||||
<div class="flex items-center gap-1 pt-6">
|
||||
<h3 class="">Cloudflare Tunnels
|
||||
@ -87,28 +87,32 @@ class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-1
|
||||
<livewire:server.configure-cloudflare-tunnels :server_id="$server->id" />
|
||||
</x-modal-input>
|
||||
@endif
|
||||
<h3 class="pt-6">Swarm <span class="text-xs text-neutral-500">(experimental)</span></h3>
|
||||
<div class="pb-4">Read the docs <a class='underline dark:text-white'
|
||||
href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>.
|
||||
</div>
|
||||
@if ($server->settings->is_swarm_worker)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@endif
|
||||
@if (!$server->isBuildServer())
|
||||
<h3 class="pt-6">Swarm <span class="text-xs text-neutral-500">(experimental)</span></h3>
|
||||
<div class="pb-4">Read the docs <a class='underline dark:text-white'
|
||||
href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>.
|
||||
</div>
|
||||
@if ($server->settings->is_swarm_worker)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox"
|
||||
id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@endif
|
||||
|
||||
@if ($server->settings->is_swarm_manager)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@if ($server->settings->is_swarm_manager)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox"
|
||||
id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
@else
|
||||
@ -132,7 +136,7 @@ class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-1
|
||||
|
||||
@if ($server->isFunctional())
|
||||
<h3 class="py-4">Settings</h3>
|
||||
<div class="flex gap-2 flex-wrap sm:flex-nowrap">
|
||||
<div class="flex flex-wrap gap-2 sm:flex-nowrap">
|
||||
<x-forms.input id="cleanup_after_percentage" label="Disk cleanup threshold (%)" required
|
||||
helper="The disk cleanup task will run when the disk usage exceeds this threshold." />
|
||||
<x-forms.input id="server.settings.concurrent_builds" label="Number of concurrent builds" required
|
||||
|
@ -20,9 +20,9 @@
|
||||
</svg>Before switching proxies, please read <a class="underline dark:text-white"
|
||||
href="https://coolify.io/docs/knowledge-base/server/proxies#switch-between-proxies">this</a>.</div>
|
||||
@if ($server->proxyType() === 'TRAEFIK_V2')
|
||||
<div class="pb-4">Traefik v2</div>
|
||||
<h4 class="pb-4">Traefik</h4>
|
||||
@elseif ($server->proxyType() === 'CADDY')
|
||||
<div class="pb-4 ">Caddy</div>
|
||||
<h4 class="pb-4 ">Caddy</h4>
|
||||
@endif
|
||||
@if (
|
||||
$server->proxy->last_applied_settings &&
|
||||
|
@ -99,26 +99,28 @@
|
||||
@else
|
||||
<div class="w-64"><x-loading text="Minimum Docker version:" /></div>
|
||||
@endisset
|
||||
@if ($proxy_started)
|
||||
<div class="flex w-64 gap-2">Proxy started: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="currentColor">
|
||||
<path
|
||||
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||
opacity=".2" />
|
||||
<path
|
||||
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||
</g>
|
||||
</svg></div>
|
||||
@else
|
||||
@if ($error)
|
||||
<div class="flex w-64 gap-2">Proxy started: <svg class="w-5 h-5 text-error"
|
||||
@if (!$server->isBuildServer())
|
||||
@if ($proxy_started)
|
||||
<div class="flex w-64 gap-2">Proxy started: <svg class="w-5 h-5 text-success"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||
<g fill="currentColor">
|
||||
<path
|
||||
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||
opacity=".2" />
|
||||
<path
|
||||
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||
</g>
|
||||
</svg></div>
|
||||
@else
|
||||
<div class="w-64"><x-loading text="Proxy started:" /></div>
|
||||
@if ($error)
|
||||
<div class="flex w-64 gap-2">Proxy started: <svg class="w-5 h-5 text-error"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||
</svg></div>
|
||||
@else
|
||||
<div class="w-64"><x-loading text="Proxy started:" /></div>
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
@else
|
||||
|
@ -30,7 +30,6 @@
|
||||
@endif
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<h2 class="pb-4">Executions</h2>
|
||||
<livewire:project.database.backup-executions :backup="$backup" :executions="$executions" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,5 +25,8 @@ class="font-bold text-red-500 dark:text-warning">from the server (if it's reacha
|
||||
@empty
|
||||
<div>No users found other than the root.</div>
|
||||
@endforelse
|
||||
@if ($lots_of_users)
|
||||
<div>There are more users than shown. Please use the search bar to find the user you are looking for.</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
@ -254,14 +254,16 @@
|
||||
$exeuctionId = request()->route('executionId');
|
||||
$execution = ScheduledDatabaseBackupExecution::where('id', $exeuctionId)->firstOrFail();
|
||||
$execution_team_id = $execution->scheduledDatabaseBackup->database->team()?->id;
|
||||
if (is_null($execution_team_id)) {
|
||||
return response()->json(['message' => 'Team not found.'], 404);
|
||||
}
|
||||
if ($team->id !== $execution_team_id) {
|
||||
return response()->json(['message' => 'Permission denied.'], 403);
|
||||
}
|
||||
if (is_null($execution)) {
|
||||
return response()->json(['message' => 'Backup not found.'], 404);
|
||||
if ($team->id !== 0) {
|
||||
if (is_null($execution_team_id)) {
|
||||
return response()->json(['message' => 'Team not found.'], 404);
|
||||
}
|
||||
if ($team->id !== $execution_team_id) {
|
||||
return response()->json(['message' => 'Permission denied.'], 403);
|
||||
}
|
||||
if (is_null($execution)) {
|
||||
return response()->json(['message' => 'Backup not found.'], 404);
|
||||
}
|
||||
}
|
||||
$filename = data_get($execution, 'filename');
|
||||
if ($execution->scheduledDatabaseBackup->database->getMorphClass() === 'App\Models\ServiceDatabase') {
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Webhook\Bitbucket;
|
||||
use App\Http\Controllers\Webhook\Gitea;
|
||||
use App\Http\Controllers\Webhook\Github;
|
||||
use App\Http\Controllers\Webhook\Gitlab;
|
||||
use App\Http\Controllers\Webhook\Stripe;
|
||||
@ -16,6 +17,8 @@
|
||||
|
||||
Route::post('/source/bitbucket/events/manual', [Bitbucket::class, 'manual']);
|
||||
|
||||
Route::post('/source/gitea/events/manual', [Gitea::class, 'manual']);
|
||||
|
||||
Route::post('/payments/stripe/events', [Stripe::class, 'events']);
|
||||
|
||||
Route::get('/waitlist/confirm', [Waitlist::class, 'confirm'])->name('webhooks.waitlist.confirm');
|
||||
|
115
templates/compose/chatwoot.yaml
Normal file
@ -0,0 +1,115 @@
|
||||
# documentation: https://www.chatwoot.com/docs/self-hosted/
|
||||
# slogan: Delightful customer relationships at scale.
|
||||
# tags: chatwoot,chat,api,open,source,rails,redis,postgresql,sidekiq
|
||||
# logo: svgs/chatwoot.svg
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
rails:
|
||||
image: chatwoot/chatwoot:latest
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
environment:
|
||||
- SERVICE_FQDN_CHATWOOT_3000
|
||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||
- FORCE_SSL=false
|
||||
- ENABLE_ACCOUNT_SIGNUP=false
|
||||
- REDIS_URL=redis://default@redis:6379
|
||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
||||
- POSTGRES_DATABASE=chatwoot
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- RAILS_MAX_THREADS=5
|
||||
- NODE_ENV=production
|
||||
- RAILS_ENV=production
|
||||
- INSTALLATION_ENV=docker
|
||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||
- SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
|
||||
- SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
|
||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||
- ACTIVE_STORAGE_SERVICE=local
|
||||
entrypoint: docker/entrypoints/rails.sh
|
||||
command: sh -c "bundle exec rails db:chatwoot_prepare && bundle exec rails s -p 3000 -b 0.0.0.0"
|
||||
volumes:
|
||||
- rails-data:/app/storage
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:3000"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
|
||||
sidekiq:
|
||||
image: chatwoot/chatwoot:latest
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
environment:
|
||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||
- FORCE_SSL=false
|
||||
- ENABLE_ACCOUNT_SIGNUP=false
|
||||
- REDIS_URL=redis://default@redis:6379
|
||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
||||
- POSTGRES_DATABASE=chatwoot
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- RAILS_MAX_THREADS=5
|
||||
- NODE_ENV=production
|
||||
- RAILS_ENV=production
|
||||
- INSTALLATION_ENV=docker
|
||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||
- SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
|
||||
- SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
|
||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||
- ACTIVE_STORAGE_SERVICE=local
|
||||
command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
|
||||
volumes:
|
||||
- sidekiq-data:/app/storage
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "bundle exec rails runner 'puts Sidekiq.redis(&:info)' > /dev/null 2>&1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
postgres:
|
||||
image: postgres:12
|
||||
restart: always
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_DB=chatwoot
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $SERVICE_USER_POSTGRES_USER -d chatwoot -h 127.0.0.1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
restart: always
|
||||
command: ["sh", "-c", "redis-server --requirepass \"$SERVICE_PASSWORD_REDIS\""]
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "PING"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
36
templates/compose/docuseal-with-postgres.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
# documentation: https://www.docuseal.co/
|
||||
# slogan: Document Signing for Everyone free forever for individuals, extensible for businesses and developers. Open Source Alternative to DocuSign, PandaDoc and more.
|
||||
# tags: documentation
|
||||
# logo: svgs/docuseal.png
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
docuseal:
|
||||
image: docuseal/docuseal:latest
|
||||
environment:
|
||||
- SERVICE_FQDN_DOCUSEAL_3000
|
||||
- HOST=${SERVICE_FQDN_DOCUSEAL}
|
||||
- DATABASE_URL=postgresql://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/${POSTGRES_DB}
|
||||
volumes:
|
||||
- docuseal-data:/data
|
||||
depends_on:
|
||||
postgresql:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
postgresql:
|
||||
image: postgres:16-alpine
|
||||
volumes:
|
||||
- postgresql-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- POSTGRES_DB=${POSTGRES_DB:-docuseal}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
19
templates/compose/docuseal.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
# documentation: https://www.docuseal.co/
|
||||
# slogan: Document Signing for Everyone free forever for individuals, extensible for businesses and developers. Open Source Alternative to DocuSign, PandaDoc and more.
|
||||
# tags: documentation
|
||||
# logo: svgs/docuseal.png
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
docuseal:
|
||||
image: docuseal/docuseal:latest
|
||||
environment:
|
||||
- SERVICE_FQDN_DOCUSEAL_3000
|
||||
- HOST=${SERVICE_FQDN_DOCUSEAL}
|
||||
volumes:
|
||||
- docuseal-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
92
templates/compose/glance.yaml
Normal file
@ -0,0 +1,92 @@
|
||||
# documentation: https://github.com/glanceapp/glance
|
||||
# slogan: A self-hosted dashboard that puts all your feeds in one place.
|
||||
# tags: dashboard, server, applications, interface, rrss
|
||||
# logo: svgs/glance.png
|
||||
# port: 8080
|
||||
|
||||
services:
|
||||
glance:
|
||||
image: glanceapp/glance:latest
|
||||
environment:
|
||||
- SERVICE_FQDN_GLANCE_8080
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ./glance-settings
|
||||
target: /app/glance.yml
|
||||
content: |
|
||||
pages:
|
||||
- name: Home
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 8080
|
||||
assets-path: /user/assets
|
||||
columns:
|
||||
- size: small
|
||||
widgets:
|
||||
- type: calendar
|
||||
|
||||
- type: rss
|
||||
limit: 10
|
||||
collapse-after: 3
|
||||
cache: 3h
|
||||
feeds:
|
||||
- url: https://ciechanow.ski/atom.xml
|
||||
- url: https://www.joshwcomeau.com/rss.xml
|
||||
title: Josh Comeau
|
||||
- url: https://samwho.dev/rss.xml
|
||||
- url: https://awesomekling.github.io/feed.xml
|
||||
- url: https://ishadeed.com/feed.xml
|
||||
title: Ahmad Shadeed
|
||||
|
||||
- type: twitch-channels
|
||||
channels:
|
||||
- theprimeagen
|
||||
- heyandras
|
||||
- cohhcarnage
|
||||
- christitustech
|
||||
- blurbs
|
||||
- asmongold
|
||||
- jembawls
|
||||
|
||||
- size: full
|
||||
widgets:
|
||||
- type: hacker-news
|
||||
|
||||
- type: videos
|
||||
channels:
|
||||
- UCR-DXc1voovS8nhAvccRZhg # Jeff Geerling
|
||||
- UCv6J_jJa8GJqFwQNgNrMuww # ServeTheHome
|
||||
- UCOk-gHyjcWZNj3Br4oxwh0A # Techno Tim
|
||||
|
||||
- type: reddit
|
||||
subreddit: selfhosted
|
||||
|
||||
- size: small
|
||||
widgets:
|
||||
- type: weather
|
||||
location: London, United Kingdom
|
||||
|
||||
- type: stocks
|
||||
stocks:
|
||||
- symbol: SPY
|
||||
name: S&P 500
|
||||
- symbol: BTC-USD
|
||||
name: Bitcoin
|
||||
- symbol: NVDA
|
||||
name: NVIDIA
|
||||
- symbol: AAPL
|
||||
name: Apple
|
||||
- symbol: MSFT
|
||||
name: Microsoft
|
||||
- symbol: GOOGL
|
||||
name: Google
|
||||
- symbol: AMD
|
||||
name: AMD
|
||||
- symbol: RDDT
|
||||
name: Reddit
|
||||
- glance-assets:/user/assets
|
||||
healthcheck:
|
||||
test: ["CMD", "echo", "[+] Should be working fine."]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
117
templates/compose/huly.yaml
Normal file
@ -0,0 +1,117 @@
|
||||
# ignore: true
|
||||
# documentation: https://huly.io/
|
||||
# slogan: Open Source All-in-One Project Management Platform
|
||||
# tags: linear,jira,slack,project,management,notion,motion
|
||||
# port: 8080
|
||||
|
||||
services:
|
||||
mongodb:
|
||||
image: "mongo:7-jammy"
|
||||
container_name: mongodb
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
volumes:
|
||||
- huly-db:/data/db
|
||||
minio:
|
||||
image: "minio/minio"
|
||||
command: server /data --address ":9000" --console-address ":9001"
|
||||
volumes:
|
||||
- huly-files:/data
|
||||
elastic:
|
||||
image: "elasticsearch:7.14.2"
|
||||
command: |
|
||||
/bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment;
|
||||
/usr/local/bin/docker-entrypoint.sh eswrapper"
|
||||
volumes:
|
||||
- huly-elastic:/usr/share/elasticsearch/data
|
||||
environment:
|
||||
- ELASTICSEARCH_PORT_NUMBER=9200
|
||||
- BITNAMI_DEBUG=true
|
||||
- discovery.type=single-node
|
||||
- ES_JAVA_OPTS=-Xms1024m -Xmx1024m
|
||||
- http.cors.enabled=true
|
||||
- http.cors.allow-origin=http://localhost:8082
|
||||
healthcheck:
|
||||
test: curl -s http://127.0.0.1:9200/_cluster/health | grep -vq '"status":"red"'
|
||||
interval: 5s
|
||||
retries: 10
|
||||
account:
|
||||
image: hardcoreeng/account:v0.6.246
|
||||
environment:
|
||||
- SERVICE_FQDN_HULY_3000
|
||||
- SERVER_PORT=3000
|
||||
- SERVER_SECRET=$SERVICE_PASSWORD_SECRET
|
||||
- MONGO_URL=mongodb://mongodb:27017
|
||||
- TRANSACTOR_URL=ws://transactor:3333
|
||||
- ENDPOINT_URL=ws://transactor:3333
|
||||
- MINIO_ENDPOINT=minio
|
||||
- MINIO_ACCESS_KEY=minioadmin
|
||||
- MINIO_SECRET_KEY=minioadmin
|
||||
- FRONT_URL=http://front:8080
|
||||
- INIT_WORKSPACE=demo-tracker
|
||||
- MODEL_ENABLED=*
|
||||
- ACCOUNTS_URL=http://localhost:3000
|
||||
front:
|
||||
image: hardcoreeng/front:v0.6.246
|
||||
environment:
|
||||
- SERVICE_FQDN_HULY_8080
|
||||
- MONGO_URL=mongodb://mongodb:27017
|
||||
- SERVER_PORT=8080
|
||||
- SERVER_SECRET=$SERVICE_PASSWORD_SECRET
|
||||
- ACCOUNTS_URL=http://account:3000
|
||||
- REKONI_URL=http://rekoni:4004
|
||||
- CALENDAR_URL=http://localhost:8095
|
||||
- GMAIL_URL=http://localhost:8088
|
||||
- TELEGRAM_URL=http://localhost:8086
|
||||
- UPLOAD_URL=/files
|
||||
- TRANSACTOR_URL=ws://transactor:3333
|
||||
- ELASTIC_URL=http://elastic:9200
|
||||
- COLLABORATOR_URL=ws://collaborator:3078
|
||||
- COLLABORATOR_API_URL=http://collaborator:3078
|
||||
- MINIO_ENDPOINT=minio
|
||||
- MINIO_ACCESS_KEY=minioadmin
|
||||
- MINIO_SECRET_KEY=minioadmin
|
||||
- TITLE=Huly Self Hosted
|
||||
- DEFAULT_LANGUAGE=en
|
||||
- LAST_NAME_FIRST=true
|
||||
restart: unless-stopped
|
||||
collaborator:
|
||||
image: hardcoreeng/collaborator:v0.6.246
|
||||
environment:
|
||||
- COLLABORATOR_PORT=3078
|
||||
- SECRET=secret
|
||||
- ACCOUNTS_URL=http://account:3000
|
||||
- TRANSACTOR_URL=ws://transactor:3333
|
||||
- UPLOAD_URL=/files
|
||||
- MONGO_URL=mongodb://mongodb:27017
|
||||
- MINIO_ENDPOINT=minio
|
||||
- MINIO_ACCESS_KEY=minioadmin
|
||||
- MINIO_SECRET_KEY=minioadmin
|
||||
transactor:
|
||||
image: hardcoreeng/transactor:v0.6.246
|
||||
environment:
|
||||
- SERVER_PORT=3333
|
||||
- ELASTIC_INDEX_NAME=huly
|
||||
- SERVER_SECRET=$SERVICE_PASSWORD_SECRET
|
||||
- SERVER_CURSOR_MAXTIMEMS=30000
|
||||
- ELASTIC_URL=http://elastic:9200
|
||||
- MONGO_URL=mongodb://mongodb:27017
|
||||
- METRICS_CONSOLE=false
|
||||
- METRICS_FILE=metrics.txt
|
||||
- MINIO_ENDPOINT=minio
|
||||
- MINIO_ACCESS_KEY=minioadmin
|
||||
- MINIO_SECRET_KEY=minioadmin
|
||||
- REKONI_URL=http://rekoni:4004
|
||||
- FRONT_URL=http://localhost:8087
|
||||
- SERVER_PROVIDER=ws
|
||||
- ACCOUNTS_URL=http://account:3000
|
||||
- LAST_NAME_FIRST=true
|
||||
- UPLOAD_URL=/files
|
||||
restart: unless-stopped
|
||||
rekoni:
|
||||
image: hardcoreeng/rekoni-service:latest
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 500M
|
20
templates/compose/mediawiki.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
# documentation: https://www.mediawiki.org
|
||||
# slogan: MediaWiki is a collaboration and documentation platform brought to you by a vibrant community.
|
||||
# tags: wiki, collaboration, documentation
|
||||
# logo: svgs/mediawiki.ico
|
||||
# port: 80
|
||||
|
||||
services:
|
||||
mediawiki:
|
||||
image: mediawiki:latest
|
||||
environment:
|
||||
- SERVICE_FQDN_MEDIAWIKI_80
|
||||
volumes:
|
||||
- mediawiki-images:/var/www/html/images
|
||||
- mediawiki-sqlite:/var/www/html/data
|
||||
- ./LocalSettings.php:/var/www/html/LocalSettings.php
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:80"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
@ -285,7 +285,7 @@ services:
|
||||
"CMD",
|
||||
"node",
|
||||
"-e",
|
||||
"require('http').get('http://127.0.0.1:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})",
|
||||
"require('http').get('http://127.0.0.1:3000/api/profile', (r) => {if (r.statusCode !== 200) process.exit(1); else process.exit(0); }).on('error', () => process.exit(1))",
|
||||
]
|
||||
timeout: 5s
|
||||
interval: 5s
|
||||
@ -911,6 +911,7 @@ services:
|
||||
- PGRST_APP_SETTINGS_JWT_SECRET=${SERVICE_PASSWORD_JWT}
|
||||
- PGRST_APP_SETTINGS_JWT_EXP=${JWT_EXPIRY:-3600}
|
||||
command: "postgrest"
|
||||
exclude_from_hc: true
|
||||
supabase-auth:
|
||||
image: supabase/gotrue:v2.149.0
|
||||
depends_on:
|
||||
@ -1054,7 +1055,7 @@ services:
|
||||
content: |
|
||||
#!/bin/sh
|
||||
/usr/bin/mc alias set supabase-minio http://supabase-minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD};
|
||||
/usr/bin/mc mb supabase-minio/stub;
|
||||
/usr/bin/mc mb --ignore-existing supabase-minio/stub;
|
||||
exit 0
|
||||
|
||||
supabase-storage:
|
||||
@ -1162,6 +1163,11 @@ services:
|
||||
depends_on:
|
||||
supabase-analytics:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "echo", "Edge Functions is healthy"]
|
||||
timeout: 5s
|
||||
interval: 5s
|
||||
retries: 3
|
||||
environment:
|
||||
- JWT_SECRET=${SERVICE_PASSWORD_JWT}
|
||||
- SUPABASE_URL=http://supabase-kong:8000
|
||||
|
@ -1,11 +1,10 @@
|
||||
{
|
||||
"coolify": {
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.285"
|
||||
"version": "4.0.0-beta.286"
|
||||
},
|
||||
"sentinel": {
|
||||
"version": "0.0.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|