';
const REWRITE_ON = 'RewriteEngine on';
const LS_MODULE_DONOTEDIT = '## LITESPEED WP CACHE PLUGIN - Do not edit the contents of this block! ##';
const MARKER = 'LSCACHE';
const MARKER_NONLS = 'NON_LSCACHE';
const MARKER_LOGIN_COOKIE = '### marker LOGIN COOKIE';
const MARKER_ASYNC = '### marker ASYNC';
const MARKER_CRAWLER = '### marker CRAWLER';
const MARKER_MOBILE = '### marker MOBILE';
const MARKER_NOCACHE_COOKIES = '### marker NOCACHE COOKIES';
const MARKER_NOCACHE_USER_AGENTS = '### marker NOCACHE USER AGENTS';
const MARKER_CACHE_RESOURCE = '### marker CACHE RESOURCE';
const MARKER_BROWSER_CACHE = '### marker BROWSER CACHE';
const MARKER_MINIFY = '### marker MINIFY';
const MARKER_CORS = '### marker CORS';
const MARKER_WEBP = '### marker WEBP';
const MARKER_DROPQS = '### marker DROPQS';
const MARKER_START = ' start ###';
const MARKER_END = ' end ###';
/**
* Initialize the class and set its properties.
*
* @since 1.0.7
*/
public function __construct() {
$this->_path_set();
$this->_default_frontend_htaccess = $this->frontend_htaccess;
$this->_default_backend_htaccess = $this->backend_htaccess;
$frontend_htaccess = defined('LITESPEED_CFG_HTACCESS') ? constant('LITESPEED_CFG_HTACCESS') : false;
if ($frontend_htaccess && substr($frontend_htaccess, -10) === '/.htaccess') {
$this->frontend_htaccess = $frontend_htaccess;
}
$backend_htaccess = defined('LITESPEED_CFG_HTACCESS_BACKEND') ? constant('LITESPEED_CFG_HTACCESS_BACKEND') : false;
if ($backend_htaccess && substr($backend_htaccess, -10) === '/.htaccess') {
$this->backend_htaccess = $backend_htaccess;
}
// Filter for frontend&backend htaccess path
$this->frontend_htaccess = apply_filters('litespeed_frontend_htaccess', $this->frontend_htaccess);
$this->backend_htaccess = apply_filters('litespeed_backend_htaccess', $this->backend_htaccess);
clearstatcache();
// frontend .htaccess privilege
$test_permissions = file_exists($this->frontend_htaccess) ? $this->frontend_htaccess : dirname($this->frontend_htaccess);
if (is_readable($test_permissions)) {
$this->frontend_htaccess_readable = true;
}
if (is_writable($test_permissions)) {
$this->frontend_htaccess_writable = true;
}
$this->__rewrite_on = array(
self::REWRITE_ON,
'CacheLookup on',
'RewriteRule .* - [E=Cache-Control:no-autoflush]',
'RewriteRule ' . preg_quote(LITESPEED_DATA_FOLDER) . '/debug/.*\.log$ - [F,L]',
'RewriteRule ' . preg_quote(self::CONF_FILE) . ' - [F,L]',
);
// backend .htaccess privilege
if ($this->frontend_htaccess === $this->backend_htaccess) {
$this->backend_htaccess_readable = $this->frontend_htaccess_readable;
$this->backend_htaccess_writable = $this->frontend_htaccess_writable;
} else {
$test_permissions = file_exists($this->backend_htaccess) ? $this->backend_htaccess : dirname($this->backend_htaccess);
if (is_readable($test_permissions)) {
$this->backend_htaccess_readable = true;
}
if (is_writable($test_permissions)) {
$this->backend_htaccess_writable = true;
}
}
}
/**
* Get if htaccess file is readable
*
* @since 1.1.0
* @return string
*/
private function _readable( $kind = 'frontend' ) {
if ($kind === 'frontend') {
return $this->frontend_htaccess_readable;
}
if ($kind === 'backend') {
return $this->backend_htaccess_readable;
}
}
/**
* Get if htaccess file is writable
*
* @since 1.1.0
* @return string
*/
public function writable( $kind = 'frontend' ) {
if ($kind === 'frontend') {
return $this->frontend_htaccess_writable;
}
if ($kind === 'backend') {
return $this->backend_htaccess_writable;
}
}
/**
* Get frontend htaccess path
*
* @since 1.1.0
* @return string
*/
public static function get_frontend_htaccess( $show_default = false ) {
if ($show_default) {
return self::cls()->_default_frontend_htaccess;
}
return self::cls()->frontend_htaccess;
}
/**
* Get backend htaccess path
*
* @since 1.1.0
* @return string
*/
public static function get_backend_htaccess( $show_default = false ) {
if ($show_default) {
return self::cls()->_default_backend_htaccess;
}
return self::cls()->backend_htaccess;
}
/**
* Check to see if .htaccess exists starting at $start_path and going up directories until it hits DOCUMENT_ROOT.
*
* As dirname() strips the ending '/', paths passed in must exclude the final '/'
*
* @since 1.0.11
* @access private
*/
private function _htaccess_search( $start_path ) {
while (!file_exists($start_path . '/.htaccess')) {
if ($start_path === '/' || !$start_path) {
return false;
}
if (!empty($_SERVER['DOCUMENT_ROOT']) && wp_normalize_path($start_path) === wp_normalize_path($_SERVER['DOCUMENT_ROOT'])) {
return false;
}
if (dirname($start_path) === $start_path) {
return false;
}
$start_path = dirname($start_path);
}
return $start_path;
}
/**
* Set the path class variables.
*
* @since 1.0.11
* @access private
*/
private function _path_set() {
$frontend = Router::frontend_path();
$frontend_htaccess_search = $this->_htaccess_search($frontend); // The existing .htaccess path to be used for frontend .htaccess
$this->frontend_htaccess = ($frontend_htaccess_search ?: $frontend) . '/.htaccess';
$backend = realpath(ABSPATH); // /home/user/public_html/backend/
if ($frontend == $backend) {
$this->backend_htaccess = $this->frontend_htaccess;
return;
}
// Backend is a different path
$backend_htaccess_search = $this->_htaccess_search($backend);
// Found affected .htaccess
if ($backend_htaccess_search) {
$this->backend_htaccess = $backend_htaccess_search . '/.htaccess';
return;
}
// Frontend path is the parent of backend path
if (stripos($backend, $frontend . '/') === 0) {
// backend use frontend htaccess
$this->backend_htaccess = $this->frontend_htaccess;
return;
}
$this->backend_htaccess = $backend . '/.htaccess';
}
/**
* Get corresponding htaccess path
*
* @since 1.1.0
* @param string $kind Frontend or backend
* @return string Path
*/
public function htaccess_path( $kind = 'frontend' ) {
switch ($kind) {
case 'backend':
$path = $this->backend_htaccess;
break;
case 'frontend':
default:
$path = $this->frontend_htaccess;
break;
}
return $path;
}
/**
* Get the content of the rules file.
*
* NOTE: will throw error if failed
*
* @since 1.0.4
* @since 2.9 Used exception for failed reading
* @access public
*/
public function htaccess_read( $kind = 'frontend' ) {
$path = $this->htaccess_path($kind);
if (!$path || !file_exists($path)) {
return "\n";
}
if (!$this->_readable($kind)) {
Error::t('HTA_R');
}
$content = File::read($path);
if ($content === false) {
Error::t('HTA_GET');
}
// Remove ^M characters.
$content = str_ireplace("\x0D", '', $content);
return $content;
}
/**
* Try to backup the .htaccess file if we didn't save one before.
*
* NOTE: will throw error if failed
*
* @since 1.0.10
* @access private
*/
private function _htaccess_backup( $kind = 'frontend' ) {
$path = $this->htaccess_path($kind);
if (!file_exists($path)) {
return;
}
if (file_exists($path . '.bk')) {
return;
}
$res = copy($path, $path . '.bk');
// Failed to backup, abort
if (!$res) {
Error::t('HTA_BK');
}
}
/**
* Get mobile view rule from htaccess file
*
* NOTE: will throw error if failed
*
* @since 1.1.0
*/
public function current_mobile_agents() {
$rules = $this->_get_rule_by(self::MARKER_MOBILE);
if (!isset($rules[0])) {
Error::t('HTA_DNF', self::MARKER_MOBILE);
}
$rule = trim($rules[0]);
// 'RewriteCond %{HTTP_USER_AGENT} ' . Utility::arr2regex( $cfg[ $id ], true ) . ' [NC]';
$match = substr($rule, strlen('RewriteCond %{HTTP_USER_AGENT} '), -strlen(' [NC]'));
if (!$match) {
Error::t('HTA_DNF', __('Mobile Agent Rules', 'litespeed-cache'));
}
return $match;
}
/**
* Parse rewrites rule from the .htaccess file.
*
* NOTE: will throw error if failed
*
* @since 1.1.0
* @access public
*/
public function current_login_cookie( $kind = 'frontend' ) {
$rule = $this->_get_rule_by(self::MARKER_LOGIN_COOKIE, $kind);
if (!$rule) {
Error::t('HTA_DNF', self::MARKER_LOGIN_COOKIE);
}
if (strpos($rule, 'RewriteRule .? - [E=') !== 0) {
Error::t('HTA_LOGIN_COOKIE_INVALID');
}
$rule_cookie = substr($rule, strlen('RewriteRule .? - [E='), -1);
if (LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_OLS') {
$rule_cookie = trim($rule_cookie, '"');
}
// Drop `Cache-Vary:`
$rule_cookie = substr($rule_cookie, strlen('Cache-Vary:'));
return $rule_cookie;
}
/**
* Get rewrite rules based on the marker
*
* @since 2.0
* @access private
*/
private function _get_rule_by( $cond, $kind = 'frontend' ) {
clearstatcache();
$path = $this->htaccess_path($kind);
if (!$this->_readable($kind)) {
return false;
}
$rules = File::extract_from_markers($path, self::MARKER);
if (!in_array($cond . self::MARKER_START, $rules) || !in_array($cond . self::MARKER_END, $rules)) {
return false;
}
$key_start = array_search($cond . self::MARKER_START, $rules);
$key_end = array_search($cond . self::MARKER_END, $rules);
if ($key_start === false || $key_end === false) {
return false;
}
$results = array_slice($rules, $key_start + 1, $key_end - $key_start - 1);
if (!$results) {
return false;
}
if (count($results) == 1) {
return trim($results[0]);
}
return array_filter($results);
}
/**
* Generate browser cache rules
*
* @since 1.3
* @access private
* @return array Rules set
*/
private function _browser_cache_rules( $cfg ) {
/**
* Add ttl setting
*
* @since 1.6.3
*/
$id = Base::O_CACHE_TTL_BROWSER;
$ttl = $cfg[$id];
$rules = array(
self::EXPIRES_MODULE_START,
// '',
'ExpiresActive on',
'ExpiresByType application/pdf A' . $ttl,
'ExpiresByType image/x-icon A' . $ttl,
'ExpiresByType image/vnd.microsoft.icon A' . $ttl,
'ExpiresByType image/svg+xml A' . $ttl,
'',
'ExpiresByType image/jpg A' . $ttl,
'ExpiresByType image/jpeg A' . $ttl,
'ExpiresByType image/png A' . $ttl,
'ExpiresByType image/gif A' . $ttl,
'ExpiresByType image/webp A' . $ttl,
'ExpiresByType image/avif A' . $ttl,
'',
'ExpiresByType video/ogg A' . $ttl,
'ExpiresByType audio/ogg A' . $ttl,
'ExpiresByType video/mp4 A' . $ttl,
'ExpiresByType video/webm A' . $ttl,
'',
'ExpiresByType text/css A' . $ttl,
'ExpiresByType text/javascript A' . $ttl,
'ExpiresByType application/javascript A' . $ttl,
'ExpiresByType application/x-javascript A' . $ttl,
'',
'ExpiresByType application/x-font-ttf A' . $ttl,
'ExpiresByType application/x-font-woff A' . $ttl,
'ExpiresByType application/font-woff A' . $ttl,
'ExpiresByType application/font-woff2 A' . $ttl,
'ExpiresByType application/vnd.ms-fontobject A' . $ttl,
'ExpiresByType font/ttf A' . $ttl,
'ExpiresByType font/otf A' . $ttl,
'ExpiresByType font/woff A' . $ttl,
'ExpiresByType font/woff2 A' . $ttl,
'',
// '',
self::LS_MODULE_END,
);
return $rules;
}
/**
* Generate CORS rules for fonts
*
* @since 1.5
* @access private
* @return array Rules set
*/
private function _cors_rules() {
return array(
'',
'',
'Header set Access-Control-Allow-Origin "*"',
'',
'',
);
}
/**
* Generate rewrite rules based on settings
*
* @since 1.3
* @access private
* @param array $cfg The settings to be used for rewrite rule
* @return array Rules array
*/
private function _generate_rules( $cfg ) {
$new_rules = array();
$new_rules_nonls = array();
$new_rules_backend = array();
$new_rules_backend_nonls = array();
// continual crawler
// $id = Base::O_CRAWLER;
// if (!empty($cfg[$id])) {
$new_rules[] = self::MARKER_ASYNC . self::MARKER_START;
$new_rules[] = 'RewriteCond %{REQUEST_URI} /wp-admin/admin-ajax\.php';
$new_rules[] = 'RewriteCond %{QUERY_STRING} action=async_litespeed';
$new_rules[] = 'RewriteRule .* - [E=noabort:1]';
$new_rules[] = self::MARKER_ASYNC . self::MARKER_END;
$new_rules[] = '';
// }
// mobile agents
$id = Base::O_CACHE_MOBILE_RULES;
if ((!empty($cfg[Base::O_CACHE_MOBILE]) || !empty($cfg[Base::O_GUEST])) && !empty($cfg[$id])) {
$new_rules[] = self::MARKER_MOBILE . self::MARKER_START;
$new_rules[] = 'RewriteCond %{HTTP_USER_AGENT} ' . Utility::arr2regex($cfg[$id], true) . ' [NC]';
$new_rules[] = 'RewriteRule .* - [E=Cache-Control:vary=%{ENV:LSCACHE_VARY_VALUE}+ismobile]';
$new_rules[] = self::MARKER_MOBILE . self::MARKER_END;
$new_rules[] = '';
}
// nocache cookie
$id = Base::O_CACHE_EXC_COOKIES;
if (!empty($cfg[$id])) {
$new_rules[] = self::MARKER_NOCACHE_COOKIES . self::MARKER_START;
$new_rules[] = 'RewriteCond %{HTTP_COOKIE} ' . Utility::arr2regex($cfg[$id], true);
$new_rules[] = 'RewriteRule .* - [E=Cache-Control:no-cache]';
$new_rules[] = self::MARKER_NOCACHE_COOKIES . self::MARKER_END;
$new_rules[] = '';
}
// nocache user agents
$id = Base::O_CACHE_EXC_USERAGENTS;
if (!empty($cfg[$id])) {
$new_rules[] = self::MARKER_NOCACHE_USER_AGENTS . self::MARKER_START;
$new_rules[] = 'RewriteCond %{HTTP_USER_AGENT} ' . Utility::arr2regex($cfg[$id], true) . ' [NC]';
$new_rules[] = 'RewriteRule .* - [E=Cache-Control:no-cache]';
$new_rules[] = self::MARKER_NOCACHE_USER_AGENTS . self::MARKER_END;
$new_rules[] = '';
}
// check login cookie
$vary_cookies = $cfg[Base::O_CACHE_VARY_COOKIES];
$id = Base::O_CACHE_LOGIN_COOKIE;
if (!empty($cfg[$id])) {
$vary_cookies[] = $cfg[$id];
}
if (LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_OLS') {
// Need to keep this due to different behavior of OLS when handling response vary header @Sep/22/2018
if (defined('COOKIEHASH')) {
$vary_cookies[] = ',wp-postpass_' . COOKIEHASH;
}
}
$vary_cookies = apply_filters('litespeed_vary_cookies', $vary_cookies); // todo: test if response vary header can work in latest OLS, drop the above two lines
// frontend and backend
if ($vary_cookies) {
$env = 'Cache-Vary:' . implode(',', $vary_cookies);
// if (LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_OLS') {
// }
$env = '"' . $env . '"';
$new_rules[] = $new_rules_backend[] = self::MARKER_LOGIN_COOKIE . self::MARKER_START;
$new_rules[] = $new_rules_backend[] = 'RewriteRule .? - [E=' . $env . ']';
$new_rules[] = $new_rules_backend[] = self::MARKER_LOGIN_COOKIE . self::MARKER_END;
$new_rules[] = '';
}
// CORS font rules
$id = Base::O_CDN;
if (!empty($cfg[$id])) {
$new_rules[] = self::MARKER_CORS . self::MARKER_START;
$new_rules = array_merge($new_rules, $this->_cors_rules()); // todo: network
$new_rules[] = self::MARKER_CORS . self::MARKER_END;
$new_rules[] = '';
}
// webp support
$id = Base::O_IMG_OPTM_WEBP;
if (!empty($cfg[$id])) {
$next_gen_format = 'webp';
if ($cfg[$id] == 2) {
$next_gen_format = 'avif';
}
$new_rules[] = self::MARKER_WEBP . self::MARKER_START;
// Check for WebP support via HTTP_ACCEPT
$new_rules[] = 'RewriteCond %{HTTP_ACCEPT} image/' . $next_gen_format . ' [OR]';
// Check for iPhone browsers (version > 13)
$new_rules[] = 'RewriteCond %{HTTP_USER_AGENT} iPhone\ OS\ (1[4-9]|[2-9][0-9]) [OR]';
// Check for Firefox (version >= 65)
$new_rules[] = 'RewriteCond %{HTTP_USER_AGENT} Firefox/([6-9][0-9]|[1-9][0-9]{2,})';
// Add vary
$new_rules[] = 'RewriteRule .* - [E=Cache-Control:vary=%{ENV:LSCACHE_VARY_VALUE}+webp]';
$new_rules[] = self::MARKER_WEBP . self::MARKER_END;
$new_rules[] = '';
}
// drop qs support
$id = Base::O_CACHE_DROP_QS;
if (!empty($cfg[$id])) {
$new_rules[] = self::MARKER_DROPQS . self::MARKER_START;
foreach ($cfg[$id] as $v) {
$new_rules[] = 'CacheKeyModify -qs:' . $v;
}
$new_rules[] = self::MARKER_DROPQS . self::MARKER_END;
$new_rules[] = '';
}
// Browser cache
$id = Base::O_CACHE_BROWSER;
if (!empty($cfg[$id])) {
$new_rules_nonls[] = $new_rules_backend_nonls[] = self::MARKER_BROWSER_CACHE . self::MARKER_START;
$new_rules_nonls = array_merge($new_rules_nonls, $this->_browser_cache_rules($cfg));
$new_rules_backend_nonls = array_merge($new_rules_backend_nonls, $this->_browser_cache_rules($cfg));
$new_rules_nonls[] = $new_rules_backend_nonls[] = self::MARKER_BROWSER_CACHE . self::MARKER_END;
$new_rules_nonls[] = '';
}
// Add module wrapper for LiteSpeed rules
if ($new_rules) {
$new_rules = $this->_wrap_ls_module($new_rules);
}
if ($new_rules_backend) {
$new_rules_backend = $this->_wrap_ls_module($new_rules_backend);
}
return array( $new_rules, $new_rules_backend, $new_rules_nonls, $new_rules_backend_nonls );
}
/**
* Add LitSpeed module wrapper with rewrite on
*
* @since 2.1.1
* @access private
*/
private function _wrap_ls_module( $rules = array() ) {
return array_merge(array( self::LS_MODULE_START ), $this->__rewrite_on, array( '' ), $rules, array( self::LS_MODULE_END ));
}
/**
* Insert LitSpeed module wrapper with rewrite on
*
* @since 2.1.1
* @access public
*/
public function insert_ls_wrapper() {
$rules = $this->_wrap_ls_module();
$this->_insert_wrapper($rules);
}
/**
* wrap rules with module on info
*
* @since 1.1.5
* @param array $rules
* @return array wrapped rules with module info
*/
private function _wrap_do_no_edit( $rules ) {
// When to clear rules, don't need DONOTEDIT msg
if ($rules === false || !is_array($rules)) {
return $rules;
}
$rules = array_merge(array( self::LS_MODULE_DONOTEDIT ), $rules, array( self::LS_MODULE_DONOTEDIT ));
return $rules;
}
/**
* Write to htaccess with rules
*
* NOTE: will throw error if failed
*
* @since 1.1.0
* @access private
*/
private function _insert_wrapper( $rules = array(), $kind = false, $marker = false ) {
if ($kind != 'backend') {
$kind = 'frontend';
}
// Default marker is LiteSpeed marker `LSCACHE`
if ($marker === false) {
$marker = self::MARKER;
}
$this->_htaccess_backup($kind);
File::insert_with_markers($this->htaccess_path($kind), $this->_wrap_do_no_edit($rules), $marker, true);
}
/**
* Update rewrite rules based on setting
*
* NOTE: will throw error if failed
*
* @since 1.3
* @access public
*/
public function update( $cfg ) {
list($frontend_rules, $backend_rules, $frontend_rules_nonls, $backend_rules_nonls) = $this->_generate_rules($cfg);
// Check frontend content
list($rules, $rules_nonls) = $this->_extract_rules();
// Check Non-LiteSpeed rules
if ($this->_wrap_do_no_edit($frontend_rules_nonls) != $rules_nonls) {
Debug2::debug('[Rules] Update non-ls frontend rules');
// Need to update frontend htaccess
try {
$this->_insert_wrapper($frontend_rules_nonls, false, self::MARKER_NONLS);
} catch (\Exception $e) {
$manual_guide_codes = $this->_rewrite_codes_msg($this->frontend_htaccess, $frontend_rules_nonls, self::MARKER_NONLS);
Debug2::debug('[Rules] Update Failed');
throw new \Exception($manual_guide_codes);
}
}
// Check LiteSpeed rules
if ($this->_wrap_do_no_edit($frontend_rules) != $rules) {
Debug2::debug('[Rules] Update frontend rules');
// Need to update frontend htaccess
try {
$this->_insert_wrapper($frontend_rules);
} catch (\Exception $e) {
Debug2::debug('[Rules] Update Failed');
$manual_guide_codes = $this->_rewrite_codes_msg($this->frontend_htaccess, $frontend_rules);
throw new \Exception($manual_guide_codes);
}
}
if ($this->frontend_htaccess !== $this->backend_htaccess) {
list($rules, $rules_nonls) = $this->_extract_rules('backend');
// Check Non-LiteSpeed rules for backend
if ($this->_wrap_do_no_edit($backend_rules_nonls) != $rules_nonls) {
Debug2::debug('[Rules] Update non-ls backend rules');
// Need to update frontend htaccess
try {
$this->_insert_wrapper($backend_rules_nonls, 'backend', self::MARKER_NONLS);
} catch (\Exception $e) {
Debug2::debug('[Rules] Update Failed');
$manual_guide_codes = $this->_rewrite_codes_msg($this->backend_htaccess, $backend_rules_nonls, self::MARKER_NONLS);
throw new \Exception($manual_guide_codes);
}
}
// Check backend content
if ($this->_wrap_do_no_edit($backend_rules) != $rules) {
Debug2::debug('[Rules] Update backend rules');
// Need to update backend htaccess
try {
$this->_insert_wrapper($backend_rules, 'backend');
} catch (\Exception $e) {
Debug2::debug('[Rules] Update Failed');
$manual_guide_codes = $this->_rewrite_codes_msg($this->backend_htaccess, $backend_rules);
throw new \Exception($manual_guide_codes);
}
}
}
return true;
}
/**
* Get existing rewrite rules
*
* NOTE: will throw error if failed
*
* @since 1.3
* @access private
* @param string $kind Frontend or backend .htaccess file
*/
private function _extract_rules( $kind = 'frontend' ) {
clearstatcache();
$path = $this->htaccess_path($kind);
if (!$this->_readable($kind)) {
Error::t('E_HTA_R');
}
$rules = File::extract_from_markers($path, self::MARKER);
$rules_nonls = File::extract_from_markers($path, self::MARKER_NONLS);
return array( $rules, $rules_nonls );
}
/**
* Output the msg with rules plain data for manual insert
*
* @since 1.1.5
* @param string $file
* @param array $rules
* @return string final msg to output
*/
private function _rewrite_codes_msg( $file, $rules, $marker = false ) {
return sprintf(
__('Please add/replace the following codes into the beginning of %1$s:
%2$s', 'litespeed-cache'),
$file,
''
);
}
/**
* Generate rules plain data for manual insert
*
* @since 1.1.5
*/
private function _wrap_rules_with_marker( $rules, $marker = false ) {
// Default marker is LiteSpeed marker `LSCACHE`
if ($marker === false) {
$marker = self::MARKER;
}
$start_marker = "# BEGIN {$marker}";
$end_marker = "# END {$marker}";
$new_file_data = implode("\n", array_merge(array( $start_marker ), $this->_wrap_do_no_edit($rules), array( $end_marker )));
return $new_file_data;
}
/**
* Clear the rules file of any changes added by the plugin specifically.
*
* @since 1.0.4
* @access public
*/
public function clear_rules() {
$this->_insert_wrapper(false); // Use false to avoid do-not-edit msg
// Clear non ls rules
$this->_insert_wrapper(false, false, self::MARKER_NONLS);
if ($this->frontend_htaccess !== $this->backend_htaccess) {
$this->_insert_wrapper(false, 'backend');
$this->_insert_wrapper(false, 'backend', self::MARKER_NONLS);
}
}
}
/**
* The object cache class.
*
* @since 1.8
* @package LiteSpeed
*/
namespace LiteSpeed;
defined( 'WPINC' ) || exit();
require_once dirname( __DIR__ ) . '/autoload.php';
/**
* Object cache handler using Redis or Memcached.
*
* NOTE: this class may be included without initialized core.
*
* @since 1.8
*/
class Object_Cache extends Root {
const LOG_TAG = '[Object_Cache]';
/**
* Debug option key.
*
* @var string
*/
const O_DEBUG = 'debug';
/**
* Object cache enable key.
*
* @var string
*/
const O_OBJECT = 'object';
/**
* Object kind (Redis/Memcached).
*
* @var string
*/
const O_OBJECT_KIND = 'object-kind';
/**
* Object host.
*
* @var string
*/
const O_OBJECT_HOST = 'object-host';
/**
* Object port.
*
* @var string
*/
const O_OBJECT_PORT = 'object-port';
/**
* Object life/TTL.
*
* @var string
*/
const O_OBJECT_LIFE = 'object-life';
/**
* Persistent connection flag.
*
* @var string
*/
const O_OBJECT_PERSISTENT = 'object-persistent';
/**
* Admin cache flag.
*
* @var string
*/
const O_OBJECT_ADMIN = 'object-admin';
/**
* Transients store flag.
*
* @var string
*/
const O_OBJECT_TRANSIENTS = 'object-transients';
/**
* DB index for Redis.
*
* @var string
*/
const O_OBJECT_DB_ID = 'object-db_id';
/**
* Username for auth.
*
* @var string
*/
const O_OBJECT_USER = 'object-user';
/**
* Password for auth.
*
* @var string
*/
const O_OBJECT_PSWD = 'object-pswd';
/**
* Global groups list.
*
* @var string
*/
const O_OBJECT_GLOBAL_GROUPS = 'object-global_groups';
/**
* Non-persistent groups list.
*
* @var string
*/
const O_OBJECT_NON_PERSISTENT_GROUPS = 'object-non_persistent_groups';
/**
* Connection instance.
*
* @var \Redis|\Memcached|null
*/
private $_conn;
/**
* Debug config.
*
* @var bool
*/
private $_cfg_debug;
/**
* Whether OC is enabled.
*
* @var bool
*/
private $_cfg_enabled;
/**
* True => Redis, false => Memcached.
*
* @var bool
*/
private $_cfg_method;
/**
* Host name.
*
* @var string
*/
private $_cfg_host;
/**
* Port number.
*
* @var int|string
*/
private $_cfg_port;
/**
* TTL in seconds.
*
* @var int
*/
private $_cfg_life;
/**
* Use persistent connection.
*
* @var bool
*/
private $_cfg_persistent;
/**
* Cache admin pages.
*
* @var bool
*/
private $_cfg_admin;
/**
* Store transients.
*
* @var bool
*/
private $_cfg_transients;
/**
* Redis DB index.
*
* @var int
*/
private $_cfg_db;
/**
* Auth username.
*
* @var string
*/
private $_cfg_user;
/**
* Auth password.
*
* @var string
*/
private $_cfg_pswd;
/**
* Default TTL in seconds.
*
* @var int
*/
private $_default_life = 360;
/**
* 'Redis' or 'Memcached'.
*
* @var string
*/
private $_oc_driver = 'Memcached'; // Redis or Memcached.
/**
* Global groups.
*
* @var array
*/
private $_global_groups = array();
/**
* Non-persistent groups.
*
* @var array
*/
private $_non_persistent_groups = array();
/**
* Init.
*
* NOTE: this class may be included without initialized core.
*
* @since 1.8
*
* @param array|false $cfg Optional configuration to bootstrap without core.
*/
public function __construct( $cfg = false ) {
if ( $cfg ) {
if ( ! is_array( $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] ) ) {
$cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] = explode( "\n", $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] );
}
if ( ! is_array( $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] ) ) {
$cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] = explode( "\n", $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] );
}
$this->_cfg_debug = $cfg[ Base::O_DEBUG ] ? $cfg[ Base::O_DEBUG ] : false;
$this->_cfg_method = $cfg[ Base::O_OBJECT_KIND ] ? true : false;
$this->_cfg_host = $cfg[ Base::O_OBJECT_HOST ];
$this->_cfg_port = $cfg[ Base::O_OBJECT_PORT ];
$this->_cfg_life = $cfg[ Base::O_OBJECT_LIFE ];
$this->_cfg_persistent = $cfg[ Base::O_OBJECT_PERSISTENT ];
$this->_cfg_admin = $cfg[ Base::O_OBJECT_ADMIN ];
$this->_cfg_transients = $cfg[ Base::O_OBJECT_TRANSIENTS ];
$this->_cfg_db = $cfg[ Base::O_OBJECT_DB_ID ];
$this->_cfg_user = $cfg[ Base::O_OBJECT_USER ];
$this->_cfg_pswd = $cfg[ Base::O_OBJECT_PSWD ];
$this->_global_groups = $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ];
$this->_non_persistent_groups = $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ];
if ( $this->_cfg_method ) {
$this->_oc_driver = 'Redis';
}
$this->_cfg_enabled = $cfg[ Base::O_OBJECT ] && class_exists( $this->_oc_driver ) && $this->_cfg_host;
} elseif ( defined( 'LITESPEED_CONF_LOADED' ) ) { // If OC is OFF, will hit here to init OC after conf initialized
$this->_cfg_debug = $this->conf( Base::O_DEBUG ) ? $this->conf( Base::O_DEBUG ) : false;
$this->_cfg_method = $this->conf( Base::O_OBJECT_KIND ) ? true : false;
$this->_cfg_host = $this->conf( Base::O_OBJECT_HOST );
$this->_cfg_port = $this->conf( Base::O_OBJECT_PORT );
$this->_cfg_life = $this->conf( Base::O_OBJECT_LIFE );
$this->_cfg_persistent = $this->conf( Base::O_OBJECT_PERSISTENT );
$this->_cfg_admin = $this->conf( Base::O_OBJECT_ADMIN );
$this->_cfg_transients = $this->conf( Base::O_OBJECT_TRANSIENTS );
$this->_cfg_db = $this->conf( Base::O_OBJECT_DB_ID );
$this->_cfg_user = $this->conf( Base::O_OBJECT_USER );
$this->_cfg_pswd = $this->conf( Base::O_OBJECT_PSWD );
$this->_global_groups = $this->conf( Base::O_OBJECT_GLOBAL_GROUPS );
$this->_non_persistent_groups = $this->conf( Base::O_OBJECT_NON_PERSISTENT_GROUPS );
if ( $this->_cfg_method ) {
$this->_oc_driver = 'Redis';
}
$this->_cfg_enabled = $this->conf( Base::O_OBJECT ) && class_exists( $this->_oc_driver ) && $this->_cfg_host;
} elseif ( defined( 'self::CONF_FILE' ) && file_exists( WP_CONTENT_DIR . '/' . self::CONF_FILE ) ) {
// Get cfg from _data_file.
// Use self::const to avoid loading more classes.
$cfg = \json_decode( file_get_contents( WP_CONTENT_DIR . '/' . self::CONF_FILE ), true );
if ( ! empty( $cfg[ self::O_OBJECT_HOST ] ) ) {
$this->_cfg_debug = ! empty( $cfg[ Base::O_DEBUG ] ) ? $cfg[ Base::O_DEBUG ] : false;
$this->_cfg_method = ! empty( $cfg[ self::O_OBJECT_KIND ] ) ? $cfg[ self::O_OBJECT_KIND ] : false;
$this->_cfg_host = $cfg[ self::O_OBJECT_HOST ];
$this->_cfg_port = $cfg[ self::O_OBJECT_PORT ];
$this->_cfg_life = ! empty( $cfg[ self::O_OBJECT_LIFE ] ) ? $cfg[ self::O_OBJECT_LIFE ] : $this->_default_life;
$this->_cfg_persistent = ! empty( $cfg[ self::O_OBJECT_PERSISTENT ] ) ? $cfg[ self::O_OBJECT_PERSISTENT ] : false;
$this->_cfg_admin = ! empty( $cfg[ self::O_OBJECT_ADMIN ] ) ? $cfg[ self::O_OBJECT_ADMIN ] : false;
$this->_cfg_transients = ! empty( $cfg[ self::O_OBJECT_TRANSIENTS ] ) ? $cfg[ self::O_OBJECT_TRANSIENTS ] : false;
$this->_cfg_db = ! empty( $cfg[ self::O_OBJECT_DB_ID ] ) ? $cfg[ self::O_OBJECT_DB_ID ] : 0;
$this->_cfg_user = ! empty( $cfg[ self::O_OBJECT_USER ] ) ? $cfg[ self::O_OBJECT_USER ] : '';
$this->_cfg_pswd = ! empty( $cfg[ self::O_OBJECT_PSWD ] ) ? $cfg[ self::O_OBJECT_PSWD ] : '';
$this->_global_groups = ! empty( $cfg[ self::O_OBJECT_GLOBAL_GROUPS ] ) ? $cfg[ self::O_OBJECT_GLOBAL_GROUPS ] : array();
$this->_non_persistent_groups = ! empty( $cfg[ self::O_OBJECT_NON_PERSISTENT_GROUPS ] ) ? $cfg[ self::O_OBJECT_NON_PERSISTENT_GROUPS ] : array();
if ( $this->_cfg_method ) {
$this->_oc_driver = 'Redis';
}
$this->_cfg_enabled = class_exists( $this->_oc_driver ) && $this->_cfg_host;
} else {
$this->_cfg_enabled = false;
}
} else {
$this->_cfg_enabled = false;
}
}
/**
* Add debug.
*
* @since 6.3
* @access private
*
* @param string $text Log text.
* @return void
*/
private function debug_oc( $text ) {
if ( defined( 'LSCWP_LOG' ) ) {
self::debug( $text );
return;
}
if ( Base::VAL_ON2 !== $this->_cfg_debug ) {
return;
}
$litespeed_data_folder = defined( 'LITESPEED_DATA_FOLDER' ) ? LITESPEED_DATA_FOLDER : 'litespeed';
$lscwp_content_dir = defined( 'LSCWP_CONTENT_DIR' ) ? LSCWP_CONTENT_DIR : WP_CONTENT_DIR;
$litespeed_static_dir = $lscwp_content_dir . '/' . $litespeed_data_folder;
$log_path_prefix = $litespeed_static_dir . '/debug/';
$log_file = $log_path_prefix . Debug2::FilePath( 'debug' );
if ( file_exists( $log_path_prefix . 'index.php' ) && file_exists( $log_file ) ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
error_log(gmdate('m/d/y H:i:s') . ' - OC - ' . $text . PHP_EOL, 3, $log_file);
}
}
/**
* Get `Store Transients` setting value.
*
* @since 1.8.3
* @access public
*
* @param string $group Group name.
* @return bool
*/
public function store_transients( $group ) {
return $this->_cfg_transients && $this->_is_transients_group( $group );
}
/**
* Check if the group belongs to transients or not.
*
* @since 1.8.3
* @access private
*
* @param string $group Group name.
* @return bool
*/
private function _is_transients_group( $group ) {
return in_array( $group, array( 'transient', 'site-transient' ), true );
}
/**
* Update WP object cache file config.
*
* @since 1.8
* @access public
*
* @param array $options Options to apply after update.
* @return void
*/
public function update_file( $options ) {
$changed = false;
// NOTE: When included in oc.php, `LSCWP_DIR` will show undefined, so this must be assigned/generated when used.
$_oc_ori_file = LSCWP_DIR . 'lib/object-cache.php';
$_oc_wp_file = WP_CONTENT_DIR . '/object-cache.php';
// Update cls file.
if ( ! file_exists( $_oc_wp_file ) || md5_file( $_oc_wp_file ) !== md5_file( $_oc_ori_file ) ) {
$this->debug_oc( 'copying object-cache.php file to ' . $_oc_wp_file );
copy( $_oc_ori_file, $_oc_wp_file );
$changed = true;
}
/**
* Clear object cache.
*/
if ( $changed ) {
$this->_reconnect( $options );
}
}
/**
* Remove object cache file.
*
* @since 1.8.2
* @access public
*
* @return void
*/
public function del_file() {
// NOTE: When included in oc.php, `LSCWP_DIR` will show undefined, so this must be assigned/generated when used.
$_oc_ori_file = LSCWP_DIR . 'lib/object-cache.php';
$_oc_wp_file = WP_CONTENT_DIR . '/object-cache.php';
if ( file_exists( $_oc_wp_file ) && md5_file( $_oc_wp_file ) === md5_file( $_oc_ori_file ) ) {
$this->debug_oc( 'removing ' . $_oc_wp_file );
wp_delete_file( $_oc_wp_file );
}
}
/**
* Try to build connection.
*
* @since 1.8
* @access public
*
* @return bool|null False on failure, true on success, null if unsupported.
*/
public function test_connection() {
return $this->_connect();
}
/**
* Force to connect with this setting.
*
* @since 1.8
* @access private
*
* @param array $cfg Reconnect configuration.
* @return void
*/
private function _reconnect( $cfg ) {
$this->debug_oc( 'Reconnecting' );
if ( isset( $this->_conn ) ) {
// error_log( 'Object: Quitting existing connection!' );
$this->debug_oc( 'Quitting existing connection' );
$this->flush();
$this->_conn = null;
$this->cls( false, true );
}
$cls = $this->cls( false, false, $cfg );
$cls->_connect();
if ( isset( $cls->_conn ) ) {
$cls->flush();
}
}
/**
* Connect to Memcached/Redis server.
*
* @since 1.8
* @access private
*
* @return bool|null False on failure, true on success, null if driver missing.
*/
private function _connect() {
if ( isset( $this->_conn ) ) {
// error_log( 'Object: _connected' );
return true;
}
if ( ! class_exists( $this->_oc_driver ) || ! $this->_cfg_host ) {
$this->debug_oc( '_oc_driver cls non existed or _cfg_host missed: ' . $this->_oc_driver . ' [_cfg_host] ' . $this->_cfg_host . ':' . $this->_cfg_port );
return null;
}
if ( defined( 'LITESPEED_OC_FAILURE' ) ) {
$this->debug_oc( 'LITESPEED_OC_FAILURE const defined' );
return false;
}
$this->debug_oc( 'Init ' . $this->_oc_driver . ' connection to ' . $this->_cfg_host . ':' . $this->_cfg_port );
$failed = false;
/**
* Connect to Redis.
*
* @since 1.8.1
* @see https://github.com/phpredis/phpredis/#example-1
*/
if ( 'Redis' === $this->_oc_driver ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
set_error_handler( 'litespeed_exception_handler' );
try {
$this->_conn = new \Redis();
// error_log( 'Object: _connect Redis' );
if ( $this->_cfg_persistent ) {
if ( $this->_cfg_port ) {
$this->_conn->pconnect( $this->_cfg_host, $this->_cfg_port );
} else {
$this->_conn->pconnect( $this->_cfg_host );
}
} elseif ( $this->_cfg_port ) {
$this->_conn->connect( $this->_cfg_host, $this->_cfg_port );
} else {
$this->_conn->connect( $this->_cfg_host );
}
if ( $this->_cfg_pswd ) {
if ( $this->_cfg_user ) {
$this->_conn->auth( array( $this->_cfg_user, $this->_cfg_pswd ) );
} else {
$this->_conn->auth( $this->_cfg_pswd );
}
}
if (defined('Redis::OPT_REPLY_LITERAL')) {
$this->debug_oc( 'Redis set OPT_REPLY_LITERAL' );
$this->_conn->setOption(\Redis::OPT_REPLY_LITERAL, true);
}
if ( $this->_cfg_db ) {
$this->_conn->select( $this->_cfg_db );
}
$res = $this->_conn->rawCommand('PING');
if ( 'PONG' !== $res ) {
$this->debug_oc( 'Redis resp is wrong: ' . $res );
$failed = true;
}
} catch ( \Exception $e ) {
$this->debug_oc( 'Redis connect exception: ' . $e->getMessage() );
$failed = true;
} catch ( \ErrorException $e ) {
$this->debug_oc( 'Redis connect error: ' . $e->getMessage() );
$failed = true;
}
restore_error_handler();
} else {
// Connect to Memcached.
if ( $this->_cfg_persistent ) {
$this->_conn = new \Memcached( $this->_get_mem_id() );
// Check memcached persistent connection.
if ( $this->_validate_mem_server() ) {
// error_log( 'Object: _validate_mem_server' );
$this->debug_oc( 'Got persistent ' . $this->_oc_driver . ' connection' );
return true;
}
$this->debug_oc( 'No persistent ' . $this->_oc_driver . ' server list!' );
} else {
// error_log( 'Object: new memcached!' );
$this->_conn = new \Memcached();
}
$this->_conn->addServer( $this->_cfg_host, (int) $this->_cfg_port );
/**
* Add SASL auth.
*
* @since 1.8.1
* @since 2.9.6 Fixed SASL connection @see https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:lsmcd:new_sasl
*/
if ( $this->_cfg_user && $this->_cfg_pswd && method_exists( $this->_conn, 'setSaslAuthData' ) ) {
$this->_conn->setOption( \Memcached::OPT_BINARY_PROTOCOL, true );
$this->_conn->setOption( \Memcached::OPT_COMPRESSION, false );
$this->_conn->setSaslAuthData( $this->_cfg_user, $this->_cfg_pswd );
}
// Check connection.
if ( ! $this->_validate_mem_server() ) {
$failed = true;
}
}
// If failed to connect.
if ( $failed ) {
$this->debug_oc( '❌ Failed to connect ' . $this->_oc_driver . ' server!' );
$this->_conn = null;
$this->_cfg_enabled = false;
! defined( 'LITESPEED_OC_FAILURE' ) && define( 'LITESPEED_OC_FAILURE', true );
// error_log( 'Object: false!' );
return false;
}
$this->debug_oc( '✅ Connected to ' . $this->_oc_driver . ' server.' );
return true;
}
/**
* Check if the connected memcached host is the one in cfg.
*
* @since 1.8
* @access private
*
* @return bool
*/
private function _validate_mem_server() {
$mem_list = $this->_conn->getStats();
if ( empty( $mem_list ) ) {
return false;
}
foreach ( $mem_list as $k => $v ) {
if ( substr( $k, 0, strlen( $this->_cfg_host ) ) !== $this->_cfg_host ) {
continue;
}
if ( ! empty( $v['pid'] ) || ! empty( $v['curr_connections'] ) ) {
return true;
}
}
return false;
}
/**
* Get memcached unique id to be used for connecting.
*
* @since 1.8
* @access private
*
* @return string
*/
private function _get_mem_id() {
$mem_id = 'litespeed';
if ( is_multisite() ) {
$mem_id .= '_' . get_current_blog_id();
}
return $mem_id;
}
/**
* Get cache.
*
* @since 1.8
* @access public
*
* @param string $key Cache key.
* @return mixed|null
*/
public function get( $key ) {
if ( ! $this->_cfg_enabled ) {
return null;
}
if ( ! $this->_can_cache() ) {
return null;
}
if ( ! $this->_connect() ) {
return null;
}
$res = $this->_conn->get( $key );
return $res;
}
/**
* Set cache.
*
* @since 1.8
* @access public
*
* @param string $key Cache key.
* @param mixed $data Data to store.
* @param int $expire TTL seconds.
* @return bool|null
*/
public function set( $key, $data, $expire ) {
if ( ! $this->_cfg_enabled ) {
return null;
}
/**
* To fix the Cloud callback cached as its frontend call but the hash is generated in backend
* Bug found by Stan at Jan/10/2020
*/
// if ( ! $this->_can_cache() ) {
// return null;
// }
if ( ! $this->_connect() ) {
return null;
}
$ttl = $expire ? $expire : $this->_cfg_life;
if ( 'Redis' === $this->_oc_driver ) {
try {
$res = $this->_conn->setEx( $key, $ttl, $data );
} catch ( \RedisException $ex ) {
$res = false;
$msg = sprintf( __( 'Redis encountered a fatal error: %1$s (code: %2$d)', 'litespeed-cache' ), $ex->getMessage(), $ex->getCode() );
$this->debug_oc( $msg );
Admin_Display::error( $msg );
}
} else {
$res = $this->_conn->set( $key, $data, $ttl );
}
return $res;
}
/**
* Check if can cache or not.
*
* @since 1.8
* @access private
*
* @return bool
*/
private function _can_cache() {
if ( ! $this->_cfg_admin && defined( 'WP_ADMIN' ) ) {
return false;
}
return true;
}
/**
* Delete cache.
*
* @since 1.8
* @access public
*
* @param string $key Cache key.
* @return bool|null
*/
public function delete( $key ) {
if ( ! $this->_cfg_enabled ) {
return null;
}
if ( ! $this->_connect() ) {
return null;
}
if ( 'Redis' === $this->_oc_driver ) {
$res = $this->_conn->del( $key );
} else {
$res = $this->_conn->delete( $key );
}
return (bool) $res;
}
/**
* Clear all cache.
*
* @since 1.8
* @access public
*
* @return bool|null
*/
public function flush() {
if ( ! $this->_cfg_enabled ) {
$this->debug_oc( 'bypass flushing' );
return null;
}
if ( ! $this->_connect() ) {
return null;
}
$this->debug_oc( 'flush!' );
if ( 'Redis' === $this->_oc_driver ) {
$res = $this->_conn->flushDb();
} else {
$res = $this->_conn->flush();
$this->_conn->resetServerList();
}
return $res;
}
/**
* Add global groups.
*
* @since 1.8
* @access public
*
* @param string|string[] $groups Group(s) to add.
* @return void
*/
public function add_global_groups( $groups ) {
if ( ! is_array( $groups ) ) {
$groups = array( $groups );
}
$this->_global_groups = array_merge( $this->_global_groups, $groups );
$this->_global_groups = array_unique( $this->_global_groups );
}
/**
* Check if is in global groups or not.
*
* @since 1.8
* @access public
*
* @param string $group Group name.
* @return bool
*/
public function is_global( $group ) {
return in_array( $group, $this->_global_groups, true );
}
/**
* Add non persistent groups.
*
* @since 1.8
* @access public
*
* @param string|string[] $groups Group(s) to add.
* @return void
*/
public function add_non_persistent_groups( $groups ) {
if ( ! is_array( $groups ) ) {
$groups = array( $groups );
}
$this->_non_persistent_groups = array_merge( $this->_non_persistent_groups, $groups );
$this->_non_persistent_groups = array_unique( $this->_non_persistent_groups );
}
/**
* Check if is in non persistent groups or not.
*
* @since 1.8
* @access public
*
* @param string $group Group name.
* @return bool
*/
public function is_non_persistent( $group ) {
return in_array( $group, $this->_non_persistent_groups, true );
}
}
:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}#woocommerce-admin-print-label{min-height:100px}#woocommerce-admin-print-label .handlediv,#woocommerce-admin-print-label .hndle,#woocommerce-admin-print-label .postbox-header{display:none}#woocommerce-admin-print-label .wc-admin-shipping-banner-container{display:flex;align-items:center;margin-top:18px;margin-bottom:6px}#woocommerce-admin-print-label .wc-admin-shipping-banner-blob,#woocommerce-admin-print-label .wc-admin-shipping-banner-illustration{margin-right:8px}#woocommerce-admin-print-label h3{margin:0;font-size:1.15em}#woocommerce-admin-print-label p{margin:0;font-size:15px;line-height:19px}#woocommerce-admin-print-label .components-button.is-primary{margin:10px 61px 10px auto;padding:0 30px;font-size:14px;font-weight:500;line-height:25px;text-decoration:none;text-shadow:none;overflow:visible}#woocommerce-admin-print-label .notice-dismiss{top:14px;right:18px}#woocommerce-admin-print-label .wc-admin-shipping-banner-install-error{color:#d63638}#woocommerce-admin-print-label .wc-admin-shipping-banner-install-error>.warning-icon{margin-right:3px;vertical-align:middle;margin-top:-2px}#woocommerce-admin-print-label .wc-admin-shipping-banner-install-error>.warning-icon path{fill:#d63638}#woocommerce-admin-print-label .components-external-link__icon{display:none}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal{width:500px;max-width:100%}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .components-modal__header .components-button.has-icon{left:15px}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .components-modal__header .components-button.has-icon svg{width:30px;height:30px}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .components-modal__header-heading{font-style:normal;font-weight:500;font-size:20px;line-height:32px}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .wc-admin-shipping-banner__dismiss-modal-help-text{font-size:16px;line-height:24px}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .wc-admin-shipping-banner__dismiss-modal-actions{text-align:right}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .wc-admin-shipping-banner__dismiss-modal-actions .components-button.is-primary{padding-left:15px;padding-right:15px;text-align:center;font-size:14px;line-height:15px;font-weight:500;align-items:center;margin-left:10px}.components-modal__frame.wc-admin-shipping-banner__dismiss-modal .wc-admin-shipping-banner__dismiss-modal-actions button.is-primary{align-self:flex-end}@media(max-width:1080px){#woocommerce-admin-print-label{text-align:center}#woocommerce-admin-print-label .wc-admin-shipping-banner-container{flex-wrap:wrap;justify-content:center}#woocommerce-admin-print-label .components-button.is-primary{margin:10px 0 0}#woocommerce-admin-print-label p{margin:5px 15px;max-width:none}#woocommerce-admin-print-label h3{margin-top:10px}}.notice.wcs-nux__notice,.wc-admin-shipping-banner__dismiss-modal .components-button span{display:none}+
-
*
/
%
=
+=
-=
*=
/=
%=
<<=
>>=
>>>=
&=
^=
|=
&
|
^
~
<<
>>
>>>
==
===
!=
!==
>
<
>=
<=
&&
||
!
.
[
?
:
,
;
(
{
/**
* LiteSpeed Cache option Interface CLI.
*
* @package LiteSpeed\CLI
*/
namespace LiteSpeed\CLI;
defined( 'WPINC' ) || exit();
use LiteSpeed\Base;
use LiteSpeed\Admin_Settings;
use LiteSpeed\Utility;
use WP_CLI;
use WP_Filesystem;
/**
* LiteSpeed Cache option Interface
*/
class Option extends Base {
/**
* Set an individual LiteSpeed Cache option.
*
* ## OPTIONS
*
*
* : The option key to update.
*
*
* : The new value to set the option to.
*
* ## EXAMPLES
*
* # Set to not cache the login page
* $ wp litespeed-option set cache-priv false
* $ wp litespeed-option set 'cdn-mapping[url][0]' https://cdn.EXAMPLE.com
* $ wp litespeed-option set media-lqip_exc $'line1\nline2'
*
* @param array $args Positional arguments (key, newvalue).
* @param array $assoc_args Associative arguments.
*/
public function set( $args, $assoc_args ) {
// Note: If the value is multiple dimensions like cdn-mapping, need to specially handle it both here and in `const.default.json`
// For CDN/Crawler multi dimension settings, if all children are empty in one line, will delete that line. To delete one line, just set all to empty.
// E.g. to delete cdn-mapping[0], need to run below:
// `set cdn-mapping[url][0] ''`
// `set cdn-mapping[inc_img][0] ''`
// `set cdn-mapping[inc_css][0] ''`
// `set cdn-mapping[inc_js][0] ''`
// `set cdn-mapping[filetype][0] ''`
$key = $args[0];
$val = $args[1];
// For CDN mapping, allow:
// `set 'cdn-mapping[url][0]' https://the1st_cdn_url`
// `set 'cdn-mapping[inc_img][0]' true`
// `set 'cdn-mapping[inc_img][0]' 1`
//
// For Crawler cookies:
// `set 'crawler-cookies[name][0]' my_currency`
// `set 'crawler-cookies[vals][0]' "USD\nTWD"`
//
// For multi lines setting:
// `set media-lqip_exc $'img1.jpg\nimg2.jpg'`
// Build raw data
$raw_data = array(
Admin_Settings::ENROLL => array( $key ),
);
// Contains child set
if ( false !== strpos( $key, '[' ) ) {
parse_str( $key . '=' . $val, $key2 );
$raw_data = array_merge( $raw_data, $key2 );
} else {
$raw_data[ $key ] = $val;
}
$this->cls( 'Admin_Settings' )->save( $raw_data );
WP_CLI::line( "$key:" );
$this->get( $args, $assoc_args );
}
/**
* Get all plugin options.
*
* ## OPTIONS
*
* [--format=]
* : Output format (e.g., json).
*
* ## EXAMPLES
*
* # Get all options
* $ wp litespeed-option all
* $ wp litespeed-option all --json
*
* @param array $args Positional arguments.
* @param array $assoc_args Associative arguments.
*/
public function all( $args, $assoc_args ) {
$options = $this->get_options();
if ( ! empty( $assoc_args['format'] ) ) {
WP_CLI::print_value( $options, $assoc_args );
return;
}
$option_out = array();
$buf = WP_CLI::colorize( '%CThe list of options:%n' );
WP_CLI::line( $buf );
foreach ( $options as $k => $v ) {
if ( self::O_CDN_MAPPING === $k || self::O_CRAWLER_COOKIES === $k ) {
foreach ( $v as $k2 => $v2 ) {
// $k2 is numeric
if ( is_array( $v2 ) ) {
foreach ( $v2 as $k3 => $v3 ) {
// $k3 is 'url/inc_img/name/vals'
if ( is_array( $v3 ) ) {
$option_out[] = array(
'key' => '',
'value' => '',
);
foreach ( $v3 as $k4 => $v4 ) {
$option_out[] = array(
'key' => 0 === $k4 ? "{$k}[$k3][$k2]" : '',
'value' => $v4,
);
}
$option_out[] = array(
'key' => '',
'value' => '',
);
} else {
$option_out[] = array(
'key' => "{$k}[$k3][$k2]",
'value' => $v3,
);
}
}
}
}
continue;
} elseif ( is_array( $v ) && $v ) {
$option_out[] = array(
'key' => '',
'value' => '',
);
foreach ( $v as $k2 => $v2 ) {
$option_out[] = array(
'key' => 0 === $k2 ? $k : '',
'value' => $v2,
);
}
$option_out[] = array(
'key' => '',
'value' => '',
);
continue;
}
if ( array_key_exists( $k, self::$_default_options ) && is_bool( self::$_default_options[ $k ] ) && ! $v ) {
$v = 0;
}
if ( '' === $v || array() === $v ) {
$v = "''";
}
$option_out[] = array(
'key' => $k,
'value' => $v,
);
}
WP_CLI\Utils\format_items( 'table', $option_out, array( 'key', 'value' ) );
}
/**
* Get a specific plugin option.
*
* ## OPTIONS
*
*
* : The option ID to retrieve (e.g., cache-priv, cdn-mapping[url][0]).
*
* ## EXAMPLES
*
* # Get one option
* $ wp litespeed-option get cache-priv
* $ wp litespeed-option get 'cdn-mapping[url][0]'
*
* @param array $args Positional arguments (id).
* @param array $assoc_args Associative arguments.
*/
public function get( $args, $assoc_args ) {
$id = $args[0];
$child = false;
if ( false !== strpos( $id, '[' ) ) {
parse_str( $id, $id2 );
Utility::compatibility();
$id = array_key_first( $id2 );
$child = array_key_first( $id2[ $id ] ); // is `url`
if ( ! $child ) {
WP_CLI::error( 'Wrong child key' );
return;
}
$numeric = array_key_first( $id2[ $id ][ $child ] ); // `0`
if ( null === $numeric ) {
WP_CLI::error( 'Wrong 2nd level numeric key' );
return;
}
}
if ( ! isset( self::$_default_options[ $id ] ) ) {
WP_CLI::error( 'ID not exist [id] ' . $id );
return;
}
$v = $this->conf( $id );
$default_v = self::$_default_options[ $id ];
// For CDN_mapping and crawler_cookies
// Examples of option name:
// cdn-mapping[url][0]
// crawler-cookies[name][1]
if ( self::O_CDN_MAPPING === $id ) {
if ( ! in_array( $child, array( self::CDN_MAPPING_URL, self::CDN_MAPPING_INC_IMG, self::CDN_MAPPING_INC_CSS, self::CDN_MAPPING_INC_JS, self::CDN_MAPPING_FILETYPE ), true ) ) {
WP_CLI::error( 'Wrong child key' );
return;
}
}
if ( self::O_CRAWLER_COOKIES === $id ) {
if ( ! in_array( $child, array( self::CRWL_COOKIE_NAME, self::CRWL_COOKIE_VALS ), true ) ) {
WP_CLI::error( 'Wrong child key' );
return;
}
}
if ( self::O_CDN_MAPPING === $id || self::O_CRAWLER_COOKIES === $id ) {
if ( ! empty( $v[ $numeric ][ $child ] ) ) {
$v = $v[ $numeric ][ $child ];
} elseif ( self::O_CDN_MAPPING === $id ) {
if ( in_array( $child, array( self::CDN_MAPPING_INC_IMG, self::CDN_MAPPING_INC_CSS, self::CDN_MAPPING_INC_JS ), true ) ) {
$v = 0;
} else {
$v = "''";
}
} else {
$v = "''";
}
}
if ( is_array( $v ) ) {
$v = implode( PHP_EOL, $v );
}
if ( ! $v && self::O_CDN_MAPPING !== $id && self::O_CRAWLER_COOKIES !== $id ) {
// empty array for CDN/crawler has been handled
if ( is_bool( $default_v ) ) {
$v = 0;
} elseif ( ! is_array( $default_v ) ) {
$v = "''";
}
}
WP_CLI::line( $v );
}
/**
* Export plugin options to a file.
*
* ## OPTIONS
*
* [--filename=]
* : The default path used is CURRENTDIR/lscache_wp_options_DATE-TIME.txt.
* To select a different file, use this option.
*
* ## EXAMPLES
*
* # Export options to a file.
* $ wp litespeed-option export
*
* @param array $args Positional arguments.
* @param array $assoc_args Associative arguments.
*/
public function export( $args, $assoc_args ) {
if ( isset( $assoc_args['filename'] ) ) {
$file = $assoc_args['filename'];
} else {
$file = getcwd() . '/litespeed_options_' . gmdate( 'd_m_Y-His' ) . '.data';
}
global $wp_filesystem;
if ( ! $wp_filesystem ) {
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
if ( ! $wp_filesystem->is_writable( dirname( $file ) ) ) {
WP_CLI::error( 'Directory not writable.' );
return;
}
$data = $this->cls( 'Import' )->export( true );
if ( false === $wp_filesystem->put_contents( $file, $data ) ) {
WP_CLI::error( 'Failed to create file.' );
return;
}
WP_CLI::success( 'Created file ' . $file );
}
/**
* Import plugin options from a file.
*
* The file must be formatted as such:
* option_key=option_value
* One per line.
* A semicolon at the beginning of the line indicates a comment and will be skipped.
*
* ## OPTIONS
*
*
* : The file to import options from.
*
* ## EXAMPLES
*
* # Import options from CURRENTDIR/options.txt
* $ wp litespeed-option import options.txt
*
* @param array $args Positional arguments (file).
* @param array $assoc_args Associative arguments.
*/
public function import( $args, $assoc_args ) {
$file = $args[0];
global $wp_filesystem;
if ( ! $wp_filesystem ) {
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
if ( ! $wp_filesystem->exists( $file ) || ! $wp_filesystem->is_readable( $file ) ) {
WP_CLI::error( 'File does not exist or is not readable.' );
return;
}
$res = $this->cls( 'Import' )->import( $file );
if ( ! $res ) {
WP_CLI::error( 'Failed to parse serialized data from file.' );
return;
}
WP_CLI::success( 'Options imported. [File] ' . $file );
}
/**
* Import plugin options from a remote file.
*
* The file must be formatted as such:
* option_key=option_value
* One per line.
* A semicolon at the beginning of the line indicates a comment and will be skipped.
*
* ## OPTIONS
*
*
* : The URL to import options from.
*
* ## EXAMPLES
*
* # Import options from https://domain.com/options.txt
* $ wp litespeed-option import_remote https://domain.com/options.txt
*
* @param array $args Positional arguments (url).
*/
public function import_remote( $args ) {
$file = $args[0];
$tmp_file = download_url( $file );
if ( is_wp_error( $tmp_file ) ) {
WP_CLI::error( 'Failed to download file.' );
return;
}
$res = $this->cls( 'Import' )->import( $tmp_file );
if ( ! $res ) {
WP_CLI::error( 'Failed to parse serialized data from file.' );
return;
}
WP_CLI::success( 'Options imported. [File] ' . $file );
}
/**
* Reset all options to default.
*
* ## EXAMPLES
*
* # Reset all options
* $ wp litespeed-option reset
*/
public function reset() {
$this->cls( 'Import' )->reset();
}
}
/*! @elementor/editor-app-bar */
/*! @elementor/editor-v1-adapters */
/*! @elementor/icons */
/*! @elementor/store */
/*! @elementor/ui */
/*! @wordpress/i18n */
/*! react */
/*!**************************!*\
!*** external ["React"] ***!
\**************************/
/*!******************************!*\
!*** external ["wp","i18n"] ***!
\******************************/
/*!*************************************!*\
!*** external ["elementorV2","ui"] ***!
\*************************************/
/*!****************************************!*\
!*** external ["elementorV2","icons"] ***!
\****************************************/
/*!****************************************!*\
!*** external ["elementorV2","store"] ***!
\****************************************/
/*!***********************************************!*\
!*** external ["elementorV2","editorAppBar"] ***!
\***********************************************/
/*!***************************************************!*\
!*** external ["elementorV2","editorV1Adapters"] ***!
\***************************************************/
/*!******************************************************************!*\
!*** ./node_modules/@elementor/editor-responsive/dist/index.mjs ***!
\******************************************************************/
// phpcs:ignoreFile
/**
* Rewrite file-relative URIs as root-relative in CSS files
*
* @package Minify
* @author Stephen Clay
*/
namespace LiteSpeed\Lib;
defined( 'WPINC' ) || exit;
class UriRewriter {
/**
* rewrite() and rewriteRelative() append debugging information here
*
* @var string
*/
public static $debugText = '';
/**
* In CSS content, rewrite file relative URIs as root relative
*
* @param string $css
*
* @param string $currentDir The directory of the current CSS file.
*
* @param string $docRoot The document root of the web site in which
* the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']).
*
* @param array $symlinks (default = array()) If the CSS file is stored in
* a symlink-ed directory, provide an array of link paths to
* target paths, where the link paths are within the document root. Because
* paths need to be normalized for this to work, use "//" to substitute
* the doc root in the link paths (the array keys). E.g.:
*
* array('//symlink' => '/real/target/path') // unix
* array('//static' => 'D:\\staticStorage') // Windows
*
*
* @return string
*/
public static function rewrite( $css, $currentDir, $docRoot = null, $symlinks = array() ) {
self::$_docRoot = self::_realpath(
$docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']
);
self::$_currentDir = self::_realpath( $currentDir );
self::$_symlinks = array();
// normalize symlinks in order to map to link
foreach ( $symlinks as $link => $target ) {
$link = ( $link === '//' ) ? self::$_docRoot : str_replace( '//', self::$_docRoot . '/', $link );
$link = strtr( $link, '/', DIRECTORY_SEPARATOR );
self::$_symlinks[ $link ] = self::_realpath( $target );
}
self::$debugText .= 'docRoot : ' . self::$_docRoot . "\n"
. 'currentDir : ' . self::$_currentDir . "\n";
if ( self::$_symlinks ) {
self::$debugText .= 'symlinks : ' . var_export( self::$_symlinks, 1 ) . "\n";
}
self::$debugText .= "\n";
$css = self::_trimUrls( $css );
$css = self::_owlifySvgPaths( $css );
// rewrite
$pattern = '/@import\\s+([\'"])(.*?)[\'"]/';
$css = preg_replace_callback( $pattern, __CLASS__ . '::_processUriCB', $css );
$pattern = '/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/';
$css = preg_replace_callback( $pattern, __CLASS__ . '::_processUriCB', $css );
$css = self::_unOwlify( $css );
return $css;
}
/**
* In CSS content, prepend a path to relative URIs
*
* @param string $css
*
* @param string $path The path to prepend.
*
* @return string
*/
public static function prepend( $css, $path ) {
self::$_prependPath = $path;
$css = self::_trimUrls( $css );
$css = self::_owlifySvgPaths( $css );
// append
$pattern = '/@import\\s+([\'"])(.*?)[\'"]/';
$css = preg_replace_callback( $pattern, __CLASS__ . '::_processUriCB', $css );
$pattern = '/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/';
$css = preg_replace_callback( $pattern, __CLASS__ . '::_processUriCB', $css );
$css = self::_unOwlify( $css );
self::$_prependPath = null;
return $css;
}
/**
* Get a root relative URI from a file relative URI
*
*
* UriRewriter::rewriteRelative(
* '../img/hello.gif'
* , '/home/user/www/css' // path of CSS file
* , '/home/user/www' // doc root
* );
* // returns '/img/hello.gif'
*
* // example where static files are stored in a symlinked directory
* UriRewriter::rewriteRelative(
* 'hello.gif'
* , '/var/staticFiles/theme'
* , '/home/user/www'
* , array('/home/user/www/static' => '/var/staticFiles')
* );
* // returns '/static/theme/hello.gif'
*
*
* @param string $uri file relative URI
*
* @param string $realCurrentDir realpath of the current file's directory.
*
* @param string $realDocRoot realpath of the site document root.
*
* @param array $symlinks (default = array()) If the file is stored in
* a symlink-ed directory, provide an array of link paths to
* real target paths, where the link paths "appear" to be within the document
* root. E.g.:
*
* array('/home/foo/www/not/real/path' => '/real/target/path') // unix
* array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows
*
*
* @return string
*/
public static function rewriteRelative( $uri, $realCurrentDir, $realDocRoot, $symlinks = array() ) {
// prepend path with current dir separator (OS-independent)
$path = strtr( $realCurrentDir, '/', DIRECTORY_SEPARATOR );
$path .= DIRECTORY_SEPARATOR . strtr( $uri, '/', DIRECTORY_SEPARATOR );
self::$debugText .= "file-relative URI : {$uri}\n"
. "path prepended : {$path}\n";
// "unresolve" a symlink back to doc root
foreach ( $symlinks as $link => $target ) {
if ( 0 === strpos( $path, $target ) ) {
// replace $target with $link
$path = $link . substr( $path, strlen( $target ) );
self::$debugText .= "symlink unresolved : {$path}\n";
break;
}
}
// strip doc root
$path = substr( $path, strlen( $realDocRoot ) );
self::$debugText .= "docroot stripped : {$path}\n";
// fix to root-relative URI
$uri = strtr( $path, '/\\', '//' );
$uri = self::removeDots( $uri );
self::$debugText .= "traversals removed : {$uri}\n\n";
return $uri;
}
/**
* Remove instances of "./" and "../" where possible from a root-relative URI
*
* @param string $uri
*
* @return string
*/
public static function removeDots( $uri ) {
$uri = str_replace( '/./', '/', $uri );
// inspired by patch from Oleg Cherniy
do {
$uri = preg_replace( '@/[^/]+/\\.\\./@', '/', $uri, 1, $changed );
} while ( $changed );
return $uri;
}
/**
* Get realpath with any trailing slash removed. If realpath() fails,
* just remove the trailing slash.
*
* @param string $path
*
* @return mixed path with no trailing slash
*/
protected static function _realpath( $path ) {
$realPath = realpath( $path );
if ( $realPath !== false ) {
$path = $realPath;
}
return rtrim( $path, '/\\' );
}
/**
* Directory of this stylesheet
*
* @var string
*/
private static $_currentDir = '';
/**
* DOC_ROOT
*
* @var string
*/
private static $_docRoot = '';
/**
* directory replacements to map symlink targets back to their
* source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
*
* @var array
*/
private static $_symlinks = array();
/**
* Path to prepend
*
* @var string
*/
private static $_prependPath = null;
/**
* @param string $css
*
* @return string
*/
private static function _trimUrls( $css ) {
$pattern = '/
url\\( # url(
\\s*
([^\\)]+?) # 1 = URI (assuming does not contain ")")
\\s*
\\) # )
/x';
return preg_replace( $pattern, 'url($1)', $css );
}
/**
* @param array $m
*
* @return string
*/
private static function _processUriCB( $m ) {
// $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
$isImport = ( $m[0][0] === '@' );
// determine URI and the quote character (if any)
if ( $isImport ) {
$quoteChar = $m[1];
$uri = $m[2];
} else {
// $m[1] is either quoted or not
$quoteChar = ( $m[1][0] === "'" || $m[1][0] === '"' ) ? $m[1][0] : '';
$uri = ( $quoteChar === '' ) ? $m[1] : substr( $m[1], 1, strlen( $m[1] ) - 2 );
}
if ( $uri === '' ) {
return $m[0];
}
// if not anchor id, not root/scheme relative, and not starts with scheme
if ( ! preg_match( '~^(#|/|[a-z]+\:)~', $uri ) ) {
// URI is file-relative: rewrite depending on options
if ( self::$_prependPath === null ) {
$uri = self::rewriteRelative( $uri, self::$_currentDir, self::$_docRoot, self::$_symlinks );
} else {
$uri = self::$_prependPath . $uri;
if ( $uri[0] === '/' ) {
$root = '';
$rootRelative = $uri;
$uri = $root . self::removeDots( $rootRelative );
} elseif ( preg_match( '@^((https?\:)?//([^/]+))/@', $uri, $m ) && ( false !== strpos( $m[3], '.' ) ) ) {
$root = $m[1];
$rootRelative = substr( $uri, strlen( $root ) );
$uri = $root . self::removeDots( $rootRelative );
}
}
}
if ( $isImport ) {
return "@import {$quoteChar}{$uri}{$quoteChar}";
} else {
return "url({$quoteChar}{$uri}{$quoteChar})";
}
}
/**
* Mungs some inline SVG URL declarations so they won't be touched
*
* @link https://github.com/mrclay/minify/issues/517
* @see _unOwlify
*
* @param string $css
* @return string
*/
private static function _owlifySvgPaths( $css ) {
$pattern = '~\b((?:clip-path|mask|-webkit-mask)\s*\:\s*)url(\(\s*#\w+\s*\))~';
return preg_replace( $pattern, '$1owl$2', $css );
}
/**
* Undo work of _owlify
*
* @see _owlifySvgPaths
*
* @param string $css
* @return string
*/
private static function _unOwlify( $css ) {
$pattern = '~\b((?:clip-path|mask|-webkit-mask)\s*\:\s*)owl~';
return preg_replace( $pattern, '$1url', $css );
}
}
// phpcs:ignoreFile
/**
* The registry for Third Party Plugins Integration files.
*
* This file is only used to include the integration files/classes.
* This works as an entry point for the initial add_action for the
* detect function.
*
* It is not required to add all integration files here, this just provides
* a common place for plugin authors to append their file to.
*/
defined('WPINC') || exit();
use LiteSpeed\API;
$third_cls = array(
'Aelia_CurrencySwitcher',
'Autoptimize',
'Avada',
'BBPress',
'Beaver_Builder',
'Caldera_Forms',
'Divi_Theme_Builder',
'Facetwp',
'LiteSpeed_Check',
'Theme_My_Login',
'User_Switching',
'WCML',
'WooCommerce',
'WC_PDF_Product_Vouchers',
'Woo_Paypal',
'Wp_Polls',
'WP_PostRatings',
'Wpdiscuz',
'WPLister',
'WPML',
'WpTouch',
'Yith_Wishlist',
);
foreach ($third_cls as $cls) {
add_action('litespeed_load_thirdparty', 'LiteSpeed\Thirdparty\\' . $cls . '::detect');
}
// Preload needed for certain thirdparty
add_action('litespeed_init', 'LiteSpeed\Thirdparty\Divi_Theme_Builder::preload');
add_action('litespeed_init', 'LiteSpeed\Thirdparty\WooCommerce::preload');
add_action('litespeed_init', 'LiteSpeed\Thirdparty\NextGenGallery::preload');
add_action('litespeed_init', 'LiteSpeed\Thirdparty\AMP::preload');
add_action('litespeed_init', 'LiteSpeed\Thirdparty\Elementor::preload');
add_action('litespeed_init', 'LiteSpeed\Thirdparty\Gravity_Forms::preload');
add_action('litespeed_init', 'LiteSpeed\Thirdparty\Perfmatters::preload');
/**
* Plugin Name: Skyboot Custom Icons for Elementor
* Description: Skyboot Custom Icons for Elementor expands your Elementor icon library with 14,300+ icons from 15 packs, fully customizable in Elementor's editor.
* Plugin URI: https://skybootstrap.com/custom-icons-for-elementor/
* Version: 1.1.0
* Author: Skybootstrap
* Author URI: https://skybootstrap.com/
* License: GPLv3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
* Text Domain: skb_cife
* Domain Path: /languages
**/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
// Define Useful Contastant
define( 'SKB_CIFE_VERSION', '1.1.0' );
define( 'SKB_CIFE_PL_ROOT', __FILE__ );
define( 'SKB_CIFE_PL_URL', plugin_dir_url( SKB_CIFE_PL_ROOT ) );
define( 'SKB_CIFE_PL_PATH', plugin_dir_path( SKB_CIFE_PL_ROOT ) );
define( 'SKB_CIFE_PLUGIN_BASE', plugin_basename( SKB_CIFE_PL_ROOT ) );
define( 'SKB_CIFE_ASSETS', trailingslashit( SKB_CIFE_PL_URL . 'assets' ) );
// Include Base class and Helper Fuctions
require_once SKB_CIFE_PL_PATH . 'includes/class-base.php';
require_once SKB_CIFE_PL_PATH . 'includes/helper-functions.php';
/**
* Register the activation hook.
*
* When the plugin is activated, call the 'activate' method of our base class.
*/
register_activation_hook( SKB_CIFE_PL_ROOT, [ 'Skb_Cife\Skb_Cife_Base', 'activate' ] );
/**
* The main instance of the plugin.
*/
\Skb_Cife\Skb_Cife_Base::instance();/**
* UAE.
*
* @package UAE
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Uae_Nps_Survey' ) ) :
/**
* Admin
*/
class Uae_Nps_Survey {
/**
* Instance
*
* @since 1.0.0
* @var (Object) Uae_Nps_Survey
*/
private static $instance = null;
/**
* Get Instance
*
* @since 1.0.0
*
* @return object Class object.
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*
* @since 1.0.0
*/
private function __construct() {
$this->version_check();
add_action( 'init', array( $this, 'load' ), 999 );
}
/**
* Version Check
*
* @return void
*/
public function version_check() {
$file = realpath( dirname( __FILE__ ) . '/nps-survey/version.json' );
// Is file exist?
if ( is_file( $file ) ) {
$file_data = json_decode( file_get_contents( $file ), true ); //phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown
global $nps_survey_version, $nps_survey_init;
$path = realpath( dirname( __FILE__ ) . '/nps-survey/nps-survey.php' );
$version = isset( $file_data['nps-survey'] ) ? $file_data['nps-survey'] : 0;
if ( null === $nps_survey_version ) {
$nps_survey_version = '1.0.0';
}
// Compare versions.
if ( version_compare( $version, $nps_survey_version, '>=' ) ) {
$nps_survey_version = $version;
$nps_survey_init = $path;
}
}
}
/**
* Load latest plugin
*
* @return void
*/
public function load() {
global $nps_survey_version, $nps_survey_init;
if ( is_file( realpath( $nps_survey_init ) ) ) {
include_once realpath( $nps_survey_init );
}
}
}
/**
* Kicking this off by calling 'get_instance()' method
*/
Uae_Nps_Survey::get_instance();
endif;
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor repeater element.
*
* Elementor repeater handler class is responsible for initializing the repeater.
*
* @since 1.0.0
*/
class Repeater extends Element_Base {
/**
* Repeater counter.
*
* Holds the Repeater counter data. Default is `0`.
*
* @since 1.0.0
* @access private
* @static
*
* @var int Repeater counter.
*/
private static $counter = 0;
/**
* Holds the count of the CURRENT instance
*
* @var int
*/
private $id;
/**
* Repeater constructor.
*
* Initializing Elementor repeater element.
*
* @since 1.0.7
* @access public
*
* @param array $data Optional. Element data. Default is an empty array.
* @param array|null $args Optional. Element default arguments. Default is null.
*
*/
public function __construct( array $data = [], array $args = null ) {
self::$counter++;
$this->id = self::$counter;
parent::__construct( $data, $args );
$this->add_control(
'_id',
[
'type' => Controls_Manager::HIDDEN,
]
);
}
/**
* Get repeater name.
*
* Retrieve the repeater name.
*
* @since 1.0.7
* @access public
*
* @return string Repeater name.
*/
public function get_name() {
return 'repeater-' . $this->id;
}
/**
* Get repeater type.
*
* Retrieve the repeater type.
*
* @since 1.0.0
* @access public
* @static
*
* @return string Repeater type.
*/
public static function get_type() {
return 'repeater';
}
/**
* Add new repeater control to stack.
*
* Register a repeater control to allow the user to set/update data.
*
* This method should be used inside `register_controls()`.
*
* @since 1.0.0
* @access public
*
* @param string $id Repeater control ID.
* @param array $args Repeater control arguments.
* @param array $options Optional. Repeater control options. Default is an
* empty array.
*
* @return bool True if repeater control added, False otherwise.
*/
public function add_control( $id, array $args, $options = [] ) {
$current_tab = $this->get_current_tab();
if ( null !== $current_tab ) {
$args = array_merge( $args, $current_tab );
}
return parent::add_control( $id, $args, $options );
}
/**
* Get repeater fields.
*
* Retrieve the fields from the current repeater control.
*
* @since 1.5.0
* @deprecated 2.1.0 Use `Repeater::get_controls()` instead.
* @access public
*
* @return array Repeater fields.
*/
public function get_fields() {
_deprecated_function( __METHOD__, '2.1.0', __CLASS__ . '::get_controls()' );
return array_values( $this->get_controls() );
}
/**
* Get default child type.
*
* Retrieve the repeater child type based on element data.
*
* Note that repeater does not support children, therefore it returns false.
*
* @since 1.0.0
* @access protected
*
* @param array $element_data Element ID.
*
* @return false Repeater default child type or False if type not found.
*/
protected function _get_default_child_type( array $element_data ) {
return false;
}
protected function handle_control_position( array $args, $control_id, $overwrite ) {
return $args;
}
}
/*! elementor-pro - v3.16.0 - 14-09-2023 */
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "../modules/page-transitions/assets/js/frontend/components/index.js":
/*!**************************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/components/index.js ***!
\**************************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({
value: true
}));
Object.defineProperty(exports, "PageTransition", ({
enumerable: true,
get: function () {
return _pageTransition.PageTransition;
}
}));
Object.defineProperty(exports, "Preloader", ({
enumerable: true,
get: function () {
return _preloader.Preloader;
}
}));
var _pageTransition = __webpack_require__(/*! ./page-transition/page-transition */ "../modules/page-transitions/assets/js/frontend/components/page-transition/page-transition.js");
var _preloader = __webpack_require__(/*! ./preloader/preloader */ "../modules/page-transitions/assets/js/frontend/components/preloader/preloader.js");
/***/ }),
/***/ "../modules/page-transitions/assets/js/frontend/components/page-transition/filters.js":
/*!********************************************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/components/page-transition/filters.js ***!
\********************************************************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
// Ref: https://stackoverflow.com/questions/26088849/url-fragment-allowed-characters
const urlFragmentPattern = /.*#[\w\-/$.+()*@?~!&',;=:%]*$/;
var _default = {
// Disable using data attribute.
isDisabled: a => Object.prototype.hasOwnProperty.call(a.dataset, 'eDisablePageTransition'),
// Allow only links from same origin and without a URL fragment (e.g. #some-string).
isEmptyHref: a => !a.getAttribute('href'),
isTargetBlank: a => '_blank' === a.target,
notSameOrigin: a => !a.href.startsWith(window.location.origin),
hasFragment: a => !!a.href.match(urlFragmentPattern),
// Internal page links, popups, etc.
// Disable for popup links / menu toggles, only when they are closed (to allow opening).
isPopup: a => 'true' === a.getAttribute('aria-haspopup') && 'false' === a.getAttribute('aria-expanded'),
// Disable in WooCommerce links.
isWoocommerce: a => {
const isAddToCart = a.href.match(/\?add-to-cart=/),
isRemoveFromCart = a.href.match(/\?remove_item=/),
isRestoreToCart = a.href.match(/\?undo_item=/),
isWoocommercePagination = a.href.match(/\?product-page=/),
isWoocommerceLogout = a.href.match(/\?elementor_wc_logout=/),
isWoocommerceTab = a.parentElement?.classList.contains('woocommerce-MyAccount-navigation-link');
return isAddToCart || isRemoveFromCart || isRestoreToCart || isWoocommercePagination || isWoocommerceLogout || isWoocommerceTab;
},
// Custom regex filter from attributes.
isExcluded: (a, exclude) => a.href.match(new RegExp(exclude))
};
exports["default"] = _default;
/***/ }),
/***/ "../modules/page-transitions/assets/js/frontend/components/page-transition/page-transition.js":
/*!****************************************************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/components/page-transition/page-transition.js ***!
\****************************************************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = exports.PageTransition = void 0;
var _pageTransitionComponent = _interopRequireDefault(__webpack_require__(/*! ./page-transition.component.scss */ "../modules/page-transitions/assets/js/frontend/components/page-transition/page-transition.component.scss"));
var _filters = _interopRequireDefault(__webpack_require__(/*! ./filters */ "../modules/page-transitions/assets/js/frontend/components/page-transition/filters.js"));
class PageTransition extends HTMLElement {
/**
* Initialize the Page Transitions element.
*
* @return {void}
*/
constructor() {
super();
this.classes = this.getClasses();
this.elements = this.getElements();
this.bindEvents();
}
/**
* Get a list of classes that are used in the code.
*
* @return {Object} - List of classes.
*/
getClasses() {
return {
preloader: 'e-page-transition--preloader',
entering: 'e-page-transition--entering',
exiting: 'e-page-transition--exiting',
entered: 'e-page-transition--entered',
preview: 'e-page-transition--preview'
};
}
/**
* Get the Page Transition CSS.
*
* @return {string} - CSS code.
*/
getStyle() {
return ``;
}
/**
* A list of attributes to observe for changes.
*
* @return {string[]} - Attributes to observe.
*/
static get observedAttributes() {
return ['preloader-type', 'preloader-icon', 'preloader-image-url', 'preloader-animation-type', 'disabled'];
}
/**
* Get the Page Transitions elements.
*
* @return {Object} - Elements.
*/
getElements() {
const triggers = this.getAttribute('triggers'),
selector = triggers || 'a:not( [data-elementor-open-lightbox="yes"] )';
return {
links: document.querySelectorAll(selector)
};
}
/**
* Determine if a link should trigger a Page Transition effect.
*
* @param {HTMLAnchorElement} a - The anchor element to check.
* @return {boolean} - Whether the given link should activate the Page Transition.
*/
shouldPageTriggerTransition(a) {
return Object.values(_filters.default).every(shouldDisable => !shouldDisable(a, this.getAttribute('exclude')));
}
/**
* Hide the loader on page show.
*
* @return {void}
*/
onPageShow() {
// To disable animation on back / forward click.
if (this.classList.contains(this.classes.exiting)) {
this.classList.add(this.classes.entered);
this.classList.remove(this.classes.exiting);
}
// Animate the loader on page load.
this.animateState('entering').then(() => {
this.classList.add(this.classes.entered);
});
}
/**
* Trigger the Page Transition on link click.
*
* @param {MouseEvent} e - The click Event.
* @return {void}
*/
onLinkClick(e) {
if (!this.shouldPageTriggerTransition(e.currentTarget)) {
return;
}
e.preventDefault();
const href = e.currentTarget.href;
this.classList.remove(this.classes.entered);
this.animateState('exiting', this.getPreloaderDelay()).then(() => {
this.classList.add(this.classes.exiting);
// Redirect the user to the clicked href only after the Page Transition has entered.
location.href = href;
});
}
/**
* Prerender a webpage using `rel=prerender`.
*
* @param {string} href
* @return {void}
*/
prerender(href) {
if (document.querySelector(`link[href="${href}"]`)) {
return;
}
const link = document.createElement('link');
link.setAttribute('rel', 'prerender');
link.setAttribute('href', href);
document.head.appendChild(link);
}
/**
* Trigger a `prerender` on link mouse enter.
*
* @param {MouseEvent} e
* @return {void}
*/
onLinkMouseEnter(e) {
if (!this.shouldPageTriggerTransition(e.currentTarget)) {
return;
}
this.prerender(e.currentTarget.href);
}
/**
* Bind events to the window & links.
*
* @return {void}
*/
bindEvents() {
window.addEventListener('pageshow', this.onPageShow.bind(this));
window.addEventListener('DOMContentLoaded', () => {
this.elements = this.getElements();
this.elements.links.forEach(a => {
a.addEventListener('click', this.onLinkClick.bind(this));
a.addEventListener('mouseenter', this.onLinkMouseEnter.bind(this));
a.addEventListener('touchstart', this.onLinkMouseEnter.bind(this));
});
});
}
/**
* Escape HTML special chars to prevent XSS.
*
* @param {string} str - String to escape.
*
* @return {string} escaped string
*/
escapeHTML(str) {
const specialChars = {
'&': '&',
'<': '<',
'>': '>',
"'": ''',
'"': '"'
};
return str.replace(/[&<>'"]/g, tag => specialChars[tag] || tag);
}
/**
* Retrieve an icon loader HTML markup.
*
* @return {string} - HTML markup.
*/
getIconLoader() {
const icon = this.getAttribute('preloader-icon') || '';
return `
`;
}
/**
* Retrieve an image loader HTML markup.
*
* @return {string} - HTML markup.
*/
getImageLoader() {
const url = this.getAttribute('preloader-image-url') || '';
return `
`;
}
/**
* Retrieve a custom loader HTML markup.
*
* @return {string} - HTML markup.
*/
getAnimationLoader() {
const type = this.getAttribute('preloader-animation-type');
if (!type) {
return '';
}
return `
`;
}
/**
* Render the Page Transition element.
*
* @return {void}
*/
render() {
// Don't render when the Page Transition is disabled.
if (this.hasAttribute('disabled')) {
this.innerHTML = '';
return;
}
const loaderType = this.getAttribute('preloader-type');
switch (loaderType) {
case 'icon':
this.innerHTML = this.getIconLoader();
break;
case 'image':
this.innerHTML = this.getImageLoader();
break;
case 'animation':
this.innerHTML = this.getAnimationLoader();
break;
default:
this.innerHTML = '';
break;
}
this.innerHTML += this.getStyle();
}
/**
* Get a CSS variable value from the current element's context.
*
* @param {string} variable - Variable name.
* @param {string} prefix - Variable prefix, defaults to `e-page-transition`.
* @return {string} - CSS variable value.
*/
getCssVar(variable) {
let prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'e-page-transition-';
return window.getComputedStyle(this).getPropertyValue(`--${prefix}${variable}`);
}
/**
* Get the animation duration as an integer in order to be used inside a `setTimeout`.
*
* Assumes that all of the timings are in `ms`.
*
* @return {number} - Animation duration.
*/
getAnimationDuration() {
return parseInt(this.getCssVar('animation-duration')) || 0;
}
/**
* Get the preloader delay.
*
* Assumes that all of the timings are in `ms`.
*
* @return {number} - Preloader delay.
*/
getPreloaderDelay() {
return parseInt(this.getCssVar('delay', 'e-preloader-')) || 0;
}
/**
* Start the animate sequence of the Page Transition (enter && exit).
*
* @return {Promise} - Animation sequence Promise.
*/
animate() {
// Don't animate if there is already an animation in progress.
if (this.isAnimating) {
return new Promise((resolve, reject) => {
reject('Animation is already in progress.');
});
}
this.isAnimating = true;
// Delay the exit animation so the user will be able to see the loader for a second.
const delay = this.getPreloaderDelay() + 1500;
this.classList.remove(this.classes.entered);
return new Promise(resolve => {
// Defer to make sure that the `entered` class is fully removed before animating.
// Return a Promise for animations chaining.
setTimeout(() => {
this.animateState('exiting', delay).then(() => {
this.animateState('entering').then(() => {
this.classList.add(this.classes.entered);
this.isAnimating = false;
resolve();
});
});
});
});
}
/**
* Animate a state of the Page Transition (enter || exit).
*
* @param {('entering'|'exiting')} state - The state name to animate.
* @param {number} delay - Delay (in ms) before resolving the Promise.
* @return {Promise} - Animation sequence Promise.
*/
animateState(state) {
let delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
const className = this.classes?.[state];
if (!className) {
return new Promise((resolve, reject) => {
reject(state);
});
}
// Remove and add the class again to force the animation, since it's using `animation-fill-mode: forwards`.
this.classList.remove(className);
this.classList.add(className);
// Return a Promise for animations chaining.
const animationDuration = this.getAnimationDuration();
return new Promise(resolve => {
setTimeout(() => {
this.classList.remove(className);
resolve(state);
}, animationDuration + delay);
});
}
/**
* Listen to attribute changes and re-render the element.
*
* @return {void}
*/
attributeChangedCallback() {
this.render();
}
/**
* Render the element when attached to the document.
*
* @return {void}
*/
connectedCallback() {
this.render();
}
}
exports.PageTransition = PageTransition;
var _default = PageTransition;
exports["default"] = _default;
/***/ }),
/***/ "../modules/page-transitions/assets/js/frontend/components/preloader/preloader.js":
/*!****************************************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/components/preloader/preloader.js ***!
\****************************************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = exports.Preloader = void 0;
var _preloaderComponent = _interopRequireDefault(__webpack_require__(/*! ./preloader.component.scss */ "../modules/page-transitions/assets/js/frontend/components/preloader/preloader.component.scss"));
class Preloader extends HTMLElement {
/**
* A list of attributes to observe for changes.
*
* @return {string[]} - Attributes to observe.
*/
static get observedAttributes() {
return ['type'];
}
/**
* Listen to attribute changes and re-render the element.
*
* @return {void}
*/
attributeChangedCallback() {
this.render();
}
/**
* Get the Preloader CSS.
*
* @return {string} - CSS code.
*/
getStyle() {
return ``;
}
/**
* Render the Preloader element.
*
* @return {void}
*/
render() {
const type = this.getAttribute('type'),
dotsTypes = ['bouncing-dots', 'pulsing-dots'];
this.innerHTML = '';
if (!type) {
return;
}
if (dotsTypes.includes(type)) {
this.innerHTML += `
`;
}
this.innerHTML += this.getStyle();
}
/**
* Render the element when attached to the document.
*
* @return {void}
*/
connectedCallback() {
this.render();
}
}
exports.Preloader = Preloader;
var _default = Preloader;
exports["default"] = _default;
/***/ }),
/***/ "../modules/page-transitions/assets/js/frontend/components/page-transition/page-transition.component.scss":
/*!****************************************************************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/components/page-transition/page-transition.component.scss ***!
\****************************************************************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../../../node_modules/css-loader/dist/runtime/api.js */ "../node_modules/css-loader/dist/runtime/api.js");
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);
// Imports
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});
// Module
___CSS_LOADER_EXPORT___.push([module.id, "e-page-transition{--preloader-fade-duration: .5s;--preloader-delay: calc( var( --e-page-transition-animation-duration, 0s ) + var( --e-preloader-delay, 0s ) );--page-transition-delay: var( --preloader-fade-duration );position:fixed;inset:0;display:grid;place-items:center;z-index:10000;background:#fff;animation-fill-mode:both;animation-duration:var(--e-page-transition-animation-duration)}e-page-transition[disabled]{display:none}e-page-transition e-preloader,e-page-transition .e-page-transition--preloader{opacity:0}e-page-transition .e-page-transition--preloader{position:absolute;font-size:var(--e-preloader-size);color:var(--e-preloader-color);fill:var(--e-preloader-color);width:var(--e-preloader-width);max-width:var(--e-preloader-max-width);transform:rotate(var(--e-preloader-rotate, 0deg));animation-name:var(--e-preloader-animation);animation-duration:var(--e-preloader-animation-duration, 1000ms);animation-iteration-count:infinite;animation-timing-function:linear}e-page-transition svg.e-page-transition--preloader{width:var(--e-preloader-size)}.e-page-transition--entering{animation-name:var(--e-page-transition-entrance-animation);animation-delay:var(--preloader-fade-duration, 0s)}.e-page-transition--entering e-preloader,.e-page-transition--entering .e-page-transition--preloader{animation:var(--e-preloader-animation, none) var(--e-preloader-animation-duration, 0s) linear infinite,e-page-transition-fade-out var(--preloader-fade-duration) both;transition:none}.e-page-transition--exiting{animation-name:var(--e-page-transition-exit-animation)}.e-page-transition--exiting e-preloader,.e-page-transition--exiting .e-page-transition--preloader{opacity:var(--e-preloader-opacity, 1);transition:var(--preloader-fade-duration) all;transition-delay:var(--preloader-delay, 0s)}.e-page-transition--entered:not(.e-page-transition--preview){display:none}.e-page-transition--preview{animation-fill-mode:initial}.e-page-transition--preview.e-page-transition--entered e-preloader,.e-page-transition--preview.e-page-transition--entered .e-page-transition--preloader{opacity:var(--e-preloader-opacity, 1)}@media(prefers-reduced-motion: reduce){e-page-transition{display:none}}@keyframes e-page-transition-fade-in{from{opacity:0}to{opacity:1}}@keyframes e-page-transition-fade-in-down{from{opacity:0;transform:translate3d(0, -100%, 0)}to{opacity:1;transform:none}}@keyframes e-page-transition-fade-in-left{from{opacity:0;transform:translate3d(-100%, 0, 0)}to{opacity:1;transform:none}}@keyframes e-page-transition-fade-in-right{from{opacity:0;transform:translate3d(100%, 0, 0)}to{opacity:1;transform:none}}@keyframes e-page-transition-fade-in-up{from{opacity:0;transform:translate3d(0, 100%, 0)}to{opacity:1;transform:none}}@keyframes e-page-transition-zoom-in{from{opacity:0;transform:scale3d(0.3, 0.3, 0.3)}50%{opacity:1}}@keyframes e-page-transition-slide-in-down{from{transform:translate3d(0, -100%, 0);visibility:visible}to{transform:translate3d(0, 0, 0)}}@keyframes e-page-transition-slide-in-left{from{transform:translate3d(-100%, 0, 0);visibility:visible}to{transform:translate3d(0, 0, 0)}}@keyframes e-page-transition-slide-in-right{from{transform:translate3d(100%, 0, 0);visibility:visible}to{transform:translate3d(0, 0, 0)}}@keyframes e-page-transition-slide-in-up{from{transform:translate3d(0, 100%, 0);visibility:visible}to{transform:translate3d(0, 0, 0)}}@keyframes e-page-transition-fade-out{from{opacity:1}to{opacity:0}}@keyframes e-page-transition-fade-out-up{from{opacity:1;transform:none}to{opacity:0;transform:translate3d(0, -100%, 0)}}@keyframes e-page-transition-fade-out-left{from{opacity:1;transform:none}to{opacity:0;transform:translate3d(-100%, 0, 0)}}@keyframes e-page-transition-fade-out-right{from{opacity:1;transform:none}to{opacity:0;transform:translate3d(100%, 0, 0)}}@keyframes e-page-transition-fade-out-down{from{opacity:1;transform:none}to{opacity:0;transform:translate3d(0, 100%, 0)}}@keyframes e-page-transition-slide-out-up{from{transform:translate3d(0, 0, 0)}to{transform:translate3d(0, -100%, 0);visibility:visible}}@keyframes e-page-transition-slide-out-left{from{transform:translate3d(0, 0, 0)}to{transform:translate3d(-100%, 0, 0);visibility:visible}}@keyframes e-page-transition-slide-out-right{from{transform:translate3d(0, 0, 0)}to{transform:translate3d(100%, 0, 0);visibility:visible}}@keyframes e-page-transition-slide-out-down{from{transform:translate3d(0, 0, 0)}to{transform:translate3d(0, 100%, 0);visibility:visible}}@keyframes e-page-transition-zoom-out{from{opacity:1}50%{opacity:0;transform:scale3d(0.3, 0.3, 0.3)}}", ""]);
// Exports
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
/***/ }),
/***/ "../modules/page-transitions/assets/js/frontend/components/preloader/preloader.component.scss":
/*!****************************************************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/components/preloader/preloader.component.scss ***!
\****************************************************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../../../node_modules/css-loader/dist/runtime/api.js */ "../node_modules/css-loader/dist/runtime/api.js");
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);
// Imports
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});
// Module
___CSS_LOADER_EXPORT___.push([module.id, "e-preloader{--default-duartion: 1000ms;--duration: var( --e-preloader-animation-duration, var( --default-duration ) );display:block;font-size:var(--e-preloader-size)}e-preloader[type=circle],e-preloader[type=circle-dashed],e-preloader[type=spinners]{--e-preloader-animation: e-preloader-spin;height:1em;width:1em;border:.1em solid var(--e-preloader-color);border-top-color:rgba(0,0,0,0);border-radius:100%;animation:var(--duration) var(--e-preloader-animation) linear infinite}e-preloader[type=circle-dashed]{border:.1em solid rgba(255,255,255,.3);border-top-color:var(--e-preloader-color)}e-preloader[type=spinners]{border-bottom-color:rgba(0,0,0,0)}e-preloader[type=bouncing-dots],e-preloader[type=pulsing-dots]{display:flex;gap:1em}e-preloader[type=bouncing-dots] i,e-preloader[type=pulsing-dots] i{height:1em;width:1em;border-radius:100%;background-color:var(--e-preloader-color)}e-preloader[type=bouncing-dots] i:nth-child(2),e-preloader[type=pulsing-dots] i:nth-child(2){animation-delay:var(--delay)}e-preloader[type=bouncing-dots] i:nth-child(3),e-preloader[type=pulsing-dots] i:nth-child(3){animation-delay:calc(var(--delay)*2)}e-preloader[type=bouncing-dots] i:nth-child(4),e-preloader[type=pulsing-dots] i:nth-child(4){animation-delay:calc(var(--delay)*3)}e-preloader[type=bouncing-dots] i{--delay: calc( var( --duration ) / 10 );animation:var(--duration) e-preloader-bounce linear infinite}e-preloader[type=pulsing-dots] i{--delay: calc( var( --duration ) / 6 );animation:var(--duration) e-preloader-pulsing-dots linear infinite}e-preloader[type=pulse]{height:1em;width:1em;position:relative}e-preloader[type=pulse]::before,e-preloader[type=pulse]::after{content:\"\";position:absolute;inset:0;border:.05em solid var(--e-preloader-color);border-radius:100%;animation:1.2s e-preloader-pulse infinite both ease-out}e-preloader[type=pulse]::after{animation-delay:.6s}e-preloader[type=overlap]{height:1em;width:1em;position:relative}e-preloader[type=overlap]::before,e-preloader[type=overlap]::after{content:\"\";inset:0;position:absolute;background:var(--e-preloader-color);border-radius:100%;opacity:.5;animation:2s e-preloader-overlap infinite both ease-in-out}e-preloader[type=overlap]::after{animation-delay:-1s;animation-direction:reverse}e-preloader[type=nested-spinners],e-preloader[type=opposing-nested-spinners],e-preloader[type=opposing-nested-rings]{height:1em;width:1em;position:relative}e-preloader[type=nested-spinners]::before,e-preloader[type=nested-spinners]::after,e-preloader[type=opposing-nested-spinners]::before,e-preloader[type=opposing-nested-spinners]::after,e-preloader[type=opposing-nested-rings]::before,e-preloader[type=opposing-nested-rings]::after{content:\"\";display:block;position:absolute;border-radius:100%;border:.1em solid var(--e-preloader-color);border-top-color:rgba(0,0,0,0);animation:var(--duration) e-preloader-spin linear infinite}e-preloader[type=nested-spinners]::before,e-preloader[type=opposing-nested-spinners]::before,e-preloader[type=opposing-nested-rings]::before{inset:-0.3em}e-preloader[type=nested-spinners]::after,e-preloader[type=opposing-nested-spinners]::after,e-preloader[type=opposing-nested-rings]::after{animation-duration:calc(var(--duration) - .2s);inset:0;opacity:.5}e-preloader[type=nested-spinners]::before,e-preloader[type=nested-spinners]::after,e-preloader[type=opposing-nested-spinners]::before,e-preloader[type=opposing-nested-spinners]::after{border-bottom-color:rgba(0,0,0,0)}e-preloader[type=opposing-nested-rings]::after,e-preloader[type=opposing-nested-spinners]::after{animation-direction:reverse}e-preloader[type=progress-bar],e-preloader[type=two-way-progress-bar],e-preloader[type=repeating-bar]{--e-preloader-animation: e-preloader-progress-bar;height:.05em;width:5em;max-width:50vw;background:var(--e-preloader-color);animation:var(--duration) var(--e-preloader-animation) linear infinite both}e-preloader[type=progress-bar]{transform-origin:0 50%}e-preloader[type=repeating-bar]{--e-preloader-animation: e-preloader-repeating-bar}@media(prefers-reduced-motion: reduce){e-preloader{display:none}}@keyframes e-preloader-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes e-preloader-bounce{0%,40%,100%{transform:translateY(0)}20%{transform:translateY(-80%)}}@keyframes e-preloader-pulsing-dots{0%,40%,100%{transform:scale(1)}20%{transform:scale(1.5)}}@keyframes e-preloader-pulse{from{transform:scale(0);opacity:1}to{transform:scale(1);opacity:0}}@keyframes e-preloader-overlap{0%,100%{transform:scale(0.2)}50%{transform:scale(1)}}@keyframes e-preloader-progress-bar{0%{transform:scaleX(0)}100%{transform:scaleX(1)}}@keyframes e-preloader-repeating-bar{0%{transform:scaleX(0);transform-origin:0 50%}49%{transform-origin:0 50%}50%{transform:scaleX(1);transform-origin:100% 50%}100%{transform:scaleX(0);transform-origin:100% 50%}}", ""]);
// Exports
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
/***/ }),
/***/ "../node_modules/css-loader/dist/runtime/api.js":
/*!******************************************************!*\
!*** ../node_modules/css-loader/dist/runtime/api.js ***!
\******************************************************/
/***/ ((module) => {
"use strict";
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
// eslint-disable-next-line func-names
module.exports = function (cssWithMappingToString) {
var list = []; // return the list of modules as css string
list.toString = function toString() {
return this.map(function (item) {
var content = cssWithMappingToString(item);
if (item[2]) {
return "@media ".concat(item[2], " {").concat(content, "}");
}
return content;
}).join("");
}; // import a list of modules into the list
// eslint-disable-next-line func-names
list.i = function (modules, mediaQuery, dedupe) {
if (typeof modules === "string") {
// eslint-disable-next-line no-param-reassign
modules = [[null, modules, ""]];
}
var alreadyImportedModules = {};
if (dedupe) {
for (var i = 0; i < this.length; i++) {
// eslint-disable-next-line prefer-destructuring
var id = this[i][0];
if (id != null) {
alreadyImportedModules[id] = true;
}
}
}
for (var _i = 0; _i < modules.length; _i++) {
var item = [].concat(modules[_i]);
if (dedupe && alreadyImportedModules[item[0]]) {
// eslint-disable-next-line no-continue
continue;
}
if (mediaQuery) {
if (!item[2]) {
item[2] = mediaQuery;
} else {
item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
}
}
list.push(item);
}
};
return list;
};
/***/ }),
/***/ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js":
/*!***********************************************************************!*\
!*** ../node_modules/@babel/runtime/helpers/interopRequireDefault.js ***!
\***********************************************************************/
/***/ ((module) => {
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
"default": obj
};
}
module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
var exports = __webpack_exports__;
/*!******************************************************************!*\
!*** ../modules/page-transitions/assets/js/frontend/frontend.js ***!
\******************************************************************/
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
var _components = __webpack_require__(/*! ./components */ "../modules/page-transitions/assets/js/frontend/components/index.js");
class PageTransitionsFrontend {
/**
* Initialize the module.
*
* @return {void}
*/
constructor() {
customElements.define('e-preloader', _components.Preloader);
customElements.define('e-page-transition', _components.PageTransition);
}
}
exports["default"] = PageTransitionsFrontend;
new PageTransitionsFrontend();
})();
/******/ })()
;
//# sourceMappingURL=page-transitions.js.map/**
* HFEWpfStyler Module.
*
* @package header-footer-elementor
*/
namespace HFE\WidgetsManager\Widgets\Copyright;
use HFE\WidgetsManager\Base\Module_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class Module.
*/
class Module extends Module_Base {
/**
* Module should load or not.
*
* @since 1.15.0
* @access public
*
* @return bool true|false.
*/
public static function is_enable() {
return true;
}
/**
* Get Module Name.
*
* @since 1.15.0
* @access public
*
* @return string Module name.
*/
public function get_name() {
return 'copyright';
}
/**
* Get Widgets.
*
* @since 1.15.0
* @access public
*
* @return array Widgets.
*/
public function get_widgets() {
return [
'Copyright',
];
}
/**
* Constructor.
*/
public function __construct() { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found
parent::__construct();
}
}
/**
* HFEWpfStyler Module.
*
* @package header-footer-elementor
*/
namespace HFE\WidgetsManager\Widgets\NavigationMenu;
use HFE\WidgetsManager\Base\Module_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class Module.
*/
class Module extends Module_Base {
/**
* Module should load or not.
*
* @since 1.15.0
* @access public
*
* @return bool true|false.
*/
public static function is_enable() {
return true;
}
/**
* Get Module Name.
*
* @since 1.15.0
* @access public
*
* @return string Module name.
*/
public function get_name() {
return 'navigation-menu';
}
/**
* Get Widgets.
*
* @since 1.15.0
* @access public
*
* @return array Widgets.
*/
public function get_widgets() {
return [
'Navigation_Menu',
];
}
/**
* Constructor.
*/
public function __construct() { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found
parent::__construct();
}
}
namespace Elementor;
use \Elementor\ElementsKit_Widget_Wp_Forms_Handler as Handler;
use \ElementsKit_Lite\Modules\Controls\Controls_Manager as ElementsKit_Controls_Manager;
if (! defined( 'ABSPATH' ) ) exit;
class ElementsKit_Widget_Wp_Forms extends Widget_Base {
use \ElementsKit_Lite\Widgets\Widget_Notice;
public $base;
public function __construct( $data = [], $args = null ) {
parent::__construct( $data, $args );
$this->add_script_depends('wpforms');
}
public function get_name() {
return Handler::get_name();
}
public function get_title() {
return Handler::get_title();
}
public function get_icon() {
return Handler::get_icon();
}
public function get_categories() {
return Handler::get_categories();
}
public function get_keywords() {
return Handler::get_keywords();
}
public function get_help_url() {
return 'https://wpmet.com/doc/wp-forms/';
}
protected function is_dynamic_content(): bool {
return false;
}
protected function register_controls() {
$this->start_controls_section(
'ekit_wpform_section_tab', [
'label' =>esc_html__( 'wpForm', 'elementskit-lite' ),
]
);
$this->add_control(
'ekit_wpform_form_id',
[
'label' => __( 'Select Your Form', 'elementskit-lite' ),
'type' => Controls_Manager::SELECT,
'label_block' => true,
'default' => '0',
'options' => \ElementsKit_Lite\Utils::ekit_get__forms('wpforms'),
]
);
$this->end_controls_section();
/** Labels **/
$this->start_controls_section(
'ekit_wpForms_section_label_style',
[
'label' => __( 'Labels', 'elementskit-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'ekit_wpForms_text_color_label',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field label' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'ekit_wpForms_typography_label',
'label' => __( 'Typography', 'elementskit-lite' ),
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field label',
]
);
$this->end_controls_section();
/** Input & Textarea **/
$this->start_controls_section(
'ekit_wpForms_section_fields_style',
[
'label' => __( 'Input & Textarea', 'elementskit-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'ekit_wpForms_input_alignment',
[
'label' => __( 'Alignment', 'elementskit-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementskit-lite' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementskit-lite' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementskit-lite' ),
'icon' => 'eicon-text-align-right',
],
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select' => 'text-align: {{VALUE}};',
],
]
);
$this->start_controls_tabs( 'ekit_wpForms_tabs_fields_style' );
$this->start_controls_tab(
'ekit_wpForms_tab_fields_normal',
[
'label' => __( 'Normal', 'elementskit-lite' ),
]
);
$this->add_control(
'ekit_wpForms_field_bg_color',
[
'label' => __( 'Background Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'ekit_wpForms_field_text_color',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'ekit_wpForms_field_border',
'label' => __( 'Border', 'elementskit-lite' ),
'placeholder' => '1px',
'default' => '1px',
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select',
'separator' => 'before',
]
);
$this->add_control(
'ekit_wpForms_field_radius',
[
'label' => __( 'Border Radius', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_control(
'ekit_wpForms_hr_1',
[
'type' => Controls_Manager::DIVIDER,
]
);
$this->add_responsive_control(
'ekit_wpForms_input_width',
[
'label' => __( 'Input Width', 'elementskit-lite' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 1200,
'step' => 1,
],
],
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field select' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
'{{WRAPPER}} .ekit_wpForms_container .wpforms-form .wpforms-field-row.wpforms-field-medium' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'ekit_wpForms_hr_2',
[
'type' => Controls_Manager::DIVIDER,
]
);
$this->add_responsive_control(
'ekit_wpForms_textarea_width',
[
'label' => __( 'Textarea Width', 'elementskit-lite' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 1200,
'step' => 1,
],
],
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea' => 'width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'ekit_wpForms_textarea_height',
[
'label' => __( 'Textarea Height', 'elementskit-lite' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 400,
'step' => 1,
],
],
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea' => 'height: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'ekit_wpForms_field_padding',
[
'label' => __( 'Padding', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'ekit_wpForms_field_spacing',
[
'label' => __( 'Margin', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'ekit_wpForms_field_box_shadow',
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select',
'separator' => 'before',
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'ekit_wpForms_tab_fields_focus',
[
'label' => __( 'Focus', 'elementskit-lite' ),
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'ekit_wpForms_focus_input_border',
'label' => __( 'Border', 'elementskit-lite' ),
'placeholder' => '1px',
'default' => '1px',
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:focus, {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea:focus',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'ekit_wpForms_focus_box_shadow',
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:focus, {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea:focus',
'separator' => 'before',
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
/** Field Description **/
$this->start_controls_section(
'ekit_wpForms_section_field_description_style',
[
'label' => __( 'Field Description', 'elementskit-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'ekit_wpForms_field_description_text_color',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field .wpforms-field-description, {{WRAPPER}} .ekit_wpForms_container .wpforms-field .wpforms-field-sublabel' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'ekit_wpForms_field_description_typography',
'label' => __( 'Typography', 'elementskit-lite' ),
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field .wpforms-field-description, {{WRAPPER}} .ekit_wpForms_container .wpforms-field .wpforms-field-sublabel',
]
);
$this->add_responsive_control(
'ekit_wpForms_field_description_spacing',
[
'label' => __( 'Padding', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field .wpforms-field-description' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field .wpforms-field-sublabel' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'before',
]
);
$this->end_controls_section();
/** Placeholder **/
$this->start_controls_section(
'ekit_wpForms_section_placeholder_style',
[
'label' => __( 'Placeholder', 'elementskit-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'ekit_wpForms_field_typography',
'label' => __( 'Typography', 'elementskit-lite' ),
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-field input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]):not([type=image]):not([type=file]), {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea, {{WRAPPER}} .ekit_wpForms_container .wpforms-field select',
'separator' => 'before',
]
);
$this->add_control(
'ekit_wpForms_text_color_placeholder',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-field input::-webkit-input-placeholder, {{WRAPPER}} .ekit_wpForms_container .wpforms-field textarea::-webkit-input-placeholder' => 'color: {{VALUE}}',
],
]
);
$this->end_controls_section();
/** Submit Button **/
$this->start_controls_section(
'ekit_wpForms_section_submit_button_style',
[
'label' => __( 'Submit Button', 'elementskit-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'ekit_wpForms_button_width_type',
[
'label' => __( 'Width', 'elementskit-lite' ),
'type' => Controls_Manager::SELECT,
'default' => 'custom',
'options' => [
'full-width' => __( 'Full Width', 'elementskit-lite' ),
'custom' => __( 'Custom', 'elementskit-lite' ),
],
'prefix_class' => 'ekit_wpForms_container-form-button-',
]
);
$this->add_responsive_control(
'ekit_wpForms_button_align',
[
'label' => __( 'Alignment', 'elementskit-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementskit-lite' ),
'icon' => 'eicon-h-align-left',
],
'center' => [
'title' => __( 'Center', 'elementskit-lite' ),
'icon' => 'eicon-h-align-center',
],
'right' => [
'title' => __( 'Right', 'elementskit-lite' ),
'icon' => 'eicon-h-align-right',
],
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container' => 'text-align: {{VALUE}};',
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit' => 'display:inline-block;'
],
'condition' => [
'ekit_wpForms_button_width_type' => 'custom',
],
]
);
$this->add_responsive_control(
'ekit_wpForms_button_width',
[
'label' => __( 'Width', 'elementskit-lite' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 1200,
'step' => 1,
],
],
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit' => 'width: {{SIZE}}{{UNIT}}',
],
'condition' => [
'ekit_wpForms_button_width_type' => 'custom',
],
]
);
$this->start_controls_tabs( 'ekit_wpForms_tabs_button_style' );
$this->start_controls_tab(
'ekit_wpForms_tab_button_normal',
[
'label' => __( 'Normal', 'elementskit-lite' ),
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'ekit_wpForms_button_typography',
'label' => __( 'Typography', 'elementskit-lite' ),
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit',
'separator' => 'before',
]
);
$this->add_control(
'ekit_wpForms_button_bg_color_normal',
[
'label' => __( 'Background Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'ekit_wpForms_button_text_color_normal',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'ekit_wpForms_button_box_shadow',
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit',
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'ekit_wpForms_button_border_normal',
'label' => __( 'Border', 'elementskit-lite' ),
'placeholder' => '1px',
'default' => '1px',
'selector' => '{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit',
]
);
$this->add_control(
'ekit_wpForms_button_border_radius',
[
'label' => __( 'Border Radius', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'ekit_wpForms_button_padding',
[
'label' => __( 'Padding', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'ekit_wpForms_button_margin',
[
'label' => __( 'Margin', 'elementskit-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'ekit_wpForms_tab_button_hover',
[
'label' => __( 'Hover', 'elementskit-lite' ),
]
);
$this->add_control(
'ekit_wpForms_button_bg_color_hover',
[
'label' => __( 'Background Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit:hover' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'ekit_wpForms_button_text_color_hover',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit:hover' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'ekit_wpForms_button_border_color_hover',
[
'label' => __( 'Border Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container .wpforms-submit-container .wpforms-submit:hover' => 'border-color: {{VALUE}}',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
/** Errors **/
$this->start_controls_section(
'ekit_wpForms_section_error_style',
[
'label' => __( 'Errors', 'elementskit-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'ekit_wpForms_error_message_text_color',
[
'label' => __( 'Text Color', 'elementskit-lite' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .ekit_wpForms_container label.wpforms-error' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'ekit_wpForms_error_field_input_border',
'label' => __( 'Border', 'elementskit-lite' ),
'selector' => '{{WRAPPER}} .ekit_wpForms_container input.wpforms-error, {{WRAPPER}} .ekit_wpForms_container textarea.wpforms-error',
]
);
$this->end_controls_section();
$this->insert_pro_message();
}
protected function render( ) {
echo '';
$this->render_raw();
echo '
';
}
protected function render_raw( ) {
$settings = $this->get_settings();
if ( ! empty( $settings['ekit_wpform_form_id'] ) ) {
echo do_shortcode('[wpforms id="'.intval($settings['ekit_wpform_form_id']).'"]' );
}
}
}
namespace ElementsKit_Lite\Modules\Dynamic_Content;
defined( 'ABSPATH' ) || exit;
class Init {
public static function get_url() {
return \ElementsKit_Lite::module_url() . 'dynamic-content/';
}
public static function get_dir() {
return \ElementsKit_Lite::module_dir() . 'dynamic-content/';
}
public function __construct() {
// Includes necessary files
$this->include_files();
}
private function include_files() {
// Controls_Manager
include_once self::get_dir() . 'cpt.php';
include_once self::get_dir() . 'cpt-api.php';
}
}
namespace ElementsKit_Lite;
use ElementsKit_Lite\Libs\Framework\Attr;
use ElementsKit_Lite\Modules\Megamenu\Init;
defined( 'ABSPATH' ) || exit;
class Megamenu_Api extends Core\Handler_Api {
public function config() {
$this->prefix = 'megamenu';
}
public function get_save_menuitem_settings() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$menu_item_id = $this->request['settings']['menu_id'];
$menu_item_settings = wp_json_encode( $this->request['settings'], JSON_UNESCAPED_UNICODE );
update_post_meta( $menu_item_id, Init::$menuitem_settings_key, $menu_item_settings );
return array(
'saved' => 1,
'message' => esc_html__( 'Saved', 'elementskit-lite' ),
);
}
public function get_get_menuitem_settings() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$menu_item_id = $this->request['menu_id'];
$data = get_post_meta( $menu_item_id, Init::$menuitem_settings_key, true );
return (array) json_decode( $data );
}
public function get_megamenu_content() {
$menu_item_id = intval($this->request['id']);
if ('publish' !== get_post_status ($menu_item_id) || post_password_required($menu_item_id)) {
return;
}
$elementor = \Elementor\Plugin::instance();
$output = $elementor->frontend->get_builder_content_for_display($menu_item_id);
return $output;
}
}
new Megamenu_Api();
namespace ElementsKit_Lite\Helpers;
defined( 'ABSPATH' ) || exit;
class Widget_List extends \ElementsKit_Lite\Config\Widget_List {
//
}
/*! elementor-pro - v3.31.0 - 08-09-2025 */
@charset "UTF-8";.site-main .menu-navigation-container{overflow:visible}.elementor-item:after,.elementor-item:before{display:block;position:absolute;transition:.3s;transition-timing-function:cubic-bezier(.58,.3,.005,1)}.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{opacity:0}.elementor-item-active:after,.elementor-item-active:before,.elementor-item.highlighted:after,.elementor-item.highlighted:before,.elementor-item:focus:after,.elementor-item:focus:before,.elementor-item:hover:after,.elementor-item:hover:before{transform:scale(1)}.e--pointer-double-line .elementor-item:after,.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:after,.e--pointer-overline .elementor-item:before,.e--pointer-underline .elementor-item:after,.e--pointer-underline .elementor-item:before{background-color:#3f444b;height:3px;left:0;width:100%;z-index:2}.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{height:0;left:50%;width:0}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:10px}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:-10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:-10px}.e--pointer-double-line.e--animation-none,.e--pointer-double-line.e--animation-none .elementor-item,.e--pointer-double-line.e--animation-none .elementor-item:after,.e--pointer-double-line.e--animation-none .elementor-item:before,.e--pointer-double-line.e--animation-none .elementor-item:focus,.e--pointer-double-line.e--animation-none .elementor-item:hover,.e--pointer-double-line.e--animation-none:after,.e--pointer-double-line.e--animation-none:before,.e--pointer-double-line.e--animation-none:focus,.e--pointer-double-line.e--animation-none:hover,.e--pointer-overline.e--animation-none,.e--pointer-overline.e--animation-none .elementor-item,.e--pointer-overline.e--animation-none .elementor-item:after,.e--pointer-overline.e--animation-none .elementor-item:before,.e--pointer-overline.e--animation-none .elementor-item:focus,.e--pointer-overline.e--animation-none .elementor-item:hover,.e--pointer-overline.e--animation-none:after,.e--pointer-overline.e--animation-none:before,.e--pointer-overline.e--animation-none:focus,.e--pointer-overline.e--animation-none:hover,.e--pointer-underline.e--animation-none,.e--pointer-underline.e--animation-none .elementor-item,.e--pointer-underline.e--animation-none .elementor-item:after,.e--pointer-underline.e--animation-none .elementor-item:before,.e--pointer-underline.e--animation-none .elementor-item:focus,.e--pointer-underline.e--animation-none .elementor-item:hover,.e--pointer-underline.e--animation-none:after,.e--pointer-underline.e--animation-none:before,.e--pointer-underline.e--animation-none:focus,.e--pointer-underline.e--animation-none:hover{transition-duration:0s}.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:before{content:"";top:0}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:-20px;width:10px}.e--pointer-double-line .elementor-item:after,.e--pointer-underline .elementor-item:after{bottom:0;content:""}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{inset-inline-start:100%;width:10px}.e--pointer-framed .elementor-item:after,.e--pointer-framed .elementor-item:before{background:transparent;border:3px solid #3f444b;bottom:0;left:0;right:0;top:0}.e--pointer-framed .elementor-item:before{content:""}.e--pointer-framed.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(.75)}.e--pointer-framed.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.25)}.e--pointer-framed.e--animation-grow .elementor-item:before,.e--pointer-framed.e--animation-shrink .elementor-item:before{transition:opacity .2s,transform .4s}.e--pointer-framed.e--animation-draw .elementor-item:after,.e--pointer-framed.e--animation-draw .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-draw .elementor-item:before{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:0;border-inline-start-width:3px;transition:width .1s .2s,height .1s .3s,opacity .12s .22s}.e--pointer-framed.e--animation-draw .elementor-item:after{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto;transition:width .1s,height .1s .1s,opacity .02s .18s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{height:100%;width:100%}.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{transition:opacity .02s,height .1s,width .1s .1s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:after{transition:opacity .02s .2s,height .1s .2s,width .1s .3s}.e--pointer-framed.e--animation-corners .elementor-item:after,.e--pointer-framed.e--animation-corners .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-corners .elementor-item:before{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:0;border-inline-start-width:3px}.e--pointer-framed.e--animation-corners .elementor-item:after{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto}.e--pointer-framed.e--animation-corners .elementor-item-active:after,.e--pointer-framed.e--animation-corners .elementor-item-active:before,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:after,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:before,.e--pointer-framed.e--animation-corners .elementor-item:focus:after,.e--pointer-framed.e--animation-corners .elementor-item:focus:before,.e--pointer-framed.e--animation-corners .elementor-item:hover:after,.e--pointer-framed.e--animation-corners .elementor-item:hover:before{height:100%;transition:opacity 2ms,width .4s,height .4s;width:100%}.e--pointer-framed.e--animation-none,.e--pointer-framed.e--animation-none .elementor-item,.e--pointer-framed.e--animation-none .elementor-item:after,.e--pointer-framed.e--animation-none .elementor-item:before,.e--pointer-framed.e--animation-none .elementor-item:focus,.e--pointer-framed.e--animation-none .elementor-item:hover,.e--pointer-framed.e--animation-none:after,.e--pointer-framed.e--animation-none:before,.e--pointer-framed.e--animation-none:focus,.e--pointer-framed.e--animation-none:hover{transition-duration:0s}.e--pointer-background .elementor-item:after,.e--pointer-background .elementor-item:before{content:"";transition:.3s}.e--pointer-background .elementor-item:before{background:#3f444b;inset:0;z-index:-1}.e--pointer-background .elementor-item-active,.e--pointer-background .elementor-item.highlighted,.e--pointer-background .elementor-item:focus,.e--pointer-background .elementor-item:hover{color:#fff}.e--pointer-background.e--animation-grow .elementor-item:before{transform:scale(.5)}.e--pointer-background.e--animation-grow .elementor-item-active:before,.e--pointer-background.e--animation-grow .elementor-item.highlighted:before,.e--pointer-background.e--animation-grow .elementor-item:focus:before,.e--pointer-background.e--animation-grow .elementor-item:hover:before{opacity:1;transform:scale(1)}.e--pointer-background.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.2);transition:.3s}.e--pointer-background.e--animation-shrink .elementor-item-active:before,.e--pointer-background.e--animation-shrink .elementor-item.highlighted:before,.e--pointer-background.e--animation-shrink .elementor-item:focus:before,.e--pointer-background.e--animation-shrink .elementor-item:hover:before{transition:opacity .15s,transform .4s}.e--pointer-background.e--animation-sweep-left .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:100%}.e--pointer-background.e--animation-sweep-right .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{right:100%}.e--pointer-background.e--animation-sweep-up .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:100%}.e--pointer-background.e--animation-sweep-down .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:100%}.e--pointer-background.e--animation-shutter-out-vertical .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:50%;top:50%}.e--pointer-background.e--animation-shutter-out-horizontal .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:50%;right:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{background:#3f444b;inset:0;z-index:-1}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:before{bottom:100%;top:0}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{bottom:0;top:100%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:before{bottom:50%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:after{top:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:before{left:100%;right:0}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after{left:0;right:100%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:before{left:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:after{right:50%}.e--pointer-background.e--animation-none,.e--pointer-background.e--animation-none .elementor-item,.e--pointer-background.e--animation-none .elementor-item:after,.e--pointer-background.e--animation-none .elementor-item:before,.e--pointer-background.e--animation-none .elementor-item:focus,.e--pointer-background.e--animation-none .elementor-item:hover,.e--pointer-background.e--animation-none:after,.e--pointer-background.e--animation-none:before,.e--pointer-background.e--animation-none:focus,.e--pointer-background.e--animation-none:hover{transition-duration:0s}.e--pointer-text.e--animation-skew .elementor-item:focus,.e--pointer-text.e--animation-skew .elementor-item:hover{transform:skew(-8deg)}.e--pointer-text.e--animation-grow .elementor-item:focus,.e--pointer-text.e--animation-grow .elementor-item:hover{transform:scale(1.2)}.e--pointer-text.e--animation-shrink .elementor-item:focus,.e--pointer-text.e--animation-shrink .elementor-item:hover{transform:scale(.8)}.e--pointer-text.e--animation-float .elementor-item:focus,.e--pointer-text.e--animation-float .elementor-item:hover{transform:translateY(-8px)}.e--pointer-text.e--animation-sink .elementor-item:focus,.e--pointer-text.e--animation-sink .elementor-item:hover{transform:translateY(8px)}.e--pointer-text.e--animation-rotate .elementor-item:focus,.e--pointer-text.e--animation-rotate .elementor-item:hover{transform:rotate(6deg)}.e--pointer-text.e--animation-none,.e--pointer-text.e--animation-none .elementor-item,.e--pointer-text.e--animation-none .elementor-item:after,.e--pointer-text.e--animation-none .elementor-item:before,.e--pointer-text.e--animation-none .elementor-item:focus,.e--pointer-text.e--animation-none .elementor-item:hover,.e--pointer-text.e--animation-none:after,.e--pointer-text.e--animation-none:before,.e--pointer-text.e--animation-none:focus,.e--pointer-text.e--animation-none:hover{transition-duration:0s}.elementor-nav-menu--main .elementor-nav-menu a{transition:.4s}.elementor-nav-menu--main .elementor-nav-menu a,.elementor-nav-menu--main .elementor-nav-menu a.highlighted,.elementor-nav-menu--main .elementor-nav-menu a:focus,.elementor-nav-menu--main .elementor-nav-menu a:hover{padding:13px 20px}.elementor-nav-menu--main .elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu--main .elementor-nav-menu a.disabled{background:#3f444b;color:#88909b}.elementor-nav-menu--main .elementor-nav-menu ul{border-style:solid;border-width:0;padding:0;position:absolute;width:12em}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up{background:#fff;display:none;height:20px;overflow:hidden;position:absolute;visibility:hidden}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up-arrow{border:8px dashed transparent;border-bottom:8px solid #33373d;height:0;inset-block-start:-2px;inset-inline-start:50%;margin-inline-start:-8px;overflow:hidden;position:absolute;width:0}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow{border-color:#33373d transparent transparent;border-style:solid dashed dashed;top:6px}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg,.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow i{transform:rotate(calc(-90deg * var(--direction-multiplier, 1)))}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg{fill:currentColor;height:1em;width:1em}.elementor-nav-menu--layout-horizontal{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu{display:flex;flex-wrap:wrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu a{flex-grow:1;white-space:nowrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li ul,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>.scroll-down{top:100%!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>a{margin-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-down,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-up,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>ul{inset-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child)>a{margin-inline-end:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child):after{align-self:center;border-color:var(--e-nav-menu-divider-color,#000);border-left-style:var(--e-nav-menu-divider-style,solid);border-left-width:var(--e-nav-menu-divider-width,2px);content:var(--e-nav-menu-divider-content,none);height:var(--e-nav-menu-divider-height,35%)}.elementor-nav-menu__align-right .elementor-nav-menu{justify-content:flex-end;margin-left:auto}.elementor-nav-menu__align-right .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-left .elementor-nav-menu{justify-content:flex-start;margin-right:auto}.elementor-nav-menu__align-left .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-start .elementor-nav-menu{justify-content:flex-start;margin-inline-end:auto}.elementor-nav-menu__align-start .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-end .elementor-nav-menu{justify-content:flex-end;margin-inline-start:auto}.elementor-nav-menu__align-end .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-center .elementor-nav-menu{justify-content:center;margin-inline-end:auto;margin-inline-start:auto}.elementor-nav-menu__align-center .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:center}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu{width:100%}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{flex-grow:1}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>a{justify-content:center}.elementor-widget-nav-menu:not(.elementor-nav-menu--toggle) .elementor-menu-toggle{display:none}.elementor-widget-nav-menu .elementor-widget-container,.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*=elementor-hidden-]){display:flex;flex-direction:column}.elementor-nav-menu{position:relative;z-index:2}.elementor-nav-menu:after{clear:both;content:" ";display:block;font:0/0 serif;height:0;overflow:hidden;visibility:hidden}.elementor-nav-menu,.elementor-nav-menu li,.elementor-nav-menu ul{display:block;line-height:normal;list-style:none;margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.elementor-nav-menu ul{display:none}.elementor-nav-menu ul ul a,.elementor-nav-menu ul ul a:active,.elementor-nav-menu ul ul a:focus,.elementor-nav-menu ul ul a:hover{border-left:16px solid transparent}.elementor-nav-menu ul ul ul a,.elementor-nav-menu ul ul ul a:active,.elementor-nav-menu ul ul ul a:focus,.elementor-nav-menu ul ul ul a:hover{border-left:24px solid transparent}.elementor-nav-menu ul ul ul ul a,.elementor-nav-menu ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul a:hover{border-left:32px solid transparent}.elementor-nav-menu ul ul ul ul ul a,.elementor-nav-menu ul ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul ul a:hover{border-left:40px solid transparent}.elementor-nav-menu a,.elementor-nav-menu li{position:relative}.elementor-nav-menu li{border-width:0}.elementor-nav-menu a{align-items:center;display:flex}.elementor-nav-menu a,.elementor-nav-menu a:focus,.elementor-nav-menu a:hover{line-height:20px;padding:10px 20px}.elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu a.disabled{color:#88909b;cursor:not-allowed}.elementor-nav-menu .e-plus-icon:before{content:"+"}.elementor-nav-menu .sub-arrow{align-items:center;display:flex;line-height:1;margin-block-end:-10px;margin-block-start:-10px;padding:10px;padding-inline-end:0}.elementor-nav-menu .sub-arrow i{pointer-events:none}.elementor-nav-menu .sub-arrow .fa.fa-chevron-down,.elementor-nav-menu .sub-arrow .fas.fa-chevron-down{font-size:.7em}.elementor-nav-menu .sub-arrow .e-font-icon-svg{height:1em;width:1em}.elementor-nav-menu .sub-arrow .e-font-icon-svg.fa-svg-chevron-down{height:.7em;width:.7em}.elementor-nav-menu--dropdown .elementor-item.elementor-item-active,.elementor-nav-menu--dropdown .elementor-item.highlighted,.elementor-nav-menu--dropdown .elementor-item:focus,.elementor-nav-menu--dropdown .elementor-item:hover,.elementor-sub-item.elementor-item-active,.elementor-sub-item.highlighted,.elementor-sub-item:focus,.elementor-sub-item:hover{background-color:#3f444b;color:#fff}.elementor-menu-toggle{align-items:center;background-color:rgba(0,0,0,.05);border:0 solid;border-radius:3px;color:#33373d;cursor:pointer;display:flex;font-size:var(--nav-menu-icon-size,22px);justify-content:center;padding:.25em}.elementor-menu-toggle.elementor-active .elementor-menu-toggle__icon--open,.elementor-menu-toggle:not(.elementor-active) .elementor-menu-toggle__icon--close{display:none}.elementor-menu-toggle .e-font-icon-svg{fill:#33373d;height:1em;width:1em}.elementor-menu-toggle svg{height:auto;width:1em;fill:var(--nav-menu-icon-color,currentColor)}span.elementor-menu-toggle__icon--close,span.elementor-menu-toggle__icon--open{line-height:1}.elementor-nav-menu--dropdown{background-color:#fff;font-size:13px}.elementor-nav-menu--dropdown-none .elementor-menu-toggle,.elementor-nav-menu--dropdown-none .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown.elementor-nav-menu__container{margin-top:10px;overflow-x:hidden;overflow-y:auto;transform-origin:top;transition:max-height .3s,transform .3s}.elementor-nav-menu--dropdown.elementor-nav-menu__container .elementor-sub-item{font-size:.85em}.elementor-nav-menu--dropdown a{color:#33373d}.elementor-nav-menu--dropdown a.current{background:#1f2124;color:#fff}.elementor-nav-menu--dropdown a.disabled{color:#b3b3b3}ul.elementor-nav-menu--dropdown a,ul.elementor-nav-menu--dropdown a:focus,ul.elementor-nav-menu--dropdown a:hover{border-inline-start:8px solid transparent;text-shadow:none}.elementor-nav-menu__text-align-center .elementor-nav-menu--dropdown .elementor-nav-menu a{justify-content:center}.elementor-nav-menu--toggle{--menu-height:100vh}.elementor-nav-menu--toggle .elementor-menu-toggle:not(.elementor-active)+.elementor-nav-menu__container{max-height:0;overflow:hidden;transform:scaleY(0)}.elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active+.elementor-nav-menu__container{animation:hide-scroll .3s backwards;max-height:var(--menu-height);transform:scaleY(1)}.elementor-nav-menu--stretch .elementor-nav-menu__container.elementor-nav-menu--dropdown{position:absolute;z-index:9997}@media (max-width:767px){.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--main{display:none}}@media (min-width:768px){.elementor-nav-menu--dropdown-mobile .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:-1){.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--main{display:none}}@media (min-width:-1){.elementor-nav-menu--dropdown-mobile_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:1024px){.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--main{display:none}}@media (min-width:1025px){.elementor-nav-menu--dropdown-tablet .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:-1){.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--main{display:none}}@media (min-width:-1){.elementor-nav-menu--dropdown-tablet_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@keyframes hide-scroll{0%,to{overflow:hidden}}