Compare commits

...

5 Commits

Author SHA1 Message Date
Benjamin Bellamy d2d5eadfed Merge branch 'docs/fix-readme' into 'develop'
docs: correct guidelines URL

See merge request adaures/castopod!330
2024-04-26 19:30:41 +00:00
Yassine Doghri 51b064d67a refactor(icons): use php-icons library to load and display icons 2024-04-26 17:57:25 +00:00
Yassine Doghri fe73e9fae9 fix(platforms): add platforms service + reduce memory consumption when rendering platform cards 2024-04-26 10:45:30 +00:00
Yassine Doghri d4a36f811b chore: update CodeIgniter to 4.5.1 + other dependencies to latest 2024-04-26 09:26:22 +00:00
Benjamin Bellamy ea502b12b3 docs: correct guidelines URL 2024-03-18 14:34:20 +01:00
388 changed files with 4328 additions and 3730 deletions

View File

@ -4,7 +4,7 @@
# ⚠️ NOT optimized for production
# should be used only for development purposes
#---------------------------------------------------
FROM php:8.1-fpm
FROM php:8.2-fpm
LABEL maintainer="Yassine Doghri <yassine@doghri.fr>"

View File

@ -12,7 +12,7 @@ services:
environment:
CI_ENVIRONMENT: development
vite_environment: development
app_forceGlobalSecureRequests: false
app_forceGlobalSecureRequests: 0 #false
app_baseURL: http://localhost:8080/
media_baseURL: http://localhost:8080/
admin_gateway: cp-admin
@ -23,7 +23,7 @@ services:
database_default_username: castopod
database_default_password: castopod
database_default_DBPrefix: cp_
restapi_enabled: true
restapi_enabled: 1 #true
email_fromEmail: hello@castopod.local
email_SMTPCrypto: ""
email_SMTPHost: mailpit

1
.gitignore vendored
View File

@ -132,7 +132,6 @@ tmp/
/results/
/phpunit*.xml
/.phpunit.*.cache
# js package manager
yarn.lock

View File

@ -32,7 +32,7 @@ please contact us directly by email at
Contributions are always welcome!
See the
[contribution guidelines](https://docs.castopod.org/contributing/guidelines) for
[contribution guidelines](https://docs.castopod.org/contributing/guidelines.html) for
ways to get started.
> **Note**

View File

@ -1,6 +1,2 @@
<IfModule authz_core_module>
Require all denied
</IfModule>
<IfModule !authz_core_module>
Deny from all
</IfModule>
<IfModule authz_core_module> Require all denied </IfModule>
<IfModule !authz_core_module> Deny from all </IfModule>

View File

@ -61,6 +61,30 @@ class App extends BaseConfig
*/
public string $uriProtocol = 'REQUEST_URI';
/*
*--------------------------------------------------------------------------
* Allowed URL Characters
*--------------------------------------------------------------------------
*
* This lets you specify which characters are permitted within your URLs.
* When someone tries to submit a URL with disallowed characters they will
* get a warning message.
*
* As a security measure you are STRONGLY encouraged to restrict URLs to
* as few characters as possible.
*
* By default, only these are allowed: `a-z 0-9~%.:_-`
*
* Set an empty string to allow all characters -- but only if you are insane.
*
* The configured value is actually a regular expression character group
* and it will be used as: '/\A[<permittedURIChars>]+\z/iu'
*
* DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
*
*/
public string $permittedURIChars = 'a-z 0-9~%.:_\-@';
/**
* --------------------------------------------------------------------------
* Default Locale

View File

@ -29,23 +29,17 @@ class Autoload extends AutoloadConfig
* their location on the file system. These are used by the autoloader
* to locate files the first time they have been instantiated.
*
* The '/app' and '/system' directories are already mapped for you.
* you may change the name of the 'App' namespace if you wish,
* The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are
* already mapped for you.
*
* You may change the name of the 'App' namespace if you wish,
* but this should be done prior to creating any namespaced classes,
* else you will need to modify all of those classes for this to work.
*
* Prototype:
*
* $psr4 = [
* 'CodeIgniter' => SYSTEMPATH,
* 'App' => APPPATH
* ];
*
* @var array<string, list<string>|string>
*/
public $psr4 = [
APP_NAMESPACE => APPPATH,
'Config' => APPPATH . 'Config/',
'Modules' => ROOTPATH . 'modules/',
'Modules\Admin' => ROOTPATH . 'modules/Admin/',
'Modules\Analytics' => ROOTPATH . 'modules/Analytics/',
@ -68,7 +62,6 @@ class Autoload extends AutoloadConfig
/**
* -------------------------------------------------------------------
* Class Map
* -------------------------------------------------------------------
* The class map provides a map of class names and their exact
* location on the drive. Classes loaded in this manner will have
@ -115,5 +108,5 @@ class Autoload extends AutoloadConfig
*
* @var list<string>
*/
public $helpers = ['auth', 'setting'];
public $helpers = ['auth', 'setting', 'icons'];
}

View File

@ -11,8 +11,10 @@ declare(strict_types=1);
*
* If you set 'display_errors' to '1', CI4's detailed error report will show.
*/
error_reporting(E_ALL & ~E_DEPRECATED);
// If you want to suppress more types of errors.
// error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
ini_set('display_errors', '0');
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
/**
* --------------------------------------------------------------------------

View File

@ -48,25 +48,6 @@ class Cache extends BaseConfig
*/
public string $storePath = WRITEPATH . 'cache/';
/**
* --------------------------------------------------------------------------
* Cache Include Query String
* --------------------------------------------------------------------------
*
* Whether to take the URL query string into consideration when generating
* output cache files. Valid options are:
*
* false = Disabled
* true = Enabled, take all query parameters into account.
* Please be aware that this may result in numerous cache
* files generated for the same page over and over again.
* ['q'] = Enabled, but only take into account the specified list
* of query parameters.
*
* @var boolean|string[]
*/
public bool | array $cacheQueryString = false;
/**
* --------------------------------------------------------------------------
* Key Prefix
@ -170,4 +151,23 @@ class Cache extends BaseConfig
'redis' => RedisHandler::class,
'wincache' => WincacheHandler::class,
];
/**
* --------------------------------------------------------------------------
* Web Page Caching: Cache Include Query String
* --------------------------------------------------------------------------
*
* Whether to take the URL query string into consideration when generating
* output cache files. Valid options are:
*
* false = Disabled
* true = Enabled, take all query parameters into account.
* Please be aware that this may result in numerous cache
* files generated for the same page over and over again.
* ['q'] = Enabled, but only take into account the specified list
* of query parameters.
*
* @var bool|list<string>
*/
public $cacheQueryString = false;
}

View File

@ -35,28 +35,28 @@ class ContentSecurityPolicy extends BaseConfig
/**
* Will default to self if not overridden
*
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $defaultSrc = null;
/**
* Lists allowed scripts' URLs.
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $scriptSrc = 'self';
/**
* Lists allowed stylesheets' URLs.
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $styleSrc = 'self';
/**
* Defines the origins from which images can be loaded.
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $imageSrc = 'self';
@ -65,35 +65,35 @@ class ContentSecurityPolicy extends BaseConfig
*
* Will default to self if not overridden
*
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $baseURI = null;
/**
* Lists the URLs for workers and embedded frame contents
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $childSrc = 'self';
/**
* Limits the origins that you can connect to (via XHR, WebSockets, and EventSource).
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $connectSrc = 'self';
/**
* Specifies the origins that can serve web fonts.
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $fontSrc;
/**
* Lists valid endpoints for submission from `<form>` tags.
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $formAction = 'self';
@ -102,47 +102,47 @@ class ContentSecurityPolicy extends BaseConfig
* `<embed>`, and `<applet>` tags. This directive can't be used in `<meta>` tags and applies only to non-HTML
* resources.
*
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $frameAncestors = null;
/**
* The frame-src directive restricts the URLs which may be loaded into nested browsing contexts.
*
* @var string[]|string|null
* @var list<string>|string|null
*/
public string | array | null $frameSrc = null;
/**
* Restricts the origins allowed to deliver video and audio.
*
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $mediaSrc = null;
/**
* Allows control over Flash and other plugins.
*
* @var string|string[]
* @var list<string>|string
*/
public string | array $objectSrc = 'self';
/**
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $manifestSrc = null;
/**
* Limits the kinds of plugins a page may invoke.
*
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $pluginTypes = null;
/**
* List of actions allowed.
*
* @var string|string[]|null
* @var list<string>|string|null
*/
public string | array | null $sandbox = null;

107
app/Config/Cors.php Normal file
View File

@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
namespace Config;
use CodeIgniter\Config\BaseConfig;
/**
* Cross-Origin Resource Sharing (CORS) Configuration
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
*/
class Cors extends BaseConfig
{
/**
* The default CORS configuration.
*
* @var array{
* allowedOrigins: list<string>,
* allowedOriginsPatterns: list<string>,
* supportsCredentials: bool,
* allowedHeaders: list<string>,
* exposedHeaders: list<string>,
* allowedMethods: list<string>,
* maxAge: int,
* }
*/
public array $default = [
/**
* Origins for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* E.g.:
* - ['http://localhost:8080']
* - ['https://www.example.com']
*/
'allowedOrigins' => [],
/**
* Origin regex patterns for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* NOTE: A pattern specified here is part of a regular expression. It will
* be actually `#\A<pattern>\z#`.
*
* E.g.:
* - ['https://\w+\.example\.com']
*/
'allowedOriginsPatterns' => [],
/**
* Weather to send the `Access-Control-Allow-Credentials` header.
*
* The Access-Control-Allow-Credentials response header tells browsers whether
* the server allows cross-origin HTTP requests to include credentials.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
*/
'supportsCredentials' => false,
/**
* Set headers to allow.
*
* The Access-Control-Allow-Headers response header is used in response to
* a preflight request which includes the Access-Control-Request-Headers to
* indicate which HTTP headers can be used during the actual request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
*/
'allowedHeaders' => [],
/**
* Set headers to expose.
*
* The Access-Control-Expose-Headers response header allows a server to
* indicate which response headers should be made available to scripts running
* in the browser, in response to a cross-origin request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
*/
'exposedHeaders' => [],
/**
* Set methods to allow.
*
* The Access-Control-Allow-Methods response header specifies one or more
* methods allowed when accessing a resource in response to a preflight
* request.
*
* E.g.:
* - ['GET', 'POST', 'PUT', 'DELETE']
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
*/
'allowedMethods' => [],
/**
* Set how many seconds the results of a preflight request can be cached.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
*/
'maxAge' => 7200,
];
}

View File

@ -45,6 +45,11 @@ class Database extends Config
'failover' => [],
'port' => 3306,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
/**
@ -64,7 +69,7 @@ class Database extends Config
'pConnect' => false,
'DBDebug' => true,
'charset' => 'utf8',
'DBCollat' => 'utf8_general_ci',
'DBCollat' => '',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
@ -73,6 +78,11 @@ class Database extends Config
'port' => 3306,
'foreignKeys' => true,
'busyTimeout' => 1000,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
//--------------------------------------------------------------------

View File

@ -33,7 +33,7 @@ class Exceptions extends BaseConfig
* Any status codes here will NOT be logged if logging is turned on.
* By default, only 404 (Page Not Found) exceptions are ignored.
*
* @var int[]
* @var list<int>
*/
public array $ignoreCodes = [404];
@ -56,7 +56,7 @@ class Exceptions extends BaseConfig
* In order to specify 2 levels, use "/" to separate.
* ex. ['server', 'setup/password', 'secret_token']
*
* @var string[]
* @var list<string>
*/
public array $sensitiveDataInTrace = [];

View File

@ -11,22 +11,21 @@ use CodeIgniter\Config\BaseConfig;
*/
class Feature extends BaseConfig
{
/**
* Enable multiple filters for a route or not.
*
* If you enable this:
* - CodeIgniter\CodeIgniter::handleRequest() uses:
* - CodeIgniter\Filters\Filters::enableFilters(), instead of enableFilter()
* - CodeIgniter\CodeIgniter::tryToRouteIt() uses:
* - CodeIgniter\Router\Router::getFilters(), instead of getFilter()
* - CodeIgniter\Router\Router::handle() uses:
* - property $filtersInfo, instead of $filterInfo
* - CodeIgniter\Router\RouteCollection::getFiltersForRoute(), instead of getFilterForRoute()
*/
public bool $multipleFilters = false;
/**
* Use improved new auto routing instead of the default legacy version.
*/
public bool $autoRoutesImproved = false;
/**
* Use filter execution order in 4.4 or before.
*/
public bool $oldFilterOrder = false;
/**
* The behavior of `limit(0)` in Query Builder.
*
* If true, `limit(0)` returns all records. (the behavior of 4.4.x or before in version 4.x.)
* If false, `limit(0)` returns no records. (the behavior of 3.1.9 or later in version 3.x.)
*/
public bool $limitZeroAsAll = true;
}

View File

@ -8,8 +8,11 @@ use App\Filters\AllowCorsFilter;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\ForceHTTPS;
use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders;
use Modules\Auth\Filters\PermissionFilter;
@ -18,8 +21,10 @@ class Filters extends BaseConfig
/**
* Configures aliases for Filter classes to make reading things nicer and simpler.
*
* @var array<string, class-string|list<class-string>> [filter_name => classname]
* or [filter_name => [classname1, classname2, ...]]
* @var array<string, class-string|list<class-string>>
*
* [filter_name => classname]
* or [filter_name => [classname1, classname2, ...]]
*/
public array $aliases = [
'csrf' => CSRF::class,
@ -28,12 +33,41 @@ class Filters extends BaseConfig
'invalidchars' => InvalidChars::class,
'secureheaders' => SecureHeaders::class,
'allow-cors' => AllowCorsFilter::class,
'cors' => Cors::class,
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
];
/**
* List of special required filters.
*
* The filters listed here are special. They are applied before and after
* other kinds of filters, and always applied even if a route does not exist.
*
* Filters set by default provide framework functionality. If removed,
* those functions will no longer work.
*
* @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters
*
* @var array{before: list<string>, after: list<string>}
*/
public array $required = [
'before' => [
'forcehttps', // Force Global Secure Requests
'pagecache', // Web Page Caching
],
'after' => [
'pagecache', // Web Page Caching
'performance', // Performance Metrics
'toolbar', // Debug Toolbar
],
];
/**
* List of filter aliases that are always applied before and after every request.
*
* @var array<string, array<string, array<string, string>>>|array<string, list<string>>
* @var array<string, array<string, array<string, string|array<string>>>>>|array<string, list<string>>
*/
public array $globals = [
'before' => [
@ -44,7 +78,6 @@ class Filters extends BaseConfig
// 'invalidchars',
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
@ -53,12 +86,12 @@ class Filters extends BaseConfig
/**
* List of filter aliases that works on a particular HTTP method (GET, POST, etc.).
*
* Example: 'post' => ['foo', 'bar']
* Example: 'POST' => ['foo', 'bar']
*
* If you use this, you should disable auto-routing because auto-routing permits any HTTP method to access a
* controller. Accessing the controller with a method you dont expect could bypass the filter.
*
* @var array<string, string[]>
* @var array<string, list<string>>
*/
public array $methods = [];
@ -67,7 +100,7 @@ class Filters extends BaseConfig
*
* Example: 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
*
* @var array<string, array<string, string[]>>
* @var array<string, array<string, list<string>>>
*/
public array $filters = [];

View File

@ -24,7 +24,7 @@ class Format extends BaseConfig
* These formats are only checked when the data passed to the respond()
* method is an array.
*
* @var string[]
* @var list<string>
*/
public array $supportedResponseFormats = [
'application/json',

View File

@ -28,8 +28,10 @@ class Generators extends BaseConfig
* @var array<string, string>
*/
public array $views = [
'make:cell' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
'make:cell_view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
'make:cell' => [
'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
],
'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php',
'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php',
'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php',

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Config;
use CodeIgniter\Config\BaseConfig;
use Kint\Parser\ConstructablePluginInterface;
use Kint\Renderer\AbstractRenderer;
use Kint\Renderer\Rich\TabPluginInterface;
@ -20,7 +19,7 @@ use Kint\Renderer\Rich\ValuePluginInterface;
*
* @see https://kint-php.github.io/kint/ for details on these settings.
*/
class Kint extends BaseConfig
class Kint
{
/*
|--------------------------------------------------------------------------

View File

@ -38,7 +38,7 @@ class Logger extends BaseConfig
* For a live site you'll usually enable Critical or higher (3) to be logged otherwise
* your log files will fill up very fast.
*
* @var int|int[]
* @var int|list<int>
*/
public int | array $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
@ -75,7 +75,7 @@ class Logger extends BaseConfig
* Handlers are executed in the order defined in this array, starting with
* the handler on top and continuing down.
*
* @var array<string, mixed>
* @var array<class-string, array<string, int|list<string>|string>>
*/
public array $handlers = [
/*

View File

@ -22,7 +22,7 @@ class Mimes
/**
* Map of extensions to mime types.
*
* @var array<string, string|string[]>
* @var array<string, list<string>|string>
*/
public static $mimes = [
'hqx' => [

34
app/Config/Optimize.php Normal file
View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Config;
/**
* Optimization Configuration.
*
* NOTE: This class does not extend BaseConfig for performance reasons.
* So you cannot replace the property values with Environment Variables.
*
* @immutable
*/
class Optimize
{
/**
* --------------------------------------------------------------------------
* Config Caching
* --------------------------------------------------------------------------
*
* @see https://codeigniter.com/user_guide/concepts/factories.html#config-caching
*/
public bool $configCacheEnabled = false;
/**
* --------------------------------------------------------------------------
* Config Caching
* --------------------------------------------------------------------------
*
* @see https://codeigniter.com/user_guide/concepts/autoloader.html#file-locator-caching
*/
public bool $locatorCacheEnabled = false;
}

View File

@ -12,13 +12,14 @@ use CodeIgniter\Config\Routing as BaseRouting;
class Routing extends BaseRouting
{
/**
* For Defined Routes.
* An array of files that contain route definitions.
* Route files are read in order, with the first match
* found taking precedence.
*
* Default: APPPATH . 'Config/Routes.php'
*
* @var string[]
* @var list<string>
*/
public array $routeFiles = [
APPPATH . 'Config/Routes.php',
@ -34,6 +35,7 @@ class Routing extends BaseRouting
];
/**
* For Defined Routes and Auto Routing.
* The default namespace to use for Controllers when no other
* namespace has been specified.
*
@ -42,6 +44,7 @@ class Routing extends BaseRouting
public string $defaultNamespace = 'App\Controllers';
/**
* For Auto Routing.
* The default controller to use when no other controller has been
* specified.
*
@ -50,6 +53,7 @@ class Routing extends BaseRouting
public string $defaultController = 'HomeController';
/**
* For Defined Routes and Auto Routing.
* The default method to call on the controller when no other
* method has been set in the route.
*
@ -58,7 +62,8 @@ class Routing extends BaseRouting
public string $defaultMethod = 'index';
/**
* Whether to translate dashes in URIs to underscores.
* For Auto Routing.
* Whether to translate dashes in URIs for controller/method to underscores.
* Primarily useful when using the auto-routing.
*
* Default: false
@ -94,6 +99,7 @@ class Routing extends BaseRouting
public bool $autoRoute = false;
/**
* For Defined Routes.
* If TRUE, will enable the use of the 'prioritize' option
* when defining routes.
*
@ -102,7 +108,16 @@ class Routing extends BaseRouting
public bool $prioritize = false;
/**
* Map of URI segments and namespaces. For Auto Routing (Improved).
* For Defined Routes.
* If TRUE, matched multiple URI segments will be passed as one parameter.
*
* Default: false
*/
public bool $multipleSegmentsOneParam = false;
/**
* For Auto Routing (Improved).
* Map of URI segments and namespaces.
*
* The key is the first URI segment. The value is the controller namespace.
* E.g.,
@ -113,4 +128,15 @@ class Routing extends BaseRouting
* @var array<string, string> [ uri_segment => namespace ]
*/
public array $moduleRoutes = [];
/**
* For Auto Routing (Improved).
* Whether to translate dashes in URIs for controller/method to CamelCase.
* E.g., blog-controller -> BlogController
*
* If you enable this, $translateURIDashes is ignored.
*
* Default: false
*/
public bool $translateUriToCamelCase = false;
}

View File

@ -80,9 +80,9 @@ class Security extends BaseConfig
* CSRF Redirect
* --------------------------------------------------------------------------
*
* Redirect to previous page with error on failure.
* @see https://codeigniter4.github.io/userguide/libraries/security.html#redirection-on-failure
*/
public bool $redirect = false;
public bool $redirect = (ENVIRONMENT === 'production');
/**
* --------------------------------------------------------------------------

View File

@ -37,8 +37,8 @@ class Services extends BaseService
return static::getSharedInstance('router', $routes, $request);
}
$routes = $routes ?? static::routes();
$request = $request ?? static::request();
$routes ??= static::routes();
$request ??= static::request();
return new Router($routes, $request);
}
@ -53,7 +53,7 @@ class Services extends BaseService
return static::getSharedInstance('negotiator', $request);
}
$request = $request ?? static::request();
$request ??= static::request();
return new Negotiate($request);
}

View File

@ -101,4 +101,29 @@ class Session extends BaseConfig
* DB Group for the database session.
*/
public ?string $DBGroup = null;
/**
* --------------------------------------------------------------------------
* Lock Retry Interval (microseconds)
* --------------------------------------------------------------------------
*
* This is used for RedisHandler.
*
* Time (microseconds) to wait if lock cannot be acquired.
* The default is 100,000 microseconds (= 0.1 seconds).
*/
public int $lockRetryInterval = 100_000;
/**
* --------------------------------------------------------------------------
* Lock Max Retries
* --------------------------------------------------------------------------
*
* This is used for RedisHandler.
*
* Maximum number of lock acquisition attempts.
* The default is 300 times. That is lock timeout is about 30 (0.1 * 300)
* seconds.
*/
public int $lockMaxRetries = 300;
}

View File

@ -33,7 +33,7 @@ class Toolbar extends BaseConfig
* List of toolbar collectors that will be called when Debug Toolbar
* fires up and collects data from.
*
* @var string[]
* @var list<class-string>
*/
public array $collectors = [
Timers::class,
@ -51,7 +51,7 @@ class Toolbar extends BaseConfig
* Collect Var Data
* --------------------------------------------------------------------------
*
* If set to false var data from the views will not be colleted. Useful to
* If set to false var data from the views will not be collected. Useful to
* avoid high memory usage when there are lots of data passed to the view.
*/
public bool $collectVarData = true;
@ -102,7 +102,7 @@ class Toolbar extends BaseConfig
*
* NOTE: The ROOTPATH will be prepended to all values.
*
* @var string[]
* @var list<string>
*/
public array $watchedDirectories = ['app', 'modules', 'themes'];
@ -114,7 +114,7 @@ class Toolbar extends BaseConfig
* Contains an array of file extensions that will be watched for changes and
* used to determine if the hot-reload feature should reload the page or not.
*
* @var string[]
* @var list<string>
*/
public array $watchedExtensions = ['php', 'css', 'js', 'html', 'svg', 'json', 'env'];
}

View File

@ -16,7 +16,7 @@ class Validation extends BaseConfig
/**
* Stores the classes that contain the rules that are available.
*
* @var string[]
* @var list<string>
*/
public array $ruleSets = [
Rules::class,

View File

@ -9,8 +9,8 @@ use CodeIgniter\View\ViewDecoratorInterface;
use ViewComponents\Decorator;
/**
* @phpstan-type ParserCallable (callable(mixed): mixed)
* @phpstan-type ParserCallableString (callable(mixed): mixed)&string
* @phpstan-type parser_callable (callable(mixed): mixed)
* @phpstan-type parser_callable_string (callable(mixed): mixed)&string
*/
class View extends BaseView
{
@ -31,8 +31,8 @@ class View extends BaseView
*
* Examples: { title|esc(js) } { created_on|date(Y-m-d)|esc(attr) }
*
* @var array<string, string>
* @phpstan-var array<string, ParserCallableString>
* @var array<string, string>
* @phpstan-var array<string, parser_callable_string>
*/
public $filters = [];
@ -40,8 +40,8 @@ class View extends BaseView
* Parser Plugins provide a way to extend the functionality provided by the core Parser by creating aliases that
* will be replaced with any callable. Can be single or tag pair.
*
* @var array<string, array<string>|callable|string>
* @phpstan-var array<string, array<ParserCallableString>|ParserCallableString|ParserCallable>
* @var array<string, callable|list<string>|string>
* @phpstan-var array<string, list<parser_callable_string>|parser_callable_string|parser_callable>
*/
public $plugins = [];
@ -51,7 +51,7 @@ class View extends BaseView
*
* All classes must implement CodeIgniter\View\ViewDecoratorInterface
*
* @var class-string<ViewDecoratorInterface>[]
* @var list<class-string<ViewDecoratorInterface>>
*/
public array $decorators = [Decorator::class];
}

View File

@ -13,8 +13,6 @@ use Psr\Log\LoggerInterface;
use ViewThemes\Theme;
/**
* Class BaseController
*
* BaseController provides a convenient place for loading components and performing functions that are needed by all
* your controllers. Extend this class in any new controllers: class Home extends BaseController
*
@ -41,7 +39,7 @@ abstract class BaseController extends Controller
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* @var string[]
* @var list<string>
*/
protected $helpers = [];

View File

@ -40,7 +40,7 @@ class EpisodeAudioController extends Controller
* An array of helpers to be loaded automatically upon class instantiation. These helpers will be available to all
* other controllers that extend Analytics.
*
* @var string[]
* @var list<string>
*/
protected $helpers = ['analytics'];

View File

@ -106,9 +106,7 @@ class EpisodeController extends BaseController
// The page cache is set to a decade so it is deleted manually upon podcast update
return view('episode/comments', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -157,9 +155,7 @@ class EpisodeController extends BaseController
// The page cache is set to a decade so it is deleted manually upon podcast update
return view('episode/activity', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -218,9 +214,7 @@ class EpisodeController extends BaseController
// The page cache is set to a decade so it is deleted manually upon podcast update
return view('episode/chapters', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -284,9 +278,7 @@ class EpisodeController extends BaseController
// The page cache is set to a decade so it is deleted manually upon podcast update
return view('episode/transcript', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -339,9 +331,7 @@ class EpisodeController extends BaseController
// The page cache is set to a decade so it is deleted manually upon podcast update
return view('embed', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -420,11 +410,9 @@ class EpisodeController extends BaseController
* get comments: aggregated replies from posts referring to the episode
*/
$episodeComments = model(PostModel::class)
->whereIn('in_reply_to_id', function (BaseBuilder $builder): BaseBuilder {
return $builder->select('id')
->from('fediverse_posts')
->where('episode_id', $this->episode->id);
})
->whereIn('in_reply_to_id', fn (BaseBuilder $builder): BaseBuilder => $builder->select('id')
->from('fediverse_posts')
->where('episode_id', $this->episode->id))
->where('`published_at` <= UTC_TIMESTAMP()', null, false)
->orderBy('published_at', 'ASC');

View File

@ -79,13 +79,7 @@ class FeedController extends Controller
);
cache()
->save(
$cacheName,
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
->save($cacheName, $found, $secondsToNextUnpublishedEpisode ?: DECADE);
}
return $this->response->setXML($found);

View File

@ -96,9 +96,7 @@ class PodcastController extends BaseController
);
return view('podcast/activity', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -148,9 +146,7 @@ class PodcastController extends BaseController
);
return view('podcast/about', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}
@ -270,9 +266,7 @@ class PodcastController extends BaseController
$this->podcast->id,
);
return view('podcast/episodes', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache' => $secondsToNextUnpublishedEpisode ?: DECADE,
'cache_name' => $cacheName,
]);
}

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;

View File

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
/**
* CodeIgniter 4.5.1 introduces new DataCaster class that breaks deserialization of import queue tasks.
* This just removes them altogether.
*/
class ClearImportQueue extends Migration
{
public function up(): void
{
service('settings')->forget('Import.queue');
}
public function down(): void
{
// nothing
}
}

View File

@ -77,34 +77,32 @@ class FakePodcastsAnalyticsSeeder extends Seeder
for (
$lineNumber = 0;
$lineNumber < rand(1, (int) $probability1);
$lineNumber < random_int(1, (int) $probability1);
++$lineNumber
) {
$probability2 = floor(exp(6 - $age / 20)) + 10;
$player =
$jsonUserAgents[
rand(1, count($jsonUserAgents) - 1)
random_int(1, count($jsonUserAgents) - 1)
];
$service =
$jsonRSSUserAgents[
rand(1, count($jsonRSSUserAgents) - 1)
random_int(1, count($jsonRSSUserAgents) - 1)
]['slug'];
$app = isset($player['app']) ? $player['app'] : '';
$device = isset($player['device'])
? $player['device']
: '';
$os = isset($player['os']) ? $player['os'] : '';
$isBot = isset($player['bot']) ? $player['bot'] : 0;
$app = $player['app'] ?? '';
$device = $player['device'] ?? '';
$os = $player['os'] ?? '';
$isBot = $player['bot'] ?? 0;
$fakeIp =
rand(0, 255) .
random_int(0, 255) .
'.' .
rand(0, 255) .
random_int(0, 255) .
'.' .
rand(0, 255) .
random_int(0, 255) .
'.' .
rand(0, 255);
random_int(0, 255);
$cityReader = new Reader(WRITEPATH . 'uploads/GeoLite2-City/GeoLite2-City.mmdb');
@ -115,9 +113,7 @@ class FakePodcastsAnalyticsSeeder extends Seeder
try {
$city = $cityReader->city($fakeIp);
$countryCode = $city->country->isoCode === null
? 'N/A'
: $city->country->isoCode;
$countryCode = $city->country->isoCode ?? 'N/A';
$regionCode = $city->subdivisions === []
? 'N/A'
@ -128,20 +124,20 @@ class FakePodcastsAnalyticsSeeder extends Seeder
//Bad luck, bad IP, nothing to do.
}
$hits = rand(0, (int) $probability2);
$hits = random_int(0, (int) $probability2);
$analyticsPodcasts[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'duration' => rand(60, 3600),
'bandwidth' => rand(1000000, 10000000),
'duration' => random_int(60, 3600),
'bandwidth' => random_int(1000000, 10000000),
'hits' => $hits,
'unique_listeners' => $hits,
];
$analyticsPodcastsByHour[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'hour' => rand(0, 23),
'hour' => random_int(0, 23),
'hits' => $hits,
];
$analyticsPodcastsByCountry[] = [

View File

@ -216,23 +216,23 @@ class FakeWebsiteAnalyticsSeeder extends Seeder
for (
$lineNumber = 0;
$lineNumber < rand(1, $probability1);
$lineNumber < random_int(1, $probability1);
++$lineNumber
) {
$probability2 = (int) floor(exp(6 - $age / 20)) + 10;
$domain =
$this->domains[rand(0, count($this->domains) - 1)];
$this->domains[random_int(0, count($this->domains) - 1)];
$keyword =
$this->keywords[
rand(0, count($this->keywords) - 1)
random_int(0, count($this->keywords) - 1)
];
$browser =
$this->browsers[
rand(0, count($this->browsers) - 1)
random_int(0, count($this->browsers) - 1)
];
$hits = rand(0, $probability2);
$hits = random_int(0, $probability2);
$websiteByBrowser[] = [
'podcast_id' => $podcast->id,

View File

@ -483,7 +483,7 @@ class Episode extends Entity
public function setGuid(?string $guid = null): static
{
$this->attributes['guid'] = $guid === null ? $this->getLink() : $guid;
$this->attributes['guid'] = $guid ?? $this->getLink();
return $this;
}

View File

@ -35,7 +35,7 @@ if (! function_exists('hint_tooltip')) {
$tooltip .= ' ' . $class;
}
return $tooltip . '">' . icon('question') . '</span>';
return $tooltip . '">' . icon('question-fill') . '</span>';
}
}
@ -156,20 +156,20 @@ if (! function_exists('publication_button')) {
$label = lang('Episode.publish');
$route = route_to('episode-publish', $podcastId, $episodeId);
$variant = 'primary';
$iconLeft = 'upload-cloud';
$iconLeft = 'upload-cloud-fill'; // @icon('upload-cloud-fill')
break;
case 'with_podcast':
case 'scheduled':
$label = lang('Episode.publish_edit');
$route = route_to('episode-publish_edit', $podcastId, $episodeId);
$variant = 'warning';
$iconLeft = 'upload-cloud';
$iconLeft = 'upload-cloud-fill'; // @icon('upload-cloud-fill')
break;
case 'published':
$label = lang('Episode.unpublish');
$route = route_to('episode-unpublish', $podcastId, $episodeId);
$variant = 'danger';
$iconLeft = 'cloud-off';
$iconLeft = 'cloud-off-fill'; // @icon('cloud-off-fill')
break;
default:
$label = '';
@ -350,7 +350,9 @@ if (! function_exists('location_link')) {
return anchor(
$location->url,
icon('map-pin', 'mr-2 flex-shrink-0') . '<span class="truncate">' . esc($location->name) . '</span>',
icon('map-pin-2-fill', [
'class' => 'mr-2 flex-shrink-0',
]) . '<span class="truncate">' . esc($location->name) . '</span>',
[
'class' => 'w-full overflow-hidden inline-flex items-baseline hover:underline focus:ring-accent' .
($class === '' ? '' : " {$class}"),

View File

@ -42,24 +42,16 @@ if (! function_exists('write_audio_file_tags')) {
// populate data array
$TagData = [
'title' => [esc($episode->title)],
'artist' => [
$episode->podcast->publisher === null
? esc($episode->podcast->owner_name)
: $episode->podcast->publisher,
],
'title' => [esc($episode->title)],
'artist' => [$episode->podcast->publisher ?? esc($episode->podcast->owner_name)],
'album' => [esc($episode->podcast->title)],
'year' => [$episode->published_at instanceof Time ? $episode->published_at->format('Y') : ''],
'genre' => ['Podcast'],
'comment' => [$episode->description],
'track_number' => [(string) $episode->number],
'copyright_message' => [$episode->podcast->copyright],
'publisher' => [
$episode->podcast->publisher === null
? esc($episode->podcast->owner_name)
: $episode->podcast->publisher,
],
'encoded_by' => ['Castopod'],
'publisher' => [$episode->podcast->publisher ?? esc($episode->podcast->owner_name)],
'encoded_by' => ['Castopod'],
// TODO: find a way to add the remaining tags for podcasts as the library doesn't seem to allow it
// 'website' => [$podcast_url],

View File

@ -164,7 +164,7 @@ if (! function_exists('parse_size')) {
$size = (float) preg_replace('~[^0-9\.]~', '', $size); // Remove the non-numeric characters from the size.
if ($unit !== '') {
// Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by.
return round($size * pow(1024, (float) stripos('bkmgtpezy', $unit[0])));
return round($size * 1024 ** ((float) stripos('bkmgtpezy', $unit[0])));
}
return round($size);
@ -183,7 +183,7 @@ if (! function_exists('format_bytes')) {
$pow = floor(($bytes ? log($bytes) : 0) / log($is_binary ? 1024 : 1000));
$pow = min($pow, count($units) - 1);
$bytes /= pow($is_binary ? 1024 : 1000, $pow);
$bytes /= ($is_binary ? 1024 : 1000) ** $pow;
return round($bytes, $precision) . $units[$pow];
}

View File

@ -260,12 +260,7 @@ if (! function_exists('get_rss_feed')) {
$itunesNamespace,
);
$channel->addChild(
'author',
$podcast->publisher ? $podcast->publisher : $podcast->owner_name,
$itunesNamespace,
false
);
$channel->addChild('author', $podcast->publisher ?: $podcast->owner_name, $itunesNamespace, false);
$channel->addChild('link', $podcast->link);
$owner = $channel->addChild('owner', null, $itunesNamespace);
@ -354,7 +349,7 @@ if (! function_exists('get_rss_feed')) {
$item->addChild('episodeType', $episode->type, $itunesNamespace);
// If episode is of type trailer, add podcast:trailer tag on channel level
if ($episode->type == 'trailer') {
if ($episode->type === 'trailer') {
$trailer = $channel->addChild('trailer', $episode->title, $podcastNamespace);
$trailer->addAttribute('pubdate', $episode->published_at->format(DATE_RFC2822));
$trailer->addAttribute(

View File

@ -8,39 +8,6 @@ declare(strict_types=1);
* @link https://castopod.org/
*/
if (! function_exists('icon')) {
/**
* Returns the inline svg icon
*
* @param string $name name of the icon file without the .svg extension
* @param string $class to be added to the svg string
* @param string|null $type type of icon to be added
* @return string svg contents
*/
function icon(string $name, string $class = '', string $type = null): string
{
if ($type !== null) {
$name = $type . '/' . $name;
}
try {
$svgContents = file_get_contents('assets/icons/' . $name . '.svg');
} catch (Exception) {
if ($type !== null) {
return icon('default', $class, $type);
}
return '□';
}
if ($class !== '') {
return str_replace('<svg', '<svg class="' . $class . '"', $svgContents);
}
return $svgContents;
}
}
if (! function_exists('svg')) {
/**
* Returns the inline svg image

View File

@ -48,7 +48,7 @@ class Router extends CodeIgniterRouter
$matchedKey = $routeKey;
// Are we dealing with a locale?
if (strpos($routeKey, '{locale}') !== false) {
if (str_contains($routeKey, '{locale}')) {
$routeKey = str_replace('{locale}', '[^/]+', $routeKey);
}
@ -73,7 +73,7 @@ class Router extends CodeIgniterRouter
// Store our locale so CodeIgniter object can
// assign it to the Request.
if (strpos($matchedKey, '{locale}') !== false) {
if (str_contains($matchedKey, '{locale}')) {
preg_match(
'#^' . str_replace('{locale}', '(?<locale>[^/]+)', $matchedKey) . '$#u',
$uri,
@ -183,13 +183,13 @@ class Router extends CodeIgniterRouter
[$controller] = explode('::', (string) $handler);
// Checks `/` in controller name
if (strpos($controller, '/') !== false) {
if (str_contains($controller, '/')) {
throw RouterException::forInvalidControllerName($handler);
}
if (strpos((string) $handler, '$') !== false && strpos($routeKey, '(') !== false) {
if (str_contains((string) $handler, '$') && str_contains($routeKey, '(')) {
// Checks dynamic controller
if (strpos($controller, '$') !== false) {
if (str_contains($controller, '$')) {
throw RouterException::forDynamicController($handler);
}

View File

@ -7,8 +7,6 @@ namespace ViewComponents;
use CodeIgniter\View\ViewDecoratorInterface;
/**
* Class Decorator
*
* Enables rendering of View Components into the views.
*
* Borrowed and adapted from https://github.com/lonnieezell/Bonfire2/

View File

@ -19,7 +19,7 @@ class Theme
protected static $defaultTheme = 'app';
/**
* @var string
* @var ?string
*/
protected static $currentTheme;
@ -71,9 +71,7 @@ class Theme
*/
public static function current(): string
{
return static::$currentTheme !== null
? static::$currentTheme
: static::$defaultTheme;
return static::$currentTheme ?? static::$defaultTheme;
}
/**

View File

@ -26,7 +26,7 @@ class CategoryModel extends Model
protected $primaryKey = 'id';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = ['parent_id', 'code', 'apple_category', 'google_category'];

View File

@ -33,7 +33,7 @@ class ClipModel extends Model
protected $primaryKey = 'id';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = [
'id',

View File

@ -40,7 +40,7 @@ class EpisodeCommentModel extends UuidModel
protected $uuidFields = ['id', 'in_reply_to_id'];
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = [
'id',
@ -57,7 +57,7 @@ class EpisodeCommentModel extends UuidModel
];
/**
* @var string[]
* @var list<string>
*/
protected $beforeInsert = ['setCommentId'];

View File

@ -62,7 +62,7 @@ class EpisodeModel extends UuidModel
protected $table = 'episodes';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = [
'id',
@ -127,17 +127,17 @@ class EpisodeModel extends UuidModel
];
/**
* @var string[]
* @var list<string>
*/
protected $afterInsert = ['writeEnclosureMetadata', 'clearCache'];
/**
* @var string[]
* @var list<string>
*/
protected $afterUpdate = ['clearCache', 'writeEnclosureMetadata'];
/**
* @var string[]
* @var list<string>
*/
protected $beforeDelete = ['clearCache'];
@ -272,13 +272,7 @@ class EpisodeModel extends UuidModel
$secondsToNextUnpublishedEpisode = $this->getSecondsToNextUnpublishedEpisode($podcastId);
cache()
->save(
$cacheName,
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
->save($cacheName, $found, $secondsToNextUnpublishedEpisode ?: DECADE);
}
return $found;

View File

@ -26,7 +26,7 @@ class LanguageModel extends Model
protected $primaryKey = 'id';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = ['code', 'native_name'];

View File

@ -31,7 +31,7 @@ class LikeModel extends UuidModel
protected $uuidFields = ['comment_id'];
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = ['actor_id', 'comment_id'];

View File

@ -26,7 +26,7 @@ class PageModel extends Model
protected $primaryKey = 'id';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = ['id', 'title', 'slug', 'content_markdown', 'content_html'];
@ -55,19 +55,19 @@ class PageModel extends Model
];
/**
* @var string[]
* @var list<string>
*/
protected $afterInsert = ['clearCache'];
/**
* Before update because slug or title might change
*
* @var string[]
* @var list<string>
*/
protected $beforeUpdate = ['clearCache'];
/**
* @var string[]
* @var list<string>
*/
protected $beforeDelete = ['clearCache'];

View File

@ -26,7 +26,7 @@ class PersonModel extends Model
protected $primaryKey = 'id';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = [
'id',
@ -64,19 +64,19 @@ class PersonModel extends Model
];
/**
* @var string[]
* @var list<string>
*/
protected $afterInsert = ['clearCache'];
/**
* clear cache before update if by any chance, the person name changes, so will the person link
*
* @var string[]
* @var list<string>
*/
protected $beforeUpdate = ['clearCache'];
/**
* @var string[]
* @var list<string>
*/
protected $beforeDelete = ['clearCache'];

View File

@ -30,7 +30,7 @@ class PodcastModel extends Model
protected $primaryKey = 'id';
/**
* @var string[]
* @var list<string>
*/
protected $allowedFields = [
'id',
@ -104,29 +104,29 @@ class PodcastModel extends Model
];
/**
* @var string[]
* @var list<string>
*/
protected $beforeInsert = ['setPodcastGUID', 'createPodcastActor'];
/**
* @var string[]
* @var list<string>
*/
protected $afterInsert = ['setActorAvatar'];
/**
* @var string[]
* @var list<string>
*/
protected $afterUpdate = ['updatePodcastActor'];
/**
* clear cache before update if by any chance, the podcast name changes, so will the podcast link
*
* @var string[]
* @var list<string>
*/
protected $beforeUpdate = ['clearCache'];
/**
* @var string[]
* @var list<string>
*/
protected $beforeDelete = ['clearCache'];
@ -259,13 +259,7 @@ class PodcastModel extends Model
$secondsToNextUnpublishedEpisode = $episodeModel->getSecondsToNextUnpublishedEpisode($podcastId);
cache()
->save(
$cacheName,
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
->save($cacheName, $found, $secondsToNextUnpublishedEpisode ?: DECADE);
}
return $found;
@ -295,13 +289,7 @@ class PodcastModel extends Model
$secondsToNextUnpublishedEpisode = $episodeModel->getSecondsToNextUnpublishedEpisode($podcastId);
cache()
->save(
$cacheName,
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
->save($cacheName, $found, $secondsToNextUnpublishedEpisode ?: DECADE);
}
return $found;
@ -335,11 +323,7 @@ class PodcastModel extends Model
$secondsToNextUnpublishedEpisode = (new EpisodeModel())->getSecondsToNextUnpublishedEpisode($podcastId);
cache()
->save(
$cacheName,
$defaultQuery,
$secondsToNextUnpublishedEpisode ? $secondsToNextUnpublishedEpisode : DECADE
);
->save($cacheName, $defaultQuery, $secondsToNextUnpublishedEpisode ?: DECADE);
}
return $defaultQuery;

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C17.52 2 22 6.48 22 12C22 17.52 17.52 22 12 22C6.48 22 2 17.52 2 12C2 6.48 6.48 2 12 2ZM6.02332 15.4163C7.49083 17.6069 9.69511 19 12.1597 19C14.6243 19 16.8286 17.6069 18.2961 15.4163C16.6885 13.9172 14.5312 13 12.1597 13C9.78821 13 7.63095 13.9172 6.02332 15.4163ZM12 11C13.6569 11 15 9.65685 15 8C15 6.34315 13.6569 5 12 5C10.3431 5 9 6.34315 9 8C9 9.65685 10.3431 11 12 11Z"></path></svg>

Before

Width:  |  Height:  |  Size: 466 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM11 11H7V13H11V17H13V13H17V11H13V7H11V11Z"></path></svg>

Before

Width:  |  Height:  |  Size: 244 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z"></path></svg>

Before

Width:  |  Height:  |  Size: 125 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.4091 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72191 12.7772 2.84815 12.865 3.00017ZM10.9989 16.0002V18.0002H12.9989V16.0002H10.9989ZM10.9989 9.00017V14.0002H12.9989V9.00017H10.9989Z"></path></svg>

Before

Width:  |  Height:  |  Size: 521 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7.82843 10.9999H20V12.9999H7.82843L13.1924 18.3638L11.7782 19.778L4 11.9999L11.7782 4.22168L13.1924 5.63589L7.82843 10.9999Z"></path></svg>

Before

Width:  |  Height:  |  Size: 209 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.1716 10.9999L10.8076 5.63589L12.2218 4.22168L20 11.9999L12.2218 19.778L10.8076 18.3638L16.1716 12.9999H4V10.9999H16.1716Z"></path></svg>

Before

Width:  |  Height:  |  Size: 209 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C13.6418 20 15.1681 19.5054 16.4381 18.6571L17.5476 20.3214C15.9602 21.3818 14.0523 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12V13.5C22 15.433 20.433 17 18.5 17C17.2958 17 16.2336 16.3918 15.6038 15.4659C14.6942 16.4115 13.4158 17 12 17C9.23858 17 7 14.7614 7 12C7 9.23858 9.23858 7 12 7C13.1258 7 14.1647 7.37209 15.0005 8H17V13.5C17 14.3284 17.6716 15 18.5 15C19.3284 15 20 14.3284 20 13.5V12ZM12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9Z"></path></svg>

Before

Width:  |  Height:  |  Size: 718 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8 11H12.5C13.8807 11 15 9.88071 15 8.5C15 7.11929 13.8807 6 12.5 6H8V11ZM18 15.5C18 17.9853 15.9853 20 13.5 20H6V4H12.5C14.9853 4 17 6.01472 17 8.5C17 9.70431 16.5269 10.7981 15.7564 11.6058C17.0979 12.3847 18 13.837 18 15.5ZM8 13V18H13.5C14.8807 18 16 16.8807 16 15.5C16 14.1193 14.8807 13 13.5 13H8Z"></path></svg>

Before

Width:  |  Height:  |  Size: 386 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4.92893 2.92871L6.34315 4.34292C4.89543 5.79064 4 7.79064 4 9.99978C4 12.2089 4.89543 14.2089 6.34315 15.6566L4.92893 17.0708C3.11929 15.2612 2 12.7612 2 9.99978C2 7.23835 3.11929 4.73836 4.92893 2.92871ZM19.0711 2.92871C20.8807 4.73836 22 7.23835 22 9.99978C22 12.7612 20.8807 15.2612 19.0711 17.0708L17.6569 15.6566C19.1046 14.2089 20 12.2089 20 9.99978C20 7.79064 19.1046 5.79064 17.6569 4.34292L19.0711 2.92871ZM7.75736 5.75714L9.17157 7.17135C8.44771 7.89521 8 8.89521 8 9.99978C8 11.1043 8.44771 12.1043 9.17157 12.8282L7.75736 14.2424C6.67157 13.1566 6 11.6566 6 9.99978C6 8.34292 6.67157 6.84292 7.75736 5.75714ZM16.2426 5.75714C17.3284 6.84292 18 8.34292 18 9.99978C18 11.6566 17.3284 13.1566 16.2426 14.2424L14.8284 12.8282C15.5523 12.1043 16 11.1043 16 9.99978C16 8.89521 15.5523 7.89521 14.8284 7.17135L16.2426 5.75714ZM12 11.9998C10.8954 11.9998 10 11.1043 10 9.99978C10 8.89521 10.8954 7.99978 12 7.99978C13.1046 7.99978 14 8.89521 14 9.99978C14 11.1043 13.1046 11.9998 12 11.9998ZM12 13.9998C12.5798 13.9998 13.0774 14.4128 13.1843 14.9827L14.5 21.9998H9.5L10.8157 14.9827C10.9226 14.4128 11.4202 13.9998 12 13.9998Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2 11H22V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V11ZM17 3H21C21.5523 3 22 3.44772 22 4V9H2V4C2 3.44772 2.44772 3 3 3H7V1H9V3H15V1H17V3Z"></path></svg>

Before

Width:  |  Height:  |  Size: 238 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 14L8 10H16L12 14Z"></path></svg>

Before

Width:  |  Height:  |  Size: 105 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12L10 16V8L14 12Z"></path></svg>

Before

Width:  |  Height:  |  Size: 105 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.45455 19L2 22.5V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V18C22 18.5523 21.5523 19 21 19H6.45455Z"></path></svg>

Before

Width:  |  Height:  |  Size: 197 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.0007 15.1709L19.1931 5.97852L20.6073 7.39273L10.0007 17.9993L3.63672 11.6354L5.05093 10.2212L10.0007 15.1709Z"></path></svg>

Before

Width:  |  Height:  |  Size: 197 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.8284 12.0007L15.7782 16.9504L14.364 18.3646L8 12.0007L14.364 5.63672L15.7782 7.05093L10.8284 12.0007Z"></path></svg>

Before

Width:  |  Height:  |  Size: 189 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.1714 12.0007L8.22168 7.05093L9.63589 5.63672L15.9999 12.0007L9.63589 18.3646L8.22168 16.9504L13.1714 12.0007Z"></path></svg>

Before

Width:  |  Height:  |  Size: 197 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.9981 7L20.3075 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934C2 3.44476 2.45531 3 2.9918 3H5.99807L3.68867 7H5.99807L8.30747 3H11.9981L9.68867 7H11.9981L14.3075 3H17.9981L15.6887 7H17.9981Z"></path></svg>

Before

Width:  |  Height:  |  Size: 356 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 4V8H18V4H20.0066C20.5552 4 21 4.44495 21 4.9934V21.0066C21 21.5552 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5551 3 21.0066V4.9934C3 4.44476 3.44495 4 3.9934 4H6ZM8 2H16V6H8V2Z"></path></svg>

Before

Width:  |  Height:  |  Size: 266 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.0007 10.5865L16.9504 5.63672L18.3646 7.05093L13.4149 12.0007L18.3646 16.9504L16.9504 18.3646L12.0007 13.4149L7.05093 18.3646L5.63672 16.9504L10.5865 12.0007L5.63672 7.05093L7.05093 5.63672L12.0007 10.5865Z"></path></svg>

Before

Width:  |  Height:  |  Size: 293 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.51472 2.10051L22.6066 21.1924L21.1924 22.6066L19.1782 20.5924C18.503 20.8556 17.7684 21 17 21H7C3.68629 21 1 18.3137 1 15C1 12.3846 2.67346 10.16 5.00804 9.33857C5.0027 9.22639 5 9.11351 5 9C5 8.22228 5.12683 7.47418 5.36094 6.77527L2.10051 3.51472L3.51472 2.10051ZM17 9C17.6983 9 18.3687 9.11928 18.992 9.33857C21.3265 10.16 23 12.3846 23 15C23 16.0883 22.7103 17.1089 22.2037 17.9889L14.0109 9.79638C14.891 9.28977 15.9117 9 17 9ZM12 2C15.242 2 17.9693 4.20399 18.7652 7.19539C18.1973 7.0675 17.6065 7 17 7C15.357 7 13.8297 7.49529 12.5592 8.34471L7.69418 3.48056C8.88169 2.55284 10.3763 2 12 2Z"></path></svg>

Before

Width:  |  Height:  |  Size: 684 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 13H11V3H3V13ZM3 21H11V15H3V21ZM13 21H21V11H13V21ZM13 3V9H21V3H13Z"></path></svg>

Before

Width:  |  Height:  |  Size: 152 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 9.5V12.5C21 14.9853 16.9706 17 12 17C7.02944 17 3 14.9853 3 12.5V9.5C3 11.9853 7.02944 14 12 14C16.9706 14 21 11.9853 21 9.5ZM3 14.5C3 16.9853 7.02944 19 12 19C16.9706 19 21 16.9853 21 14.5V17.5C21 19.9853 16.9706 22 12 22C7.02944 22 3 19.9853 3 17.5V14.5ZM12 12C7.02944 12 3 9.98528 3 7.5C3 5.01472 7.02944 3 12 3C16.9706 3 21 5.01472 21 7.5C21 9.98528 16.9706 12 12 12Z"></path></svg>

Before

Width:  |  Height:  |  Size: 459 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H22V8H20V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V8H2V6H7V3C7 2.44772 7.44772 2 8 2H16C16.5523 2 17 2.44772 17 3V6ZM9 11V17H11V11H9ZM13 11V17H15V11H13ZM9 4V6H15V4H9Z"></path></svg>

Before

Width:  |  Height:  |  Size: 272 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9.17071C12.6872 9.06015 12.3506 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15C13.6569 15 15 13.6569 15 12V2.4578C19.0571 3.73207 22 7.52236 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C12.3375 2 12.6711 2.01672 13 2.04938V9.17071Z"></path></svg>

Before

Width:  |  Height:  |  Size: 371 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 19H20V12H22V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V12H4V19ZM14 9H19L12 16L5 9H10V3H14V9Z"></path></svg>

Before

Width:  |  Height:  |  Size: 195 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7.24264 17.9964H3V13.7538L14.435 2.31877C14.8256 1.92825 15.4587 1.92825 15.8492 2.31877L18.6777 5.1472C19.0682 5.53772 19.0682 6.17089 18.6777 6.56141L7.24264 17.9964ZM3 19.9964H21V21.9964H3V19.9964Z"></path></svg>

Before

Width:  |  Height:  |  Size: 285 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM11 15V17H13V15H11ZM11 7V13H13V7H11Z"></path></svg>

Before

Width:  |  Height:  |  Size: 233 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5.37833 4.51353C7.14264 2.95131 9.46301 2.00293 12.0049 2.00293C17.5277 2.00293 22.0049 6.48008 22.0049 12.0029C22.0049 14.1279 21.3421 16.098 20.212 17.7179L17.5049 12.0029H20.0049C20.0049 7.58465 16.4232 4.00293 12.0049 4.00293C9.76058 4.00293 7.73213 4.92709 6.27932 6.41563L5.37833 4.51353ZM18.6314 19.4923C16.8671 21.0545 14.5468 22.0029 12.0049 22.0029C6.48204 22.0029 2.00488 17.5258 2.00488 12.0029C2.00488 9.87798 2.66767 7.90784 3.79778 6.28794L6.50488 12.0029H4.00488C4.00488 16.4212 7.5866 20.0029 12.0049 20.0029C14.2492 20.0029 16.2776 19.0788 17.7304 17.5902L18.6314 19.4923ZM8.50488 14.0029H14.0049C14.281 14.0029 14.5049 13.7791 14.5049 13.5029C14.5049 13.2268 14.281 13.0029 14.0049 13.0029H10.0049C8.62417 13.0029 7.50488 11.8836 7.50488 10.5029C7.50488 9.12222 8.62417 8.00293 10.0049 8.00293H11.0049V7.00293H13.0049V8.00293H15.5049V10.0029H10.0049C9.72874 10.0029 9.50488 10.2268 9.50488 10.5029C9.50488 10.7791 9.72874 11.0029 10.0049 11.0029H14.0049C15.3856 11.0029 16.5049 12.1222 16.5049 13.5029C16.5049 14.8836 15.3856 16.0029 14.0049 16.0029H13.0049V17.0029H11.0049V16.0029H8.50488V14.0029Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 6V8H5V19H16V14H18V20C18 20.5523 17.5523 21 17 21H4C3.44772 21 3 20.5523 3 20V7C3 6.44772 3.44772 6 4 6H10ZM21 3V12L17.206 8.207L11.2071 14.2071L9.79289 12.7929L15.792 6.793L12 3H21Z"></path></svg>

Before

Width:  |  Height:  |  Size: 269 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M1.18164 12C2.12215 6.87976 6.60812 3 12.0003 3C17.3924 3 21.8784 6.87976 22.8189 12C21.8784 17.1202 17.3924 21 12.0003 21C6.60812 21 2.12215 17.1202 1.18164 12ZM12.0003 17C14.7617 17 17.0003 14.7614 17.0003 12C17.0003 9.23858 14.7617 7 12.0003 7C9.23884 7 7.00026 9.23858 7.00026 12C7.00026 14.7614 9.23884 17 12.0003 17ZM12.0003 15C10.3434 15 9.00026 13.6569 9.00026 12C9.00026 10.3431 10.3434 9 12.0003 9C13.6571 9 15.0003 10.3431 15.0003 12C15.0003 13.6569 13.6571 15 12.0003 15Z"></path></svg>

Before

Width:  |  Height:  |  Size: 567 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.9998 6V3C6.9998 2.44772 7.44752 2 7.9998 2H19.9998C20.5521 2 20.9998 2.44772 20.9998 3V17C20.9998 17.5523 20.5521 18 19.9998 18H16.9998V20.9991C16.9998 21.5519 16.5499 22 15.993 22H4.00666C3.45059 22 3 21.5554 3 20.9991L3.0026 7.00087C3.0027 6.44811 3.45264 6 4.00942 6H6.9998ZM8.9998 6H16.9998V16H18.9998V4H8.9998V6Z"></path></svg>

Before

Width:  |  Height:  |  Size: 404 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16 2L21 7V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5447 3 21.0082V2.9918C3 2.44405 3.44495 2 3.9934 2H16ZM13 12V8H11V12H8L12 16L16 12H13Z"></path></svg>

Before

Width:  |  Height:  |  Size: 244 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.4142 5H21C21.5523 5 22 5.44772 22 6V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H10.4142L12.4142 5ZM12 13C13.3807 13 14.5 11.8807 14.5 10.5C14.5 9.11929 13.3807 8 12 8C10.6193 8 9.5 9.11929 9.5 10.5C9.5 11.8807 10.6193 13 12 13ZM8 18H16C16 15.7909 14.2091 14 12 14C9.79086 14 8 15.7909 8 18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 419 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM8.52313 7.10891C8.25459 7.30029 7.99828 7.51644 7.75736 7.75736C7.51644 7.99828 7.30029 8.25459 7.10891 8.52313L15.4769 16.8911C15.7454 16.6997 16.0017 16.4836 16.2426 16.2426C16.4836 16.0017 16.6997 15.7454 16.8911 15.4769L8.52313 7.10891Z"></path></svg>

Before

Width:  |  Height:  |  Size: 438 B

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
/**
* @icon('funding:buymeacoffee')
* @icon('funding:donorbox')
* @icon('funding:gofundme')
* @icon('funding:helloasso')
* @icon('funding:indiegogo')
* @icon('funding:kickstarter')
* @icon('funding:kisskissbankbank')
* @icon('funding:kofi')
* @icon('funding:liberapay')
* @icon('funding:patreon')
* @icon('funding:paypal')
* @icon('funding:tipeee')
* @icon('funding:ulule')
*/

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0z" />
<path d="m18.755 7.346-.11-.555c-.099-.498-.323-.97-.834-1.15-.164-.057-.35-.081-.475-.2-.127-.12-.163-.305-.192-.477-.054-.315-.104-.63-.16-.944-.048-.27-.085-.575-.209-.823-.162-.333-.497-.528-.83-.656a4.775 4.775 0 0 0-.521-.162c-.834-.219-1.709-.3-2.565-.347a21.528 21.528 0 0 0-3.083.052c-.763.07-1.567.153-2.292.417-.265.096-.538.213-.74.417-.247.252-.327.642-.147.955.128.223.346.38.576.484.3.135.615.236.936.305.896.198 1.825.276 2.74.308 1.014.042 2.03.008 3.041-.098.25-.028.499-.061.747-.1.293-.044.482-.427.395-.694-.103-.32-.38-.443-.695-.395-.388.062-.8.09-1.152.122-.98.067-1.965.068-2.947.005a18.518 18.518 0 0 1-.964-.09 10.513 10.513 0 0 1-.818-.138c-.093-.022-.093-.154 0-.176h.004c.231-.05.464-.09.698-.123h.002c.11-.007.22-.026.328-.04a20.898 20.898 0 0 1 2.856-.1c.561.016 1.122.056 1.68.12l.19.026c.223.033.445.073.665.121.327.07.746.094.892.452.046.114.067.24.093.359l.265 1.237a.198.198 0 0 1-.165.236h-.003l-.093.013c-1.311.167-2.631.25-3.953.246A30.882 30.882 0 0 1 8 5.699c-.116-.014-.244-.035-.347-.05-.272-.04-.541-.09-.811-.134-.328-.054-.64-.027-.936.134-.242.134-.44.337-.562.584-.129.264-.166.55-.223.834-.057.283-.147.589-.112.88.072.627.51 1.137 1.141 1.251 3.12.557 6.303.663 9.453.314a.403.403 0 0 1 .446.441l-.06.581-.848 8.256c-.034.342-.039.694-.104 1.031-.102.531-.46.857-.985.976-.48.11-.97.167-1.463.17-.547.004-1.092-.02-1.639-.017-.582.003-1.296-.05-1.746-.484-.395-.382-.45-.978-.504-1.494l-.609-5.844-.268-2.579c-.031-.292-.239-.579-.565-.565-.28.013-.599.25-.565.566l.19 1.821.79 7.594c.123 1.12.979 1.723 2.039 1.893.618.1 1.252.12 1.88.13.806.013 1.62.044 2.41-.102 1.174-.215 2.055-.998 2.181-2.214.283-2.777.57-5.553.853-8.33l.18-1.739a.403.403 0 0 1 .325-.355c.335-.065.655-.176.895-.431.379-.407.455-.936.32-1.471Zm-1.231.643c-.121.114-.303.168-.482.194-2.013.3-4.055.45-6.09.384-1.457-.05-2.898-.212-4.34-.415-.141-.02-.294-.046-.391-.15-.183-.197-.093-.592-.045-.83.043-.216.127-.507.386-.538.403-.047.871.124 1.271.184.481.073.964.132 1.448.176 2.067.189 4.168.159 6.227-.116.375-.05.749-.109 1.12-.175.333-.06.7-.172.9.171.139.234.157.548.136.812a.453.453 0 0 1-.141.303Zm-5.133 3.25c-.718.309-1.533.657-2.59.657a4.906 4.906 0 0 1-1.308-.18l.73 7.503c.055.65.598 1.15 1.25 1.15 0 0 1.036.054 1.382.054.373 0 1.489-.054 1.489-.054.652 0 1.195-.5 1.249-1.15l.783-8.292a3.328 3.328 0 0 0-1.102-.198c-.688 0-1.242.236-1.883.51Z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0 0h24v24H0z"/><path d="m18.755 7.346-.11-.555c-.099-.498-.323-.97-.834-1.15-.164-.057-.35-.081-.475-.2-.127-.12-.163-.305-.192-.477-.054-.315-.104-.63-.16-.944-.048-.27-.085-.575-.209-.823-.162-.333-.497-.528-.83-.656a4.775 4.775 0 0 0-.521-.162c-.834-.219-1.709-.3-2.565-.347a21.528 21.528 0 0 0-3.083.052c-.763.07-1.567.153-2.292.417-.265.096-.538.213-.74.417-.247.252-.327.642-.147.955.128.223.346.38.576.484.3.135.615.236.936.305.896.198 1.825.276 2.74.308 1.014.042 2.03.008 3.041-.098.25-.028.499-.061.747-.1.293-.044.482-.427.395-.694-.103-.32-.38-.443-.695-.395-.388.062-.8.09-1.152.122-.98.067-1.965.068-2.947.005a18.518 18.518 0 0 1-.964-.09 10.513 10.513 0 0 1-.818-.138c-.093-.022-.093-.154 0-.176h.004c.231-.05.464-.09.698-.123h.002c.11-.007.22-.026.328-.04a20.898 20.898 0 0 1 2.856-.1c.561.016 1.122.056 1.68.12l.19.026c.223.033.445.073.665.121.327.07.746.094.892.452.046.114.067.24.093.359l.265 1.237a.198.198 0 0 1-.165.236h-.003l-.093.013c-1.311.167-2.631.25-3.953.246A30.882 30.882 0 0 1 8 5.699c-.116-.014-.244-.035-.347-.05-.272-.04-.541-.09-.811-.134-.328-.054-.64-.027-.936.134-.242.134-.44.337-.562.584-.129.264-.166.55-.223.834-.057.283-.147.589-.112.88.072.627.51 1.137 1.141 1.251 3.12.557 6.303.663 9.453.314a.403.403 0 0 1 .446.441l-.06.581-.848 8.256c-.034.342-.039.694-.104 1.031-.102.531-.46.857-.985.976-.48.11-.97.167-1.463.17-.547.004-1.092-.02-1.639-.017-.582.003-1.296-.05-1.746-.484-.395-.382-.45-.978-.504-1.494l-.609-5.844-.268-2.579c-.031-.292-.239-.579-.565-.565-.28.013-.599.25-.565.566l.19 1.821.79 7.594c.123 1.12.979 1.723 2.039 1.893.618.1 1.252.12 1.88.13.806.013 1.62.044 2.41-.102 1.174-.215 2.055-.998 2.181-2.214.283-2.777.57-5.553.853-8.33l.18-1.739a.403.403 0 0 1 .325-.355c.335-.065.655-.176.895-.431.379-.407.455-.936.32-1.471Zm-1.231.643c-.121.114-.303.168-.482.194-2.013.3-4.055.45-6.09.384-1.457-.05-2.898-.212-4.34-.415-.141-.02-.294-.046-.391-.15-.183-.197-.093-.592-.045-.83.043-.216.127-.507.386-.538.403-.047.871.124 1.271.184.481.073.964.132 1.448.176 2.067.189 4.168.159 6.227-.116.375-.05.749-.109 1.12-.175.333-.06.7-.172.9.171.139.234.157.548.136.812a.453.453 0 0 1-.141.303Zm-5.133 3.25c-.718.309-1.533.657-2.59.657a4.906 4.906 0 0 1-1.308-.18l.73 7.503c.055.65.598 1.15 1.25 1.15 0 0 1.036.054 1.382.054.373 0 1.489-.054 1.489-.054.652 0 1.195-.5 1.249-1.15l.783-8.292a3.328 3.328 0 0 0-1.102-.198c-.688 0-1.242.236-1.883.51Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0z" />
<path d="M23 12v2c0 3.314-4.925 6-11 6-5.967 0-10.824-2.591-10.995-5.823L1 14v-2c0 3.314 4.925 6 11 6s11-2.686 11-6zM12 4c6.075 0 11 2.686 11 6s-4.925 6-11 6-11-2.686-11-6 4.925-6 11-6z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0 0h24v24H0z"/><path d="M23 12v2c0 3.314-4.925 6-11 6-5.967 0-10.824-2.591-10.995-5.823L1 14v-2c0 3.314 4.925 6 11 6s11-2.686 11-6zM12 4c6.075 0 11 2.686 11 6s-4.925 6-11 6-11-2.686-11-6 4.925-6 11-6z"/></svg>

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 301 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M16.455 10.658c0 1.09-.705 2.244-2.098 3.443a13.447 13.447 0 0 1-2.381 1.62 14.102 14.102 0 0 1-2.381-1.629c-1.4-1.2-2.106-2.353-2.106-3.443 0-1.346.887-2.298 2.106-2.298.558 0 .888.054 1.263.238.22.1.412.237.577.403l.541.55.532-.55a2.07 2.07 0 0 1 .586-.421c.366-.166.678-.22 1.254-.22 1.209.018 2.107.988 2.107 2.307Z" clip-rule="evenodd"/>
<path d="M22 3.915v16.17A1.911 1.911 0 0 1 20.085 22H3.915A1.911 1.911 0 0 1 2 20.085V3.915C2 2.855 2.854 2 3.915 2h8.066c.267 0 .503.107.68.282a.986.986 0 0 1 .281.68v2.807a.962.962 0 0 1-1.922 0V3.923H4.83a.919.919 0 0 0-.916.916v14.346c0 .51.413.915.916.915h14.346a.914.914 0 0 0 .916-.915V4.839a.942.942 0 0 0-.275-.649s-.214-.206-.48-.252c-.032-.008-.07-.008-.07-.008-.03 0-.061-.007-.09-.007h-2.504a.967.967 0 0 1-.96-.962c0-.526.434-.961.96-.961h3.41A1.907 1.907 0 0 1 22 3.915Z"/>
</svg>
<svg viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em"><path d="M16.455 10.658c0 1.09-.705 2.244-2.098 3.443a13.447 13.447 0 0 1-2.381 1.62 14.102 14.102 0 0 1-2.381-1.629c-1.4-1.2-2.106-2.353-2.106-3.443 0-1.346.887-2.298 2.106-2.298.558 0 .888.054 1.263.238.22.1.412.237.577.403l.541.55.532-.55a2.07 2.07 0 0 1 .586-.421c.366-.166.678-.22 1.254-.22 1.209.018 2.107.988 2.107 2.307Z" clip-rule="evenodd"/><path d="M22 3.915v16.17A1.911 1.911 0 0 1 20.085 22H3.915A1.911 1.911 0 0 1 2 20.085V3.915C2 2.855 2.854 2 3.915 2h8.066c.267 0 .503.107.68.282a.986.986 0 0 1 .281.68v2.807a.962.962 0 0 1-1.922 0V3.923H4.83a.919.919 0 0 0-.916.916v14.346c0 .51.413.915.916.915h14.346a.914.914 0 0 0 .916-.915V4.839a.942.942 0 0 0-.275-.649s-.214-.206-.48-.252c-.032-.008-.07-.008-.07-.008-.03 0-.061-.007-.09-.007h-2.504a.967.967 0 0 1-.96-.962c0-.526.434-.961.96-.961h3.41A1.907 1.907 0 0 1 22 3.915Z"/></svg>

Before

Width:  |  Height:  |  Size: 913 B

After

Width:  |  Height:  |  Size: 915 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0,0H24V24H0Z" fill="none" />
<path d="M6.07,14.76a4.78,4.78,0,0,1,.48-.37A2.58,2.58,0,0,1,8.13,14a2.5,2.5,0,0,1,.76.19A2,2,0,0,1,9.7,15c0,.05.06.06.09,0A2,2,0,0,1,11.3,14a2,2,0,0,1,1.69.48,1.44,1.44,0,0,1,.44.83,4.6,4.6,0,0,1,.05.64V19.3c0,.1,0,.12-.12.12q-.87,0-1.74,0c-.08,0-.1,0-.1-.11v-2.6a2.56,2.56,0,0,0-.07-.62.8.8,0,0,0-1.33-.38,1.15,1.15,0,0,0-.33.76,5.88,5.88,0,0,0,0,.73v2.12c0,.07,0,.1-.09.1H7.91c-.08,0-.1,0-.1-.1V16.68a3.27,3.27,0,0,0,0-.54.73.73,0,0,0-.58-.61.86.86,0,0,0-1,.36,1.12,1.12,0,0,0-.15.62q0,1.39,0,2.79c0,.1,0,.12-.13.12q-.87,0-1.74,0c-.08,0-.1,0-.1-.1V14.21c0-.08,0-.1.11-.1H6c.08,0,.1,0,.1.1s0,.36,0,.55Zm14.62,2.29a3.65,3.65,0,0,0-.11-1,2.5,2.5,0,0,0-1.81-1.9,3.93,3.93,0,0,0-2.35,0,2.5,2.5,0,0,0-1.36,1,3,3,0,0,0-.38,2.17,2.56,2.56,0,0,0,1.72,2,4,4,0,0,0,1.5.22,4.14,4.14,0,0,0,.87-.1,2.36,2.36,0,0,0,1.81-1.61c0-.08,0-.1-.07-.1H18.82c-.07,0-.1,0-.14.07a.93.93,0,0,1-.52.37,1.47,1.47,0,0,1-.88,0,.88.88,0,0,1-.62-.67,1.64,1.64,0,0,1-.05-.32c0-.11,0-.12.1-.12h3.88C20.64,17.12,20.69,17.12,20.69,17.05Zm-1.91-1h-2c-.06,0-.08,0-.07-.08a1,1,0,0,1,1-.83,1.18,1.18,0,0,1,.77.18,1.12,1.12,0,0,1,.42.66C18.87,16.07,18.82,16.05,18.78,16.05Zm3-10.15a1.67,1.67,0,0,0-1.81-.3,2.7,2.7,0,0,0-.34.17L16.32,8.16a1.15,1.15,0,0,0-.48.73.82.82,0,0,0,.24.75,1.74,1.74,0,0,0,2,.28c.42-.25,3.2-2.31,3.66-2.64l.11-.12a1,1,0,0,0-.06-1.26ZM7.92,9.58a.82.82,0,0,0,.24-.75,1.19,1.19,0,0,0-.48-.74L4.39,5.71a1.83,1.83,0,0,0-.34-.18,1.68,1.68,0,0,0-1.8.31,1,1,0,0,0-.06,1.25l.11.12C2.76,7.55,5.54,9.6,6,9.86a1.76,1.76,0,0,0,2-.28ZM12,8.94A1.4,1.4,0,0,0,13.48,8a1.07,1.07,0,0,0,0-.25l0-2.14V5.58c0-.82-.66-1.2-1.49-1.2s-1.5.44-1.51,1.26V7.79a1,1,0,0,0,0,.25,1.35,1.35,0,0,0,1.47.9Zm4.34,1.62a10.11,10.11,0,0,0-4.51-.9c-3.23,0-5.39,1-6.49,2.5h13a5.75,5.75,0,0,0-2-1.6Z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0,0H24V24H0Z"/><path d="M6.07,14.76a4.78,4.78,0,0,1,.48-.37A2.58,2.58,0,0,1,8.13,14a2.5,2.5,0,0,1,.76.19A2,2,0,0,1,9.7,15c0,.05.06.06.09,0A2,2,0,0,1,11.3,14a2,2,0,0,1,1.69.48,1.44,1.44,0,0,1,.44.83,4.6,4.6,0,0,1,.05.64V19.3c0,.1,0,.12-.12.12q-.87,0-1.74,0c-.08,0-.1,0-.1-.11v-2.6a2.56,2.56,0,0,0-.07-.62.8.8,0,0,0-1.33-.38,1.15,1.15,0,0,0-.33.76,5.88,5.88,0,0,0,0,.73v2.12c0,.07,0,.1-.09.1H7.91c-.08,0-.1,0-.1-.1V16.68a3.27,3.27,0,0,0,0-.54.73.73,0,0,0-.58-.61.86.86,0,0,0-1,.36,1.12,1.12,0,0,0-.15.62q0,1.39,0,2.79c0,.1,0,.12-.13.12q-.87,0-1.74,0c-.08,0-.1,0-.1-.1V14.21c0-.08,0-.1.11-.1H6c.08,0,.1,0,.1.1s0,.36,0,.55Zm14.62,2.29a3.65,3.65,0,0,0-.11-1,2.5,2.5,0,0,0-1.81-1.9,3.93,3.93,0,0,0-2.35,0,2.5,2.5,0,0,0-1.36,1,3,3,0,0,0-.38,2.17,2.56,2.56,0,0,0,1.72,2,4,4,0,0,0,1.5.22,4.14,4.14,0,0,0,.87-.1,2.36,2.36,0,0,0,1.81-1.61c0-.08,0-.1-.07-.1H18.82c-.07,0-.1,0-.14.07a.93.93,0,0,1-.52.37,1.47,1.47,0,0,1-.88,0,.88.88,0,0,1-.62-.67,1.64,1.64,0,0,1-.05-.32c0-.11,0-.12.1-.12h3.88C20.64,17.12,20.69,17.12,20.69,17.05Zm-1.91-1h-2c-.06,0-.08,0-.07-.08a1,1,0,0,1,1-.83,1.18,1.18,0,0,1,.77.18,1.12,1.12,0,0,1,.42.66C18.87,16.07,18.82,16.05,18.78,16.05Zm3-10.15a1.67,1.67,0,0,0-1.81-.3,2.7,2.7,0,0,0-.34.17L16.32,8.16a1.15,1.15,0,0,0-.48.73.82.82,0,0,0,.24.75,1.74,1.74,0,0,0,2,.28c.42-.25,3.2-2.31,3.66-2.64l.11-.12a1,1,0,0,0-.06-1.26ZM7.92,9.58a.82.82,0,0,0,.24-.75,1.19,1.19,0,0,0-.48-.74L4.39,5.71a1.83,1.83,0,0,0-.34-.18,1.68,1.68,0,0,0-1.8.31,1,1,0,0,0-.06,1.25l.11.12C2.76,7.55,5.54,9.6,6,9.86a1.76,1.76,0,0,0,2-.28ZM12,8.94A1.4,1.4,0,0,0,13.48,8a1.07,1.07,0,0,0,0-.25l0-2.14V5.58c0-.82-.66-1.2-1.49-1.2s-1.5.44-1.51,1.26V7.79a1,1,0,0,0,0,.25,1.35,1.35,0,0,0,1.47.9Zm4.34,1.62a10.11,10.11,0,0,0-4.51-.9c-3.23,0-5.39,1-6.49,2.5h13a5.75,5.75,0,0,0-2-1.6Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0,0H24V24H0Z" fill="none" />
<path d="M9.74,3c7.35.4,6.31,7.57,6.31,7.57A7.62,7.62,0,0,0,9.56,7.08c-3.39.08-7,2.61-7.06,7.71A8,8,0,0,1,2,12.14C2.14,5.71,7,2.83,9.74,3Zm7.11.07a8,8,0,0,0-2.56-.81c4.48,2.43,5,6.84,3.43,9.87a7.61,7.61,0,0,1-6.13,4.07s5.83,4.32,9.66-2C22.7,11.83,22.45,6.23,16.85,3.05ZM17,20.32a8,8,0,0,0,2-1.77c-4.4,2.58-8.43.73-10.23-2.15a7.64,7.64,0,0,1-.32-7.35s-6.7,2.76-3.3,9.28C6.44,20.8,11.37,23.48,17,20.32Z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0,0H24V24H0Z"/><path d="M9.74,3c7.35.4,6.31,7.57,6.31,7.57A7.62,7.62,0,0,0,9.56,7.08c-3.39.08-7,2.61-7.06,7.71A8,8,0,0,1,2,12.14C2.14,5.71,7,2.83,9.74,3Zm7.11.07a8,8,0,0,0-2.56-.81c4.48,2.43,5,6.84,3.43,9.87a7.61,7.61,0,0,1-6.13,4.07s5.83,4.32,9.66-2C22.7,11.83,22.45,6.23,16.85,3.05ZM17,20.32a8,8,0,0,0,2-1.77c-4.4,2.58-8.43.73-10.23-2.15a7.64,7.64,0,0,1-.32-7.35s-6.7,2.76-3.3,9.28C6.44,20.8,11.37,23.48,17,20.32Z"/></svg>

Before

Width:  |  Height:  |  Size: 519 B

After

Width:  |  Height:  |  Size: 516 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0,0H24V24H0Z" fill="none" />
<path d="M17.08,15.11c-1.66,0-1.88-1.14-1.88-3s.22-3,1.88-3,1.87,1.14,1.87,3S18.72,15.11,17.08,15.11Zm0-8.87C12.89,6.24,12.14,9,12.14,12s.75,5.75,4.94,5.75S22,15,22,12s-.73-5.77-4.92-5.77m-10.7,7H8.32v.2c0,1.24,0,1.79-1.44,1.79S5,14.63,5,12.1s.79-3,2-3a4,4,0,0,1,2,.51l1.61-2.5a6.61,6.61,0,0,0-3.5-.91C3.25,6.24,2,8.1,2,12c0,3.4.91,5.75,4.6,5.75a9.41,9.41,0,0,0,1.7-.13h2.77V10.84H6.71l-.33,2.44" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0,0H24V24H0Z"/><path d="M17.08,15.11c-1.66,0-1.88-1.14-1.88-3s.22-3,1.88-3,1.87,1.14,1.87,3S18.72,15.11,17.08,15.11Zm0-8.87C12.89,6.24,12.14,9,12.14,12s.75,5.75,4.94,5.75S22,15,22,12s-.73-5.77-4.92-5.77m-10.7,7H8.32v.2c0,1.24,0,1.79-1.44,1.79S5,14.63,5,12.1s.79-3,2-3a4,4,0,0,1,2,.51l1.61-2.5a6.61,6.61,0,0,0-3.5-.91C3.25,6.24,2,8.1,2,12c0,3.4.91,5.75,4.6,5.75a9.41,9.41,0,0,0,1.7-.13h2.77V10.84H6.71l-.33,2.44"/></svg>

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 511 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0,0H24V24H0Z" fill="none" />
<path d="M21,17.52a4.6,4.6,0,0,1-8.33,2.56l-.94-1.33A4.21,4.21,0,0,1,7.47,22,4.44,4.44,0,0,1,3,17.56V6.44A4.42,4.42,0,0,1,7.47,2a4.27,4.27,0,0,1,4.29,3.38l1.08-1.46A4.63,4.63,0,0,1,16.53,2,4.4,4.4,0,0,1,21,6.38,4.35,4.35,0,0,1,20.16,9L18,12l2.15,3A4.44,4.44,0,0,1,21,17.52Z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0,0H24V24H0Z"/><path d="M21,17.52a4.6,4.6,0,0,1-8.33,2.56l-.94-1.33A4.21,4.21,0,0,1,7.47,22,4.44,4.44,0,0,1,3,17.56V6.44A4.42,4.42,0,0,1,7.47,2a4.27,4.27,0,0,1,4.29,3.38l1.08-1.46A4.63,4.63,0,0,1,16.53,2,4.4,4.4,0,0,1,21,6.38,4.35,4.35,0,0,1,20.16,9L18,12l2.15,3A4.44,4.44,0,0,1,21,17.52Z"/></svg>

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 389 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0,0H24V24H0Z" fill="none" />
<path d="M15,6.84a7.54,7.54,0,1,0-.09,10.42L9.77,12.09Zm4.86,5.23A2.54,2.54,0,1,0,17.7,7.73h0l-4.33,4.34,4.23,4.23a2.55,2.55,0,1,0,2.3-4.24" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0,0H24V24H0Z"/><path d="M15,6.84a7.54,7.54,0,1,0-.09,10.42L9.77,12.09Zm4.86,5.23A2.54,2.54,0,1,0,17.7,7.73h0l-4.33,4.34,4.23,4.23a2.55,2.55,0,1,0,2.3-4.24"/></svg>

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 255 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0z" />
<path d="M21.9 9.827C21.257 6.423 17.852 6 17.852 6H2.602c-.503 0-.565.665-.565.665s-.069 6.103-.019 9.852c.137 2.02 2.155 2.226 2.155 2.226s6.89-.019 9.972-.04c2.031-.356 2.236-2.139 2.215-3.112 3.626.2 6.185-2.36 5.54-5.764Zm-9.218 2.926c-1.038 1.211-3.342 3.314-3.342 3.314s-.101.099-.258.019c-.064-.048-.09-.075-.09-.075-.37-.368-2.807-2.541-3.362-3.295-.59-.804-.868-2.25-.076-3.092.793-.842 2.504-.905 3.636.34 0 0 1.304-1.486 2.89-.803 1.586.683 1.527 2.509.602 3.592Zm5.144.399c-.773.096-1.401.023-1.401.023V8.44H17.9s1.642.459 1.642 2.198c0 1.594-.82 2.223-1.716 2.513Z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0 0h24v24H0z"/><path d="M21.9 9.827C21.257 6.423 17.852 6 17.852 6H2.602c-.503 0-.565.665-.565.665s-.069 6.103-.019 9.852c.137 2.02 2.155 2.226 2.155 2.226s6.89-.019 9.972-.04c2.031-.356 2.236-2.139 2.215-3.112 3.626.2 6.185-2.36 5.54-5.764Zm-9.218 2.926c-1.038 1.211-3.342 3.314-3.342 3.314s-.101.099-.258.019c-.064-.048-.09-.075-.09-.075-.37-.368-2.807-2.541-3.362-3.295-.59-.804-.868-2.25-.076-3.092.793-.842 2.504-.905 3.636.34 0 0 1.304-1.486 2.89-.803 1.586.683 1.527 2.509.602 3.592Zm5.144.399c-.773.096-1.401.023-1.401.023V8.44H17.9s1.642.459 1.642 2.198c0 1.594-.82 2.223-1.716 2.513Z"/></svg>

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 694 B

View File

@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0,0H24V24H0Z" fill="none" />
<path d="M8.12,18.36A5.69,5.69,0,0,1,5.79,18a2.41,2.41,0,0,1-1.2-1,3,3,0,0,1-.36-1.53,8.94,8.94,0,0,1,.24-1.84l2.65-11L10.34,2,7.45,14a3,3,0,0,0-.09.68,1.12,1.12,0,0,0,.11.56.86.86,0,0,0,.43.38,2.37,2.37,0,0,0,.84.19Zm11.65-6.89a7.55,7.55,0,0,1-.5,2.78,6.68,6.68,0,0,1-1.39,2.17,6.15,6.15,0,0,1-2.12,1.43,7,7,0,0,1-2.69.51,7.5,7.5,0,0,1-1.42-.13L10.71,22H7.63L11.09,7.6A16.73,16.73,0,0,1,13,7.15,13,13,0,0,1,15.31,7a5.08,5.08,0,0,1,2,.36,3.8,3.8,0,0,1,1.39,1,4.06,4.06,0,0,1,.8,1.44,5.9,5.9,0,0,1,.26,1.76Zm-7.56,4.27a4.33,4.33,0,0,0,.88.08,3.51,3.51,0,0,0,1.47-.3,3.22,3.22,0,0,0,1.14-.85,4,4,0,0,0,.73-1.3,5.18,5.18,0,0,0,.26-1.67,2.79,2.79,0,0,0-.4-1.52,1.48,1.48,0,0,0-1.37-.63,6.15,6.15,0,0,0-1.25.13Z" />
</svg>
<svg fill="currentColor" viewBox="0 0 24 24" width="1em" height="1em"><path fill="none" d="M0,0H24V24H0Z"/><path d="M8.12,18.36A5.69,5.69,0,0,1,5.79,18a2.41,2.41,0,0,1-1.2-1,3,3,0,0,1-.36-1.53,8.94,8.94,0,0,1,.24-1.84l2.65-11L10.34,2,7.45,14a3,3,0,0,0-.09.68,1.12,1.12,0,0,0,.11.56.86.86,0,0,0,.43.38,2.37,2.37,0,0,0,.84.19Zm11.65-6.89a7.55,7.55,0,0,1-.5,2.78,6.68,6.68,0,0,1-1.39,2.17,6.15,6.15,0,0,1-2.12,1.43,7,7,0,0,1-2.69.51,7.5,7.5,0,0,1-1.42-.13L10.71,22H7.63L11.09,7.6A16.73,16.73,0,0,1,13,7.15,13,13,0,0,1,15.31,7a5.08,5.08,0,0,1,2,.36,3.8,3.8,0,0,1,1.39,1,4.06,4.06,0,0,1,.8,1.44,5.9,5.9,0,0,1,.26,1.76Zm-7.56,4.27a4.33,4.33,0,0,0,.88.08,3.51,3.51,0,0,0,1.47-.3,3.22,3.22,0,0,0,1.14-.85,4,4,0,0,0,.73-1.3,5.18,5.18,0,0,0,.26-1.67,2.79,2.79,0,0,0-.4-1.52,1.48,1.48,0,0,0-1.37-.63,6.15,6.15,0,0,0-1.25.13Z"/></svg>

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 822 B

Some files were not shown because too many files have changed in this diff Show More